Подтвердить что ты не робот

Многострочная метка в UIStackView

При установке многострочной метки (с привязкой линии к Word Wrap) в представление стека, метка немедленно теряет строку и отображает текст метки в одной строке.

Почему это происходит и как сохранить многострочную метку в представлении стека?

4b9b3361

Ответ 1

Правильный ответ здесь: fooobar.com/questions/148411/...

  1. UILabel в UIView (Редактор → Вставить → Просмотреть)
    1. Используйте ограничения для подгонки UILabel к UIView (например, конечный пробел, верхний пробел и UIView пробел для ограничений суперпредставления)

UIStackView будет растягивать UIView для правильного размещения, а UIView будет ограничивать UILabel несколькими строками.

Ответ 2

Для горизонтального представления стека, в котором UILabel является одним из представлений, в Интерфейсном label.numberOfLines = 0 сначала установите label.numberOfLines = 0. Это должно позволить метке иметь более 1 строки. Это первоначально не работало для меня, когда у представления стека было stackView.alignment =.fill. Чтобы это работало, просто установите stackView.alignment =.center. Теперь метка может расширяться до нескольких строк в UIStackView.

Документация Apple гласит

Для всех выравниваний, кроме выравнивания заливки, представление стека использует свойство внутреннего размера каждого упорядоченного представления при расчете его размера перпендикулярно оси стеков

Обратите внимание на слово, кроме здесь. Когда .fill используются горизонтальная UIStackView не изменяет размер себя вертикально с помощью расположенных размеров подвидов.

Ответ 3

  • Сначала установите количество строк в метке 0
  • Представление стека по-прежнему не перерастет в multiLine если вы не multiLine ему фиксированную ширину. Когда мы фиксируем его ширину, он переходит в многострочное, когда эта ширина достигается, как показано:

screen recording

Если мы не дадим фиксированную ширину стековому виду, все становится неоднозначным. Как долго будет расти представление стека с меткой (если значение метки является динамическим)?

Надеюсь, что это может решить вашу проблему.

Ответ 4

Просто установите количество строк равным 0 в инспекторе атрибутов для метки. Это будет работать для вас.

enter image description here

Ответ 5

Установка предпочитаемого MaxLayoutWidth для UILabel работала для меня

self.myLabel.preferredMaxLayoutWidth = self.bounds.size.width;

Ответ 6

iOS 9+

Вызовите [textLabel sizeToFit] после установки текста UILabel.

sizeToFit перекомпоновает многострочную метку, используя предпочитаемый параметр MaxWidth. Метка изменит размер stackView, который изменит размер ячейки. Никаких дополнительных ограничений, кроме прикрепления стека к представлению контента, не требуется.

Ответ 7

Ниже приведена реализация многострочной метки на игровой площадке с разрывом строки внутри UIStackView. Он не требует встраивания UILabel внутрь чего-либо и был протестирован с Xcode 9.2 и Swift 4. Надеюсь, это поможет.

import UIKit
import PlaygroundSupport

let containerView = UIView()
containerView.frame = CGRect.init(x: 0, y: 0, width: 400, height: 500)
containerView.backgroundColor = UIColor.white

var label = UILabel.init()
label.textColor = .black
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "This is an example of sample text that goes on for a long time. This is an example of sample text that goes on for a long time."

let stackView = UIStackView.init(arrangedSubviews: [label])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.distribution = .fill
stackView.alignment = .fill
containerView.addSubview(stackView)
stackView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
stackView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
stackView.widthAnchor.constraint(equalTo: containerView.widthAnchor).isActive = true
stackView.heightAnchor.constraint(equalTo: containerView.heightAnchor).isActive = true

PlaygroundPage.current.liveView = containerView

Ответ 8

Добавить свойства UIStackView,

stackView.alignment = .fill
stackView.distribution = .fillProportionally
stackView.spacing = 8.0
stackView.axis = .horizontal

Вместо добавления метки внутри UIView которая не требуется. Если вы используете внутри UITableViewCell пожалуйста, перезагрузите данные при ротации.

Ответ 9

Волшебным трюком для меня было установить widthAnchor к UIStackView.

Установка leadingAnchor и trailingAnchor не будет работать, но установка centerXAnchor и widthAnchor правильно сделал дисплей UILabel.

Ответ 10

