При установке многострочной метки (с привязкой линии к Word Wrap) в представление стека, метка немедленно теряет строку и отображает текст метки в одной строке.
Почему это происходит и как сохранить многострочную метку в представлении стека?
При установке многострочной метки (с привязкой линии к Word Wrap) в представление стека, метка немедленно теряет строку и отображает текст метки в одной строке.
Почему это происходит и как сохранить многострочную метку в представлении стека?
Правильный ответ здесь: fooobar.com/questions/148411/...
UILabel
в UIView
(Редактор → Вставить → Просмотреть) UILabel
к UIView
(например, конечный пробел, верхний пробел и UIView
пробел для ограничений суперпредставления) UIStackView
будет растягивать UIView
для правильного размещения, а UIView
будет ограничивать UILabel
несколькими строками.
Для горизонтального представления стека, в котором UILabel
является одним из представлений, в Интерфейсном label.numberOfLines = 0
сначала установите label.numberOfLines = 0
. Это должно позволить метке иметь более 1 строки. Это первоначально не работало для меня, когда у представления стека было stackView.alignment =.fill
. Чтобы это работало, просто установите stackView.alignment =.center
. Теперь метка может расширяться до нескольких строк в UIStackView
.
Документация Apple гласит
Для всех выравниваний, кроме выравнивания заливки, представление стека использует свойство внутреннего размера каждого упорядоченного представления при расчете его размера перпендикулярно оси стеков
Обратите внимание на слово, кроме здесь. Когда .fill
используются горизонтальная UIStackView
не изменяет размер себя вертикально с помощью расположенных размеров подвидов.
multiLine
если вы не multiLine
ему фиксированную ширину. Когда мы фиксируем его ширину, он переходит в многострочное, когда эта ширина достигается, как показано:Если мы не дадим фиксированную ширину стековому виду, все становится неоднозначным. Как долго будет расти представление стека с меткой (если значение метки является динамическим)?
Надеюсь, что это может решить вашу проблему.
Просто установите количество строк равным 0 в инспекторе атрибутов для метки. Это будет работать для вас.
Установка предпочитаемого MaxLayoutWidth для UILabel работала для меня
self.myLabel.preferredMaxLayoutWidth = self.bounds.size.width;
iOS 9+
Вызовите [textLabel sizeToFit]
после установки текста UILabel.
sizeToFit перекомпоновает многострочную метку, используя предпочитаемый параметр MaxWidth. Метка изменит размер stackView, который изменит размер ячейки. Никаких дополнительных ограничений, кроме прикрепления стека к представлению контента, не требуется.
Ниже приведена реализация многострочной метки на игровой площадке с разрывом строки внутри 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
Добавить свойства UIStackView
,
stackView.alignment = .fill
stackView.distribution = .fillProportionally
stackView.spacing = 8.0
stackView.axis = .horizontal
Вместо добавления метки внутри UIView
которая не требуется. Если вы используете внутри UITableViewCell
пожалуйста, перезагрузите данные при ротации.
Волшебным трюком для меня было установить widthAnchor
к UIStackView
.
Установка leadingAnchor
и trailingAnchor
не будет работать, но установка centerXAnchor
и widthAnchor
правильно сделал дисплей UILabel.
Системный макет должен определять происхождение, ширину и высоту, чтобы нарисовать его подпредставления, в этом случае все ваши подпредставления имеют одинаковый приоритет, в этом случае возникают конфликты, система компоновки не знает зависимостей между представлениями, из которых одно рисует первым, вторым и т.д.
Задать сжатие подпредставлений стека поможет решить проблему с несколькими строками, в зависимости от того, является ли ваш вид стека горизонтальным или вертикальным и какой из них вы хотите превратить в несколько строк. stackOtherSubviews.setContentCompressionResistancePriority(.defaultHight, for:.horizontal)
lblTitle.setContentCompressionResistancePriority(.defaultLow, for:.horizontal)
Попробовав все вышеизложенное, я обнаружил, что для UIStackView не нужно менять свойства. Я просто изменяю свойства UILabels следующим образом (метки уже добавлены в представление вертикального стека):
Swift 4 пример:
[titleLabel, subtitleLabel].forEach(){
$0.numberOfLines = 0
$0.lineBreakMode = .byWordWrapping
$0.setContentCompressionResistancePriority(UILayoutPriority.required, for: .vertical)
}
В моем случае я следил за предыдущими предложениями, но мой текст все еще усекался до одной строки, но только в ландшафте. Оказывается, я нашел невидимый символ \0
null в тексте метки, который был виновником. Он должен быть введен вместе с символом em, который я вставил. Чтобы убедиться, что это также происходит в вашем случае, используйте View Debugger, чтобы выбрать метку и проверить ее текст.
Xcode 9.2:
Просто установите количество строк в 0. Раскадровка будет выглядеть странно после установки этого. Не волнуйтесь, запустите проект. Во время работы все изменится в соответствии с настройками раскадровки. Я думаю, что это своего рода ошибка в раскадровке.
Советы: Установите "номер лайнера в 0" в последнем. сбросьте его, если вы хотите отредактировать другой вид и установите 0 после редактирования.
Что сработало для меня!
stackview: выравнивание: заполнение, распределение: заполнение, ограничение пропорциональной ширине для суперпредставления ex. 0,8,
метка: центр и линии = 0
Для тех, кто до сих пор не может заставить это работать. Попробуйте установить Autoshrink с минимальной шкалой шрифтов на этой UILabel.
UIStackView
состоящего из многострочного UILabel
с автоматической высотой. Обтекание меток зависит от ширины стека и высоты стека зависит от высоты обтекания меток. (При таком подходе вам не нужно вставлять метки в UIView
.) (Swift 5, iOS 12.2)
// 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])
}
}