【问题标题】:Swift Playground UITable View Cell not resizing after I add a subview添加子视图后,Swift Playground UITable View Cell 未调整大小
【发布时间】:2019-01-01 15:34:51
【问题描述】:

the table view loads

the sub view loads but you can see it is over other cells

sometimes the sub view loads but other cells are on top of it

我有一个 UITableView,当用户触摸一行时,一个子视图会添加到屏幕上。当他们单击另一行时,最后一个子视图消失(并且该行应该缩小到其正常大小)。子视图显示完美(单击另一行时会消失),但它挂在行外并覆盖了其他一些选项。此外,当屏幕旋转后重新加载表格视图时,子视图最终会位于表格的其他行之后。

我希望带有子视图的行调整大小,使其与子视图的框架相匹配。此外,每个子视图的大小取决于其中包含的文本和图像。因此,我尝试使用自动布局和 UITableViewAutomaticDimension,但似乎没有任何效果。

我将我的 UITableViewController 包括在内,这样你就可以看到我拥有的东西,并可以引导我朝着正确的方向前进。

class TableViewController : UITableViewController {

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    tableView.backgroundColor = #colorLiteral(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)
    self.tableView.estimatedRowHeight = rowHeight
    return filmsToDisplay.count
}

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

    var currentFilm = filmsToDisplay[indexPath.row]
    let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
    cell.selectionStyle = .none
    cell.textLabel?.text = "\(currentFilm.year) - \(currentFilm.movieTitle)"
    cell.textLabel?.textColor = #colorLiteral(red: 0.254901975393295, green: 0.274509817361832, blue: 0.301960796117783, alpha: 1.0)
    cell.textLabel?.font = UIFont.systemFont(ofSize: fontSize)
    cell.textLabel?.sizeToFit()
    cell.backgroundColor = #colorLiteral(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)
    cell.contentView.backgroundColor = #colorLiteral(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)



    let accessory = makeChart(currentFilm: filmsToDisplay[indexPath.row])
    cell.contentView.addSubview(accessory)
    accessory.translatesAutoresizingMaskIntoConstraints = false
    accessory.trailingAnchor.constraint(equalTo:cell.contentView.trailingAnchor).isActive = true
    accessory.topAnchor.constraint(equalTo: cell.contentView.topAnchor).isActive = true
    accessory.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor).isActive = true
    accessory.widthAnchor.constraint(equalTo: cell.contentView.widthAnchor, multiplier: nomBarWidth).isActive = true

    cell.contentView.translatesAutoresizingMaskIntoConstraints=false
    cell.contentView.leadingAnchor.constraint(equalTo:cell.leadingAnchor).isActive = true
    cell.contentView.trailingAnchor.constraint(equalTo:cell.trailingAnchor).isActive = true
    cell.contentView.topAnchor.constraint(equalTo:cell.topAnchor).isActive = true
    cell.contentView.bottomAnchor.constraint(equalTo: cell.bottomAnchor).isActive = true

    return cell
}

var lastSelectedCell : UITableViewCell? = nil
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let currentFilm = filmsToDisplay[indexPath.row]
    var detailView = createView(film: currentFilm)
    detailView.tag = 555
    let selectedCell:UITableViewCell = tableView.cellForRow(at: indexPath)!
    //get rid of last detail view
    if let lastCell = lastSelectedCell {
        for i in 0..<lastCell.contentView.subviews.count {
            let content = lastCell.contentView.subviews[i]
            if content.tag == 555{
                content.removeFromSuperview()
            }
        }
    }
    selectedCell.contentView.addSubview(detailView)
    detailView.translatesAutoresizingMaskIntoConstraints=false
    detailView.leadingAnchor.constraint(equalTo:selectedCell.contentView.leadingAnchor).isActive = true
    detailView.trailingAnchor.constraint(equalTo:selectedCell.contentView.trailingAnchor).isActive = true
    detailView.topAnchor.constraint(equalTo:selectedCell.contentView.topAnchor).isActive = true
    detailView.bottomAnchor.constraint(equalTo:detailView.subviews[detailView.subviews.count - 2].bottomAnchor).isActive = true
    lastSelectedCell = selectedCell
}

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

}

