在Swift 3中动态调整UITableViewCell的高度失败

时间:2017-07-10 06:27:19

标签: ios swift uitableview uitableviewautomaticdimension

我有一个自定义的UITableViewCell,我想让它更新我的标签文本内容的高度。
但我尝试在我的ViewController ViewDidLoad中使用此代码:

import snapKit
import UIKit

class ChatRightTextTableViewCell: UITableViewCell {

static let identifier = "ChatRightTextTableViewCell"
var cellHeight: CGFloat = 0

var labelContent:UILabel = { ()->UILabel in
    let ui:UILabel = GeneratorLabel()
    ui.textColor = UIColor(red:0.20, green:0.20, blue:0.20, alpha:1.00)
    ui.backgroundColor = UIColor.white
    ui.font = defaultTextFont
    ui.numberOfLines = 0
    ui.lineBreakMode = NSLineBreakMode.byCharWrapping
    ui.layer.cornerRadius = defaultButtonRadius
    ui.layer.masksToBounds = true
    return ui
}()

var labelDatetime:UILabel = { ()->UILabel in
    let ui = GeneratorLabel()
    ui.font = defaultMessageTimeFont
    ui.textColor = defaultChatTimeColor
    ui.numberOfLines = 0
    return ui
}()

var icon:UIImageView = { ()->UIImageView in
    let ui = GeneratorAvatarImageView()
    ui.isUserInteractionEnabled = true
    return ui
}()

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

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

override func layoutSubviews() {
    super.layoutSubviews()
    loadVFL()
}

override func awakeFromNib() {
    super.awakeFromNib()
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}


func loadContent() {
    backgroundColor = defaultBackgroundColor
    selectionStyle = .none
    contentView.addSubview(labelContent)
    contentView.addSubview(labelDatetime)
    contentView.addSubview(icon)
}

func loadVFL() {

    let datetimeHeight:CGFloat = UIScreen.main.bounds.height*0.0195 //13

    let contentWidth:CGFloat = contentView.bounds.width*0.62  //254.5
    let iconLeftPadding:CGFloat = contentView.bounds.width*0.0266 //15
    let contentAndDatePadding:CGFloat = UIScreen.main.bounds.height*0.0089 //6
    let dateAndBottomPaddding:CGFloat = UIScreen.main.bounds.height*0.0090 //6
    let topPadding:CGFloat            = UIScreen.main.bounds.height*0.0149 //10
    let nameLabelBottomPadding:CGFloat = UIScreen.main.bounds.height*0.0075 //5

    let views = DictionaryOfInstanceVariables(self, objects: "labelContent","labelDatetime","icon")
    let metrics = ["padding":iconLeftPadding,"contentAndDatePadding":contentAndDatePadding,"dateAndBottomPaddding":dateAndBottomPaddding,"nameLabelBottomPadding":nameLabelBottomPadding,"topPadding":topPadding]

    labelContent.frame = CGRect(x: 0, y: 0, width: contentWidth, height: CGFloat.greatestFiniteMagnitude)
    labelContent.sizeToFit()

    icon.snp.makeConstraints { (make) -> Void in
        make.width.equalTo(defaultChatroomIconWidth)
        make.height.equalTo(defaultChatroomIconWidth)
        make.centerY.equalToSuperview()
    }

    labelDatetime.snp.makeConstraints { (make) in
        make.height.equalTo(datetimeHeight)
    }

    labelContent.backgroundColor = UIColor.red
    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:[labelContent]-padding-[icon]-padding-|", options: [], metrics: metrics, views: views))
    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:[labelDatetime]-padding-[icon]-padding-|", options: [], metrics: metrics, views: views))
    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-topPadding-[labelContent]-contentAndDatePadding-[labelDatetime]-dateAndBottomPaddding-|", options: [], metrics: metrics, views: views))
    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-topPadding-[icon]", options: [], metrics: metrics, views: views))
}
}


它似乎没有更新高度 关于我的细胞限制我有什么问题?
感谢。

