首页 > 解决方案 > Swift 行高和 cell.frame.height / cell.contentView.frame.heigth 不一样

问题描述

我有一个使用所有委托函数初始化的表视图。我有一个名为 FeedCell 的自定义单元格。我正在尝试在单元格内获取行高。但是行高和 cell.frame.height / cell.contentView.frame.heigth 不一样。代码可以在下面找到,欢迎任何建议! 表初始化器 细胞类 在此处输入图像描述

标签: iosswiftuitableview

解决方案


如果您希望单元格动态更改,您可以尝试接近。

//will make auto height
 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
       return UITableView.automaticDimension
        
 }

//register your cell
tableView.register(FeedCell.self, forCellReuseIdentifier: FeedCell.identifier)

use cell in cell for row at
 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: FeedCell.identifier) as! FeedCell
    cell.backgroundColor = .clear
    cell.withImage = true
    cell.withSubtitle = true
    cell.withButton = false
          
    cell.titleLabel.text = ""
    cell.descriptionLabel.text = ""        
    return cell
}

and a sample feed cell code as you need 

extension FeedCell {
    static let identifier = "FeedCell"
}
class FeedCell: UITableViewCell {
    
    let titleLabel = UILabel()
    let subtitleLabel = UILabel()
    let descriptionLabel = UILabel()
    let iconImageView = UIImageView()
    var button = UIButton()
    
    var withImage: Bool = true {
        didSet {
            if withImage {
                self.iconImageView.isHidden = false
                self.iconImageWidthConstraint.constant = self.imageSide
                self.iconImageHeightConstraint.constant = self.imageSide
                self.titleLabelLeadingConstraint.isActive = true
                self.separatorInsetStyle = .beforeImage
            } else {
                self.iconImageView.isHidden = true
                self.iconImageWidthConstraint.constant = 0
                self.iconImageHeightConstraint.constant = 0
                self.titleLabelLeadingConstraint.isActive = false
                self.separatorInsetStyle = .auto
            }
            self.updateConstraints()
        }
    }
    
    var roundImage: Bool = false {
        didSet {
            self.layoutSubviews()
        }
    }
    
    var withSubtitle: Bool = true {
        didSet {
            self.descriptionLabelTopConstraint.isActive = false
            self.descriptionLabel.removeConstraint(self.descriptionLabelTopConstraint)
            if withSubtitle {
                self.subtitleLabel.isHidden = false
                self.descriptionLabelTopConstraint = self.descriptionLabel.topAnchor.constraint(equalTo: self.subtitleLabel.bottomAnchor, constant: self.spaceAfterSubtitle)
            } else {
                self.subtitleLabel.isHidden = true
                self.descriptionLabelTopConstraint = self.descriptionLabel.topAnchor.constraint(equalTo: self.titleLabel.bottomAnchor, constant: self.spaceAfterSubtitle)
            }
            self.descriptionLabelTopConstraint.isActive = true
            self.updateConstraints()
        }
    }
    
    var withButton: Bool = false {
        didSet {
            if withButton {
                self.button.isHidden = false
                self.descriptionLabelBottomConstraint.isActive = false
                self.buttonTopConstraint.isActive = true
                self.buttonBottomConstraint.isActive = true
            } else {
                self.button.isHidden = true
                self.buttonTopConstraint.isActive = false
                self.buttonBottomConstraint.isActive = false
                self.descriptionLabelBottomConstraint.isActive = true
            }
            self.updateConstraints()
        }
    }
    
    var centerXButton: Bool = false {
        didSet {
            if self.centerXButton {
                self.buttonLeadingConstraint.isActive = false
                self.buttonCenterXConstraint.isActive = true
            } else {
                self.buttonCenterXConstraint.isActive = false
                self.buttonLeadingConstraint.isActive = true
            }
            self.updateConstraints()
        }
    }
    
    var imageSide: CGFloat = 40 {
        didSet {
            self.iconImageWidthConstraint.constant = self.imageSide
            self.iconImageHeightConstraint.constant = self.imageSide
            self.updateConstraints()
        }
    }
    
    var topSpace: CGFloat = 11 {
        didSet {
            self.iconImageTopConstraint.constant = self.topSpace
            self.titleLabelTopConstraint.constant = self.topSpace - 2
            self.updateConstraints()
        }
    }
    
    var spaceAfterTitle: CGFloat = 2 {
        didSet {
            if self.withSubtitle {
                self.subtitleLabelTopConstraint.constant = self.spaceAfterTitle
            } else {
                self.descriptionLabelTopConstraint.constant = self.spaceAfterTitle
            }
            self.updateConstraints()
        }
    }
    