子视图的片段定义它们的高度如下(有更多片段但它们都具有相同类型的约束:

//MOVIE TITLE BAR
let movieTitleBar = UIButton()
movieTitleBar.setTitleColor(#colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0), for: UIControlState.normal)
movieTitleBar.setTitle(film.movieTitle, for: UIControlState.normal)
    movieTitleBar.backgroundColor = #colorLiteral(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)
    movieTitleBar.alpha = 0.5
    movieTitleBar.layer.borderWidth = outlineWidth
    movieTitleBar.layer.borderColor = #colorLiteral(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)
}
filmView.addSubview(movieTitleBar)
movieTitleBar.translatesAutoresizingMaskIntoConstraints = false
movieTitleBar.topAnchor.constraint(equalTo:filmView.topAnchor).isActive = true
movieTitleBar.heightAnchor.constraint(equalToConstant: rowHeight).isActive = true
movieTitleBar.leadingAnchor.constraint(equalTo:filmView.leadingAnchor).isActive = true
movieTitleBar.trailingAnchor.constraint(equalTo:filmView.trailingAnchor).isActive = true

//POSTER IMAGE
var poster = UIButton()
isPoster = false
if let posterImg = film.image {
    if let url = NSURL(string:posterImg){
        if let data = NSData(contentsOf:url as URL){
            film.poster = UIImage(data:data as Data)
            poster.setImage(film.poster, for: UIControlState.normal)
            isPoster = true
            filmView.addSubview(poster)
        }
    }
}

//BRIEF DESCRIPTION LABEL
let briefDescriptionBar = UILabel()
briefDescriptionBar.backgroundColor = film.colorUI
briefDescriptionBar.alpha = 0.8
briefDescriptionBar.text = "\(film.year) - \(film.briefDescription)"
briefDescriptionBar.textColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
briefDescriptionBar.numberOfLines = 0
briefDescriptionBar.textAlignment = .center
filmView.addSubview(briefDescriptionBar)
briefDescriptionBar.translatesAutoresizingMaskIntoConstraints = false
briefDescriptionBar.leadingAnchor.constraint(equalTo:movieTitleBar.leadingAnchor).isActive = true
briefDescriptionBar.topAnchor.constraint(equalTo:movieTitleBar.bottomAnchor).isActive = true
if isPoster == true {
    poster.translatesAutoresizingMaskIntoConstraints = false
    poster.topAnchor.constraint(equalTo:movieTitleBar.bottomAnchor).isActive = true
    poster.trailingAnchor.constraint(equalTo:movieTitleBar.trailingAnchor).isActive = true
    poster.widthAnchor.constraint(equalTo:filmView.widthAnchor, multiplier:nomBarWidth).isActive = true
    let aspect = (nomBarWidth * 41) / 27
    poster.heightAnchor.constraint(equalTo: filmView.widthAnchor, multiplier: aspect).isActive = true
    briefDescriptionBar.trailingAnchor.constraint(equalTo:poster.leadingAnchor).isActive = true
    briefDescriptionBar.bottomAnchor.constraint(equalTo:poster.bottomAnchor).isActive = true
}
else {
    briefDescriptionBar.widthAnchor.constraint(equalTo:filmView.widthAnchor).isActive = true
    briefDescriptionBar.heightAnchor.constraint(equalTo:movieTitleBar.heightAnchor, multiplier : 2).isActive = true
}

【问题讨论】:

    标签: ios swift uitableview programmatically row-height


    【解决方案1】:

    您的问题是您没有为添加的子视图提供高度限制,您只挂钩前导、尾随、顶部和底部,但 contentView 期望它是内部子视图的高度(如果它们没有内在的内容大小像标签/按钮),也不需要这部分代码

    cell.contentView.translatesAutoresizingMaskIntoConstraints=false
    cell.contentView.leadingAnchor.constraint(equalTo:cell.leadingAnchor).isActive = true
    cell.contentView.trailingAnchor.constraint(equalTo:cell.trailingAnchor).isActive = true
    cell.contentView.topAnchor.constraint(equalTo:cell.topAnchor).isActive = true
    cell.contentView.bottomAnchor.constraint(equalTo: cell.bottomAnchor).isActive = true
    

    另外,contentView 内部应该只有一个视图连接到底部,如果添加多个视图,如果两个视图也都连接到它的顶部,则会发生冲突,所以你必须打破挂钩新约束之前的最后一个视图底部约束

    【讨论】:

    • 我从子视图内部添加了一些代码。这些都有高度限制。有没有办法找到总高度并将其传递给子视图的框架?
    • 能否在github提供demo
    • 我刚刚在谷歌上搜索了如何做到这一点,看起来您需要一台 Mac,但我使用的是 iPad Pro……屏幕截图有帮助吗?
    • 我已经添加了屏幕截图
    • 根据你的照片你得到了默认的tableHeight 44,它是在无法推断高度时由ios制作的
    猜你喜欢
    • 2016-08-19
    • 1970-01-01
    • 2012-08-28
    • 2017-07-08
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    • 2013-12-09
    • 2012-01-22
    相关资源
    最近更新 更多