![cell constrain wrong like this.

section .text

global _start ; Declare global entry oint for ld
_start:

    jmp short message ; Jump to where or message is at so we can do a call to push the address onto the stack

    code:   
    xor rax, rax    ; Clean up the registers
    xor rbx, rbx
    xor rcx, rcx
    xor rdx, rdx

    ; Try to change the N to a space
    pop rsi ; Get address from stack
    mov al, 0x20 ; Load 0x20 into RAX
    mov [rsi], al; Why segfault?
    xor rax, rax; Clear again

    ; write(rdi, rsi, rdx) = write(file_descriptor, buffer, length)
    mov al, 0x01    ; write the command for 64bit Syscall Write (0x01) into the lower 8 bits of RAX
    mov rdi, rax    ; First Paramter, RDI = 0x01 which is STDOUT, we move rax to ensure the upper 56 bits of RDI are zero
    ;pop rsi        ; Second Parameter, RSI = Popped address of message from stack
    mov dl, 25  ; Third Parameter, RDX = Length of message
    syscall     ; Call Write

    ; exit(rdi) = exit(return value)    
    xor rax, rax    ; write returns # of bytes written in rax, need to clean it up again
    add rax, 0x3C   ; 64bit syscall exit is 0x3C
    xor rdi, rdi    ; Return value is in rdi (First parameter), zero it to return 0
    syscall     ; Call Exit

    message:
    call code   ; Pushes the address of the string onto the stack
    db 'AAAABBBNAAAAAAAABBBBBBBB',0x0A

3 个答案:

答案 0 :(得分:1)

疑难杂症,

如果你使用了xib,你会注意到这个警告,因为你已经对它进行了编码并且放置标签很难猜到这个问题:)

您正在使用两个标签,这些标签基本上根据它们显示的内容决定单元格的高度。但由于两者在垂直轴上都具有相同内容拥抱优先级,因此仅对这些标签提供顶部和底部约束是不够的。

您必须将内容拥抱优先于垂直轴设置为其中一个标签(您认为显然会有较小的内容)到更高的值,以提供足够的数据来计算单元格的动态高度。

摘要:

只需设置

即可
labelDatetime.setContentHuggingPriority(252, for: .vertical)

var labelDatetime:UILabel = { ()->UILabel in
let ui = GeneratorLabel()
ui.font = defaultMessageTimeFont
ui.textColor = defaultChatTimeColor
ui.numberOfLines = 0
ui..setContentHuggingPriority(252, for: .vertical)
return ui
}()

答案 1 :(得分:0)

Autolayout通常会在您使用xib的情况下提供警告。这是您的问题:内容拥抱优先级&内容抗压缩。

内容拥抱优先级是一个值,表示视图的内容应该优先在超级视图自身的约束上拉伸它的超级视图。在这种情况下,您的标签并不优先于单元格内容视图来拉伸它,因此它会被压扁。

内容压缩阻力类似地是指示视图内容优先于基于其自身来限制其超视图帧的值。例如,如果您的单元格想要达到高度1,但是您的标签具有更高的内容抗压性和高度,请说2,单元格将被强制限制为2。

here提供了对此的一个很好的解释。

让我们解决您的问题。

分配更大的内容拥抱优先级或内容压缩阻力。在您的情况下,似乎标签没有优先拉伸单元格,因此设置拥抱优先级:

labelDatetime.setContentHuggingPriority(500, for: .vertical)

或者,尝试内容压缩以使小区优先于控制其自身的高度,同时尊重标签的边界。

答案 2 :(得分:0)

  

按照以下步骤,根据内容将UITableCell高度设置为动态。这是实现所有步骤的非常简单的方法。

  • UITableViewCell删除所有约束。
  • 删除所有编程约束。
  • 现在设置图中给出的UITableViewCell的所有约束。 Table View Constraint
  • 表示提供所有约束leftrighttopbottom
  • 如果您需要标签背景,请使用xCode右侧的inspector of attribute
  • 如果您想使用无线电,请使用identity inspector标签并添加USER DEFINED RUNTIME ATTRIBUTES密钥路径 - > layer.cornerRadius,输入 - > Number和价值 - > 5 /或你想给的东西。
  • 如果您想给予标签行数,请从Attribute Inspector选择multipleLine对齐。
  • 如果您不想要,请提供第0行的编号并选择multipleLine对齐,然后选中Automatically Adjust Font
  

现在让我们限制编程

//Set Both line in view did upload function with same format 
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 100.0
  

如果您使用

,请删除功能
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
}
  

希望这可以解决您的问题并帮助减少对所有编程语言都很重要的 code complexity