Системный макет должен определять происхождение, ширину и высоту, чтобы нарисовать его подпредставления, в этом случае все ваши подпредставления имеют одинаковый приоритет, в этом случае возникают конфликты, система компоновки не знает зависимостей между представлениями, из которых одно рисует первым, вторым и т.д.

Задать сжатие подпредставлений стека поможет решить проблему с несколькими строками, в зависимости от того, является ли ваш вид стека горизонтальным или вертикальным и какой из них вы хотите превратить в несколько строк. stackOtherSubviews.setContentCompressionResistancePriority(.defaultHight, for:.horizontal) lblTitle.setContentCompressionResistancePriority(.defaultLow, for:.horizontal)

Ответ 11

Попробовав все вышеизложенное, я обнаружил, что для UIStackView не нужно менять свойства. Я просто изменяю свойства UILabels следующим образом (метки уже добавлены в представление вертикального стека):

Swift 4 пример:

    [titleLabel, subtitleLabel].forEach(){
        $0.numberOfLines = 0
        $0.lineBreakMode = .byWordWrapping
        $0.setContentCompressionResistancePriority(UILayoutPriority.required, for: .vertical)
    }

Ответ 12

В моем случае я следил за предыдущими предложениями, но мой текст все еще усекался до одной строки, но только в ландшафте. Оказывается, я нашел невидимый символ \0 null в тексте метки, который был виновником. Он должен быть введен вместе с символом em, который я вставил. Чтобы убедиться, что это также происходит в вашем случае, используйте View Debugger, чтобы выбрать метку и проверить ее текст.

Ответ 13

Xcode 9.2:

Просто установите количество строк в 0. Раскадровка будет выглядеть странно после установки этого. Не волнуйтесь, запустите проект. Во время работы все изменится в соответствии с настройками раскадровки. Я думаю, что это своего рода ошибка в раскадровке. enter image description here

Советы: Установите "номер лайнера в 0" в последнем. сбросьте его, если вы хотите отредактировать другой вид и установите 0 после редактирования.

enter image description here

Ответ 14

Что сработало для меня!

stackview: выравнивание: заполнение, распределение: заполнение, ограничение пропорциональной ширине для суперпредставления ex. 0,8,

метка: центр и линии = 0

Ответ 16

Вот полный пример вертикального UIStackView состоящего из многострочного UILabel с автоматической высотой.

Обтекание меток зависит от ширины стека и высоты стека зависит от высоты обтекания меток. (При таком подходе вам не нужно вставлять метки в UIView.) (Swift 5, iOS 12.2)

enter image description here

// A vertical stackview with multiline labels and automatic height.
class ThreeLabelStackView: UIStackView {
    let label1 = UILabel()
    let label2 = UILabel()
    let label3 = UILabel()

    init() {
        super.init(frame: .zero)
        self.translatesAutoresizingMaskIntoConstraints = false
        self.axis = .vertical
        self.distribution = .fill
        self.alignment = .fill

        label1.numberOfLines = 0
        label2.numberOfLines = 0
        label3.numberOfLines = 0
        label1.lineBreakMode = .byWordWrapping
        label2.lineBreakMode = .byWordWrapping
        label3.lineBreakMode = .byWordWrapping
        self.addArrangedSubview(label1)
        self.addArrangedSubview(label2)
        self.addArrangedSubview(label3)

        // (Add some test data, a little spacing, and the background color
        // make the labels easier to see visually.)
        self.spacing = 1
        label1.backgroundColor = .orange
        label2.backgroundColor = .orange
        label3.backgroundColor = .orange
        label1.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi."
        label2.text = "Hello darkness my old friend..."
        label3.text = "When I wrote the following pages, or rather the bulk of them, I lived alone, in the woods, a mile from any neighbor, in a house which I had built myself, on the shore of Walden Pond, in Concord, Massachusetts, and earned my living by the labor of my hands only."
    }

    required init(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}

Вот пример ViewController который использует его.

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let myLabelStackView = ThreeLabelStackView()
        self.view.addSubview(myLabelStackView)

        // Set stackview width to its superview.
        let widthConstraint  = NSLayoutConstraint(item: myLabelStackView, attribute: NSLayoutConstraint.Attribute.width, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.view, attribute: NSLayoutConstraint.Attribute.width, multiplier: 1, constant: 0)
        self.view.addConstraints([widthConstraint])
    }
}