    var spaceAfterSubtitle: CGFloat = 2 {
        didSet {
            if self.withSubtitle {
                self.descriptionLabelTopConstraint.constant = self.spaceAfterSubtitle
            }
            self.updateConstraints()
        }
    }
    
    var spaceAfterDescribtion: CGFloat = 15 {
        didSet {
            self.buttonTopConstraint.constant = self.spaceAfterDescribtion
            self.updateConstraints()
        }
    }
    
    var bottomSpace: CGFloat = 7 {
        didSet {
            if self.withButton {
                self.buttonBottomConstraint.constant = -self.bottomSpace
            } else {
                self.descriptionLabelBottomConstraint.constant = -self.bottomSpace
            }
            self.updateConstraints()
        }
    }
    
    var spaceBetweenImageAndTitles: CGFloat = 15 {
        didSet {
            self.titleLabelLeadingConstraint.constant = self.spaceBetweenImageAndTitles
            self.updateConstraints()
        }
    }
    
    override var contentViews: [UIView] {
        return [self.iconImageView, self.titleLabel, self.subtitleLabel, self.descriptionLabel]
    }
    
    //constraints
    private var iconImageTopConstraint: NSLayoutConstraint!
    private var iconImageBottomConstraint: NSLayoutConstraint!
    private var iconImageWidthConstraint: NSLayoutConstraint!
    private var iconImageHeightConstraint: NSLayoutConstraint!
    private var titleLabelLeadingConstraint: NSLayoutConstraint!
    private var titleLabelTopConstraint: NSLayoutConstraint!
    private var subtitleLabelTopConstraint: NSLayoutConstraint!
    private var descriptionLabelTopConstraint: NSLayoutConstraint!
    private var descriptionLabelBottomConstraint: NSLayoutConstraint!
    private var buttonTopConstraint: NSLayoutConstraint!
    private var buttonLeadingConstraint: NSLayoutConstraint!
    private var buttonCenterXConstraint: NSLayoutConstraint!
    private var buttonBottomConstraint: NSLayoutConstraint!
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.commonInit()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func awakeFromNib(){
        super.awakeFromNib()
    }
    
    override func commonInit() {
        super.commonInit()
        let marginGuide = contentView.layoutMarginsGuide
        
        //iconImageView
        self.iconImageView.layer.cornerRadius = 10
        self.contentView.addSubview(self.iconImageView)
        self.iconImageView.translatesAutoresizingMaskIntoConstraints = false
        self.iconImageView.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
        self.iconImageTopConstraint = self.iconImageView.topAnchor.constraint(equalTo: marginGuide.topAnchor, constant: self.topSpace)
        self.iconImageTopConstraint.isActive = true
        self.iconImageWidthConstraint = self.iconImageView.widthAnchor.constraint(equalToConstant: self.imageSide)
        self.iconImageWidthConstraint.isActive = true
        self.iconImageHeightConstraint = self.iconImageView.heightAnchor.constraint(equalToConstant: self.imageSide)
        self.iconImageHeightConstraint.isActive = true
        self.iconImageBottomConstraint = self.iconImageView.bottomAnchor.constraint(lessThanOrEqualTo: marginGuide.bottomAnchor, constant: -(self.bottomSpace))
        self.iconImageBottomConstraint.priority = UILayoutPriority.init(900)
        self.iconImageBottomConstraint.isActive = true

        //titleLabel
        self.titleLabel.numberOfLines = 0
        self.titleLabel.textAlignment = .left
        self.titleLabel.textColor = UIColor.white
        self.contentView.addSubview(self.titleLabel)
        self.titleLabel.translatesAutoresizingMaskIntoConstraints = false
        self.titleLabelLeadingConstraint = self.titleLabel.leadingAnchor.constraint(equalTo: self.iconImageView.trailingAnchor, constant: self.spaceBetweenImageAndTitles)
        self.titleLabelLeadingConstraint.isActive = true
        
        let titleLabelAdditionalLeadingConstraint = self.titleLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor)
        titleLabelAdditionalLeadingConstraint.priority = UILayoutPriority.init(900)
        titleLabelAdditionalLeadingConstraint.isActive = true
        
