Многострочная метка в UIStackView
При установке многострочной метки (с привязкой линии к Word Wrap) в представление стека, метка немедленно теряет строку и отображает текст метки в одной строке.
Почему это происходит и как сохранить многострочную метку в представлении стека?
Ответы
Ответ 1
Правильный ответ здесь: fooobar.com/questions/148411/...
-
UILabel
в UIView
(Редактор → Вставить → Просмотреть) - Используйте ограничения для подгонки
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
Ответ 15
Для тех, кто до сих пор не может заставить это работать. Попробуйте установить Autoshrink с минимальной шкалой шрифтов на этой UILabel.
Скриншот UILabel Настройки автоусадки
Ответ 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])
}
}