Как разместить динамическую многострочную UILabel в tableHeaderView - PullRequest
0 голосов
/ 18 апреля 2019

enter image description here Я создал xib-представление, связанное с классом UIView с именем InstructionView. Это представление не содержит ничего, кроме UILabel, ограниченного полями со всех сторон.

Количество строк метки равно 0, а разрыв строки установлен на перенос слов.

Это представление затем добавляется в stackView. И этот stackView затем устанавливается как tableHeaderView tableView.

override func viewsToAddAfterTitle() -> [UIView] {
    var views: [UIView] = []
    if let view = Bundle.main.loadNibNamed(Constants.Nibs.instructionView, owner: self, options: nil)?.first as? InstructionView {
        view.fillWithInstruction("A long text that needs more than 1 line")
        views.append(view)
        view.setNeedsLayout()
        view.layoutIfNeeded()
    }
    return views
}

func addTableHeaderView() {
    if let viewHeader: ViewHeader = Bundle.main.loadNibNamed(Constants.Nibs.viewHeader, owner: self, options: nil)?.first as? ViewHeader {
        viewHeader.setTitle(titleText: headerTitle())
        var arrangedStackSubviews: [UIView] = viewsToAddBeforeTitle()
        arrangedStackSubviews.append(viewHeader)
        arrangedStackSubviews.append(contentsOf: viewsToAddAfterTitle())
        let stack = UIStackView(arrangedSubviews: arrangedStackSubviews)
        stack.distribution = .fill
        stack.axis = NSLayoutConstraint.Axis.vertical
        stack.alignment = .fill
        stack.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        tableView.tableHeaderView = stack
    }
}

Функция fillWithInstruction вызывается при загрузке пера. Я звоню, чтобы установить текст метки.

func fillWithInstruction(_ instruction: String) {
    instructionLabel.text = instruction
    instructionLabel.sizeToFit()
}

Я попытался вычислить intrinsicContentSize и на основании этого установить ограничения на высоту метки. Я попытался разместить метку внутри представления и / или стека.

Ничего из того, что я пробовал, не сработало. Я хочу, чтобы метка показывала более 1 строки, если для этого текста требуется больше 1. Но в настоящее время она всегда показывает 1 строку.

Ответы [ 2 ]

0 голосов
/ 18 апреля 2019

Хорошо, вот реальная сделка:

Создать это расширение:

extension String {
func heightNeededForLabel(_ label: UILabel) -> CGFloat {
    let width = label.frame.size.width
    guard let font = label.font else {return 0}
    let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
    let boundingBox = self.boundingRect(with: constraintRect, options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: [NSAttributedString.Key.font: font], context: nil)
    return boundingBox.height + 20
}

}

+ 20 - это просто дать ему больше места

И назовите это так:

func fillWithInstruction(_ instruction: String) {
    instructionLabel.text = instruction
    guard let instructionLabel = instructionLabel else {return}
    instructionLabel.addConstraint(NSLayoutConstraint(item: instructionLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 2, constant: instruction.heightNeededForLabel(instructionLabel)))

}
0 голосов
/ 18 апреля 2019

Создайте UITableViewHeaderFooterView и используйте его с делегатом viewForHeaderInSection.

Посмотрите на этот пример

Пользовательский вид заголовка из xib для UITableView

...