Ios 滚动时自定义表格视图单元格绘制的高度错误

Ios 滚动时自定义表格视图单元格绘制的高度错误,ios,swift,uitableview,cell,Ios,Swift,Uitableview,Cell,我正在willDisplayCell方法中自定义我的表视图单元格。由于某些原因,它在滚动时绘制了一些高度错误的子视图(参见视频)。我不明白为什么 override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { cell.contentView.backgroundColor=UIColor.

我正在willDisplayCell方法中自定义我的表视图单元格。由于某些原因,它在滚动时绘制了一些高度错误的子视图(参见视频)。我不明白为什么

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {

    cell.contentView.backgroundColor=UIColor.clearColor()
    cell.reloadInputViews()

    let height = cell.frame.height - 15

    var whiteRoundedCornerView:UIView!
    whiteRoundedCornerView=UIView(frame: CGRectMake(7,10,self.view.bounds.width-14,height))
    whiteRoundedCornerView.backgroundColor=getColorByID(colorID!)
    whiteRoundedCornerView.layer.masksToBounds=false

    whiteRoundedCornerView.layer.shadowOpacity = 1.55;

    whiteRoundedCornerView.layer.shadowOffset = CGSizeMake(1, 0);
    whiteRoundedCornerView.layer.shadowColor=UIColor.grayColor().CGColor

    whiteRoundedCornerView.layer.cornerRadius=5.0
    whiteRoundedCornerView.layer.shadowOffset=CGSizeMake(-1, -1)
    whiteRoundedCornerView.layer.shadowOpacity=0.5

    whiteRoundedCornerView.layer.shouldRasterize = true
    whiteRoundedCornerView.layer.rasterizationScale = UIScreen.mainScreen().scale


    if cell.contentView.subviews.count < 6 {  //  to avoid multible subview adding when scrolling...

        cell.contentView.addSubview(whiteRoundedCornerView)
        cell.contentView.sendSubviewToBack(whiteRoundedCornerView)

    }
}
如果我不检查
tableview.subviews.count
它将在滚动时向单元格添加大量子视图


我想在重复使用单元格时更改现有子视图的高度。

您有一个不多次添加子视图的检查。发生这种情况时,您已经在前面添加了子视图,但它们的高度现在可能错误,您必须更新它们

UITableView
重用单元格,因此具有不同高度的新单元格可能已经包含您的子视图,但由于您没有更新它,因此其高度可能错误

您应该清楚地将子视图的设置与布局分开,如下所示:

class MyCell: UITableViewCell {

    private let whiteRoundedCornerView = UIView()


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

        setUp()
    }


    required init?(coder: NSCoder) {
        super.init(coder: coder)

        setUp()
    }


    override func layoutSubviews() {
        super.layoutSubviews()

        let bounds = self.bounds

        var whiteRoundedCornerViewFrame = CGRect()
        whiteRoundedCornerViewFrame.origin.x = 7
        whiteRoundedCornerViewFrame.origin.y = 10
        whiteRoundedCornerViewFrame.size.width = bounds.width - 7 - whiteRoundedCornerViewFrame.origin.x
        whiteRoundedCornerViewFrame.size.height = bounds.height - 5 - whiteRoundedCornerViewFrame.origin.y
        whiteRoundedCornerView.frame = whiteRoundedCornerViewFrame
    }


    private func setUp() {
        setUpWhiteRoundedCornerView()
    }


    private func setUpWhiteRoundedCornerView() {
        let child = whiteRoundedCornerView
        child.backgroundColor = .greenColor()

        let layer = child.layer
        layer.cornerRadius = 5.0
        layer.rasterizationScale = UIScreen.mainScreen().scale
        layer.shadowColor = UIColor.grayColor().CGColor
        layer.shadowOffset = CGSize(width: -1, height: -1)
        layer.shadowOpacity = 0.5
        layer.shouldRasterize = true

        insertSubview(child, atIndex: 0)
    }
}

如果不同行上的数据大小不同,则必须动态设置tableview单元格的高度

代码如下:

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

    var height:CGFloat

    let constraint1:CGSize = CGSizeMake(self.view.frame.size.width/2-70, 5000.0)
    let string="eefdgvfgfhgfgfhgfgjhidffjo;dkfnkjfldjfkjfkjfldfjkkjhbkjflfjihkfjkfjgfkjfkgfkgjlfgnfjgnfgnfgbkgmfjgfkgjfkggjlfgklkgkgkglkgggfkglgkkgjlgkgk"

    let answerSize = string.boundingRectWithSize(constraint1, options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont.systemFontOfSize(17.0)], context: nil)
    let questionSize = string.boundingRectWithSize(constraint1, options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont.systemFontOfSize(17.0)], context: nil)   

    height=answerSize.height + questionSize.height

    return height
}

我的问题是,为什么要用
willDisplayCell
方法来做这些事情?而不是在
cellforrowatinexpath
中?如果我将此代码放在cellforrowatinexpath中,则性能非常差..我认为您是对的。。。但是,当再次使用单元格时,如何更新子视图高度?当使用手动布局(您所做的)时,正确布局单元格中子视图的最佳方法是子类化
UITableViewCell
,并覆盖它的
layoutSubviews
。这是执行布局更改的位置。您刚刚复制了相同的错误。如果子视图已经存在,则不再对其进行布局。我会马上更新我的答案。我以为UITableViewAutomaticDimension会从iOS9开始处理这个问题?
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat{

    var height:CGFloat

    let constraint1:CGSize = CGSizeMake(self.view.frame.size.width/2-70, 5000.0)
    let string="eefdgvfgfhgfgfhgfgjhidffjo;dkfnkjfldjfkjfkjfldfjkkjhbkjflfjihkfjkfjgfkjfkgfkgjlfgnfjgnfgnfgbkgmfjgfkgjfkggjlfgklkgkgkglkgggfkglgkkgjlgkgk"

    let answerSize = string.boundingRectWithSize(constraint1, options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont.systemFontOfSize(17.0)], context: nil)
    let questionSize = string.boundingRectWithSize(constraint1, options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont.systemFontOfSize(17.0)], context: nil)   

    height=answerSize.height + questionSize.height

    return height
}