这里是使用仅代码而不是自定义XIB的示例。
出于某些要求,我尝试在TableView的单元格方法中尝试使用新的StackView
某些背景-我有一个TableView
,它的单元格里面有一个stackView
。 stackView
可以具有多种视图类型,但是为了简单起见,我现在使用labels
。我创建了一个自定义的XIB(LabelInfoView
),它具有3个水平标签。它以键值对组合的形式显示数据。标签可以是多行
现在我要在stackView
单元格内的tableView
内添加其中的6个
我已设置内容拥抱和内容压缩抵抗优先级
对于名为Label的标签,>
对于名为分隔符
的标签>对于名为Info
的标签”问题-第一次加载表时,某些(并非全部)标签被随机顺序甚至是随机单元格截断(例如,第一个单元格的第三个标签视图被截断,第二个单元格的第一个,第二个和第二个这样,完全是随机的。即使在多个应用程序之间也没有固定的顺序)
(在第一个tableView的单元格中注意第5个labelView)
现在,当我将单元格从队列中移出时,滚动时,当我的第一个单元格进入屏幕,然后又回到屏幕上时,将称为prepareForReuse()
cellsStackView.removeAllArrangedSubviews() setupCard()
我首先删除
stackView
内部的所有子视图,然后再次添加它们。这次,在调用方法之后,将正确加载stackView。我尝试了很多事情,例如调整优先级和内容,但到目前为止没有任何效果!
我正在为某些要求在TableView的单元格方法中尝试新的StackView某些背景-我有一个TableView,并且它的单元格中有一个stackView。该stackView可以有多个...
这里是使用仅代码而不是自定义XIB的示例。
没有IBOutlet
或原型单元,因此只需将WorkTableViewController
分配为UITableViewController
的自定义类:
class MyThreeLabelView: UIView {
let leftLabel: UILabel = {
let v = UILabel()
return v
}()
let sepLabel: UILabel = {
let v = UILabel()
return v
}()
let rightLabel: UILabel = {
let v = UILabel()
return v
}()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
backgroundColor = .white
[leftLabel, sepLabel, rightLabel].forEach {
$0.font = UIFont.systemFont(ofSize: 16.0)
$0.translatesAutoresizingMaskIntoConstraints = false
addSubview($0)
}
// bold-italic font for left label
leftLabel.font = leftLabel.font.boldItalic
// we want left and separator labels to NOT compress or expand
leftLabel.setContentHuggingPriority(.required, for: .horizontal)
leftLabel.setContentHuggingPriority(.required, for: .vertical)
leftLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
sepLabel.setContentHuggingPriority(.required, for: .horizontal)
sepLabel.setContentHuggingPriority(.required, for: .vertical)
sepLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
// right label should hug vertically
rightLabel.setContentHuggingPriority(.required, for: .vertical)
// right label can be mutliple lines
rightLabel.numberOfLines = 0
NSLayoutConstraint.activate([
// constrain all 3 labels 10-pts from top, at least 10-pts from bottom
leftLabel.topAnchor.constraint(equalTo: topAnchor, constant: 10.0),
leftLabel.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor, constant: -10),
sepLabel.topAnchor.constraint(equalTo: leftLabel.topAnchor, constant: 0.0),
sepLabel.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor, constant: -10),
rightLabel.topAnchor.constraint(equalTo: leftLabel.topAnchor, constant: 0.0),
rightLabel.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor, constant: -10),
// constrain left label 10-pts from leading edge
leftLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10.0),
// constrain separator label 10-pts from left label
sepLabel.leadingAnchor.constraint(equalTo: leftLabel.trailingAnchor, constant: 10.0),
// constrain right label 10-pts from separator label
rightLabel.leadingAnchor.constraint(equalTo: sepLabel.trailingAnchor, constant: 10.0),
// constrain right label 10-pts from trailing edge
rightLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -10),
])
}
}
class StackCell: UITableViewCell {
let stackView: UIStackView = {
let v = UIStackView()
v.axis = .vertical
v.alignment = .fill
v.distribution = .fill
v.spacing = 0
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
override func prepareForReuse() {
super.prepareForReuse()
// remove all arrangedSubviews from stack view
stackView.arrangedSubviews.forEach {
$0.removeFromSuperview()
}
}
func commonInit() -> Void {
contentView.backgroundColor = .lightGray
// add the stack view
contentView.addSubview(stackView)
// constrain 12-pts on all 4 sides
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 12.0),
stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -12.0),
stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 12.0),
stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -12.0),
])
}
func addLabels(_ labels: [String]) -> Void {
labels.forEach {
s in
// instance of MyThreeLabelView
let v = MyThreeLabelView()
// for this example, left and separator labels don't change
v.leftLabel.text = "Assigned To"
v.sepLabel.text = "-"
// assign right label text
v.rightLabel.text = s
// add MyThreeLabelView to the stack view
stackView.addArrangedSubview(v)
}
}
}
class WorkTableViewController: UITableViewController {
let reuseID = "StackCell"
var theData: [[String]] = [[String]]()
override func viewDidLoad() {
super.viewDidLoad()
// make 8 sets of 6-rows of labels
for i in 1...8 {
let tmp: [String] = [
"1) Row \(i)",
"2) Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s",
"3) Short text.",
"4) Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s",
"5) Short text.",
"6) Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s",
]
theData.append(tmp)
}
tableView.register(StackCell.self, forCellReuseIdentifier: reuseID)
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return theData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseID, for: indexPath) as! StackCell
cell.addLabels(theData[indexPath.row])
return cell
}
}
// UIFont extension for bold / italic / boldItalic
// found here: https://stackoverflow.com/a/21777132/6257435
extension UIFont {
var bold: UIFont {
return with(.traitBold)
} // bold
var italic: UIFont {
return with(.traitItalic)
} // italic
var boldItalic: UIFont {
return with([.traitBold, .traitItalic])
} // boldItalic
func with(_ traits: UIFontDescriptor.SymbolicTraits...) -> UIFont {
guard let descriptor = self.fontDescriptor.withSymbolicTraits(UIFontDescriptor.SymbolicTraits(traits).union(self.fontDescriptor.symbolicTraits)) else {
return self
}
return UIFont(descriptor: descriptor, size: 0)
}
func without(_ traits: UIFontDescriptor.SymbolicTraits...) -> UIFont {
guard let descriptor = self.fontDescriptor.withSymbolicTraits(self.fontDescriptor.symbolicTraits.subtracting(UIFontDescriptor.SymbolicTraits(traits))) else {
return self
}
return UIFont(descriptor: descriptor, size: 0)
}
} // extension
结果:
因为我同时将numberOfLines
和leftLabel
都设置为rightLabel
设置为0
leftLabel
的宽度添加到<= Superview的宽度的50%这里是使用仅代码而不是自定义XIB的示例。
因为我同时将numberOfLines
和leftLabel
都设置为rightLabel
设置为0