单元格宽度对于 tableview 宽度来说太大了

Posted

技术标签:

【中文标题】单元格宽度对于 tableview 宽度来说太大了【英文标题】:Cell width too big for tableview width 【发布时间】:2017-02-07 17:25:05 【问题描述】:

我有一个嵌套在轮播中的编程表格视图,但是当它显示时,编程单元格的设置总是比其所在的表格视图宽。如果我打印轮播项目宽度、表格视图宽度和单元格宽度,我得到:281、281 , 320(iphone5 屏幕宽度)。我尝试向单元格添加约束,但不断收到零错误,我相信是因为单元格尚未制作完成。所以我不确定在哪里放置约束以便我停止收到这些错误,我只需要单元格内容视图宽度来匹配 tableview 宽度,但是如何在我的自定义单元格中获取 tableview 宽度,这是以编程方式制作的?这是我当前的代码,没有任何限制:

表格视图:

import UIKit

class SplitterCarouselItemTableView: UITableView 

    var splitter: BillSplitter?

    required init(frame: CGRect, style: UITableViewStyle, splitter: BillSplitter) 
        super.init(frame: frame, style: style)
        self.splitter = splitter
        setupView()
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

    func setupView() 

        if Platform.isPhone 
            let tableViewBackground = UIImageView(image: UIImage(data: splitter?.image as! Data, scale:1.0))
            self.backgroundView = tableViewBackground
            tableViewBackground.contentMode = .scaleAspectFit
            tableViewBackground.frame = self.frame
        

        self.backgroundColor = .clear
        self.separatorStyle = .none
    


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

    tableView.register(SplitterCarouselItemTableViewCell.classForCoder(), forCellReuseIdentifier: "splitterCarouselItemTableViewCell")

    let cell: SplitterCarouselItemTableViewCell = tableView.dequeueReusableCell(withIdentifier: "splitterCarouselItemTableViewCell") as! SplitterCarouselItemTableViewCell
    var item = ((allBillSplitters[tableView.tag].items)?.allObjects as! [Item])[indexPath.row]
    if allBillSplitters[tableView.tag].isMainBillSplitter 
        getMainBillSplitterItems(splitter: allBillSplitters[tableView.tag])
        item = mainBillSplitterItems[indexPath.row]
    
    let count = item.billSplitters?.count

    if count! > 1 
        cell.name!.text = "\(item.name!)\nsplit \(count!) ways"
        cell.price!.text = "£\(Double(item.price)/Double(count!))"

     else 
        cell.name!.text = item.name!
        cell.price!.text = "£\(item.price)"
    

    return cell

单元格:

import UIKit

class SplitterCarouselItemTableViewCell: UITableViewCell 

    var name: UILabel!
    var price: UILabel!
    var view: UIView!

    required init(coder aDecoder: NSCoder) 
        fatalError("init(coder:)")
    

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) 
        super.init(style: style, reuseIdentifier: "splitterCarouselItemTableViewCell")

        self.backgroundColor = .clear

        let width = Int(contentView.bounds.width)
        let height = Int(contentView.bounds.height)

        view = UIView(frame: CGRect(x: 0, y: 2, width: width, height: height - 4 ))
        view.backgroundColor = UIColor.white.withAlphaComponent(0.5)

        let viewHeight = Int(view.bounds.height)
        let viewWidth = Int(view.bounds.width)

        price = UILabel(frame: CGRect(x: viewWidth - 80, y: 0, width: 75, height: viewHeight))
        price.font = UIFont.systemFont(ofSize: 15.0)
        price.textAlignment = .right

        name = UILabel(frame: CGRect(x: 5, y: 0, width: width, height: viewHeight))
        name.font = UIFont.systemFont(ofSize: 15.0)
        name.numberOfLines = 0

        view.addSubview(name)
        view.addSubview(price)

        contentView.addSubview(view)
    

我了解 init 不应填充所有代码,稍后将被提取。它就在那里,直到我解决宽度问题。

感谢您的帮助。

【问题讨论】:

使用UIScreen.mainScreen().bounds.width 获取屏幕的精确宽度。 您不应该在cellForRowAt:indexPath 中注册您的单元格——这可能是导致问题的原因。在viewDidLoad 中使用您的tableView 注册单元格。 @WolfgangSchreurs 谢谢我已经移动它但没有任何改变。 @iphonic 我尝试在自定义单元格的 awakeFromNib 中添加此约束,但没有任何改变。 你是如何初始化 UITableView 的?单元格和表格具有相同的宽度是正确的。你不应该做任何事情来让这些匹配。您是在情节提要中添加 TableView 还是以编程方式添加? 【参考方案1】:

挑战在于tableView.dequeueReusableCell(withIdentifier:) 方法在您的UITableViewCell 类上间接调用init(frame:)。有几种方法可以解决这个问题:

    SplitterCarouselItemTableViewCell 中覆盖init(frame:) 并在调用super.init(frame:) 时设置宽度 在func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) 方法中修改cell.frame

使用自动布局对 UITableView 单元格有问题。你不想弄乱那里的所有子视图。

【讨论】:

谢谢,我需要在单元格的初始化中设置框架,因为它在 cellForRowAt 中不起作用 UITableViewCell 没有 init(frame: CGRect) 方法,并且在编码器初始化程序中设置框架似乎不起作用。【参考方案2】:

尝试添加这个

    cell.frame = CGRect(x: CGFloat(Int(cell.frame.minX)),
                        y: CGFloat(Int(cell.frame.minY)),
                        width: tableView.frame.width,
                        height: cell.frame.height)

给你的

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

这解决了我的问题。

我的 UITableViewController 和 UITableViewCell 是以编程方式完成的

【讨论】:

以上是关于单元格宽度对于 tableview 宽度来说太大了的主要内容,如果未能解决你的问题,请参考以下文章

UIImageView 适合自调整大小的 tableview 单元格中的最大宽度

为 tableview (UITableView) 绘制一个自定义单元格,更改颜色和分隔符颜色和宽度

如何在自定义 tableView Cell 中调整标签高度和宽度

iOS 自动布局:表格视图单元格宽度 = 0

集合视图单元格中的动态按钮宽度

根据单元格宽度更改 UITableViewCell 内容的首选方法