it-swarm.com.ru

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

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

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

87
Boon

Правильный ответ здесь: https://stackoverflow.com/a/43110590/566360

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

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

125
Andy

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

документация Apple говорит 

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

Обратите внимание на слово кроме здесь. Когда используется .fill, горизонтальная UIStackView НЕ меняет свой размер по вертикали, используя упорядоченные размеры подпредставлений.

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

 screen recording

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

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

40
Irfan

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

 enter image description here

11
technerd

Ниже приведена реализация многострочной метки в Playground с разрывом строки внутри переменной 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
3
JaredH

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

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

2
Skoua

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

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

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

2
Sagar Daundkar

iOS 9+ 

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

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

1
aumansoftware

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

self.myLabel.preferredMaxLayoutWidth = self.bounds.size.width;
1
Pablo Martinez

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

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

1
Trung Phan

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

0
Jordan H

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

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

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

0
Michał Ziobro

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

Swift 4 пример:

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

Xcode 9.2:

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

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

 enter image description here

0
Surendra Kumar

Для тех, кто до сих пор не может заставить это работать. Попробуйте установить Autoshrink с минимальным масштабом шрифта на этой UILabel.

Скриншот UILabel Настройки автоусадки

0
Michal Mondík