        self.titleLabelTopConstraint = self.titleLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor, constant: self.topSpace - 2)
        self.titleLabelTopConstraint.isActive = true
        
        self.titleLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
        
        //subtitleLabel
        self.subtitleLabel.numberOfLines = 0
        self.subtitleLabel.font = UIFont.system(weight: UIFont.FontWeight.regular, size: 15)
        self.subtitleLabel.textAlignment = .left
        self.subtitleLabel.textColor = UIColor.white
        self.contentView.addSubview(self.subtitleLabel)
        self.subtitleLabel.translatesAutoresizingMaskIntoConstraints = false
        self.subtitleLabel.leadingAnchor.constraint(equalTo: self.titleLabel.leadingAnchor).isActive = true
        self.subtitleLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
        self.subtitleLabelTopConstraint = self.subtitleLabel.topAnchor.constraint(equalTo: self.titleLabel.bottomAnchor, constant: self.spaceAfterTitle)
        self.subtitleLabelTopConstraint.isActive = true
    
        //descriptionLabel
        self.descriptionLabel.numberOfLines = 0
        self.descriptionLabel.font = UIFont.system(weight: UIFont.FontWeight.regular, size: 15)
        self.descriptionLabel.textAlignment = .left
        self.descriptionLabel.textColor = .gray
        self.contentView.addSubview(self.descriptionLabel)
        self.descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
        
        self.descriptionLabel.leadingAnchor.constraint(equalTo: self.titleLabel.leadingAnchor).isActive = true
        self.descriptionLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
        self.descriptionLabelTopConstraint = self.descriptionLabel.topAnchor.constraint(equalTo: self.subtitleLabel.bottomAnchor, constant: self.spaceAfterSubtitle)
        self.descriptionLabelTopConstraint.isActive = true
        self.descriptionLabelBottomConstraint = self.descriptionLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor, constant: -self.bottomSpace)
        self.descriptionLabelBottomConstraint.isActive = true
        
        self.contentView.addSubview(self.button)
        self.button.titleLabel?.numberOfLines = 0
        self.button.contentHorizontalAlignment = UIControl.ContentHorizontalAlignment.left
        self.button.translatesAutoresizingMaskIntoConstraints = false
        
        self.buttonLeadingConstraint = self.button.leadingAnchor.constraint(equalTo: self.titleLabel.leadingAnchor)
        self.buttonLeadingConstraint.isActive = true

        self.buttonCenterXConstraint = self.button.centerXAnchor.constraint(equalTo: self.titleLabel.centerXAnchor)
        self.buttonCenterXConstraint.isActive = false
        
        self.buttonTopConstraint = self.button.topAnchor.constraint(equalTo: self.descriptionLabel.bottomAnchor, constant: self.spaceAfterDescribtion)
        self.buttonTopConstraint.isActive = false
//
        self.buttonBottomConstraint = self.button.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor, constant: -self.bottomSpace)
        self.buttonBottomConstraint.isActive = false
        
        self.buttonBottomConstraint.priority = UILayoutPriority.init(900)

        
        self.setDefaultParametrs()
    }
    
    private func setDefaultParametrs() {
        self.withImage = true
        self.withSubtitle = true
        self.withButton = true
        
        self.accessoryType = .none
        self.separatorInsetStyle = .beforeImage
        
        self.titleLabel.text = "Title"
        self.titleLabel.textAlignment = .left
        self.titleLabel.textColor = UIColor.white
        self.subtitleLabel.text = "Subtitle"
        self.subtitleLabel.font = UIFont.system(weight: UIFont.FontWeight.regular, size: 15)
        self.subtitleLabel.textAlignment = .left
        self.subtitleLabel.textColor = UIColor.black
        self.descriptionLabel.text = ""
        self.descriptionLabel.textAlignment = .left
        self.descriptionLabel.textColor = .gray
        self.button.setTitle("Button")
        
        self.imageSide = 40
        self.roundImage = false
        self.topSpace = 11
        self.spaceAfterTitle = 2
        self.spaceAfterSubtitle = 2
        self.spaceAfterDescribtion = 15
        self.bottomSpace = 7
        self.spaceBetweenImageAndTitles = 15
    }
    
    override func prepareForReuse() {
        super.prepareForReuse()
        self.setDefaultParametrs()
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        if self.roundImage {
            self.iconImageView.layer.cornerRadius = self.imageSide / 2
        } else {
            self.iconImageView.layer.cornerRadius = self.imageSide * 0.158
        }
        
        switch self.separatorInsetStyle {
        case .all:
            self.separatorInset.left = 0
        case .beforeImage:
            self.separatorInset.left = self.layoutMargins.left + self.imageSide + self.spaceBetweenImageAndTitles - 2
        case .none:
            self.separatorInset.left = self.frame.width
        case .auto:
            self.separatorInset.left = self.layoutMargins.left
        }
        

    }
    
    
}

推荐阅读