ios - 添加 subview 后,Swift Playground UITable View Cell 未调整大小

标签 ios swift uitableview row-height

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,当用户触摸一行时, subview 就会添加到屏幕上。当他们单击另一行时,最后一个 subview 消失(并且该行应缩小回正常大小)。 subview 显示完美(并在单击另一行时消失),但它卡在该行之外并覆盖了一些其他选项。此外,当 TableView 在屏幕旋转后重新加载时, subview 最终会出现在表的其他行后面。

我希望调整带有 subview 的行的大小,以便它与 subview 的框架匹配。此外,每个 subview 的大小也不同,具体取决于其中包含的文本和图像。因此,我尝试使用自动布局和 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
}

}

subview 的各个部分定义其高度如下(还有更多部分,但它们都具有相同类型的约束:

//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
}

最佳答案

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

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 内部应该只有一个 View 连接到底部,如果添加多个 View ,那么如果两个 View 也都连接到顶部,就会发生冲突,所以你必须中断在 Hook 新的之前最后查看底部约束

关于ios - 添加 subview 后,Swift Playground UITable View Cell 未调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51508330/

相关文章:

swift - 按正确的顺序从解析中获取图像

ios - 移动导航栏框架是否正确?

swift - 可编码结构包含协议(protocol)属性

iOS图像在按下按钮时旋转

swift - 在 NSTokenField 中设置 token

swift - 如何在 Swift 中将十进制数转换为二进制数?

iphone - 重现 iPhone SMS 应用程序用户界面的最简单方法?

ios - 在 UITableview 的单元格中输入数据

ios - RMStore requestProducts 在请求产品时给出异常

ios - 有什么办法可以将 Xcode 项目从 8 降级到 7?