При помещении многострочной метки (с переводом строки в Word Wrap) в представление стека метка сразу теряет перевод строки и отображает текст метки в одну строку.
Почему это происходит и как сохранить многострочную метку в виде стека?
При помещении многострочной метки (с переводом строки в Word Wrap) в представление стека метка сразу теряет перевод строки и отображает текст метки в одну строку.
Почему это происходит и как сохранить многострочную метку в виде стека?
Ответы:
Правильный ответ здесь:
https://stackoverflow.com/a/43110590/566360
UILabel
внутри UIView
(Редактор -> Вставить -> Просмотреть)UILabel
к UIView
(например, задний пространство, верхнее пространство, и ведущее пространство для SuperView ограничений)UIStackView
Будет растянуть , UIView
чтобы соответствовать должным образом, и UIView
будет сдерживать UILabel
на несколько строк.
UIView
махинаций необходимо.
Для горизонтального стека, который имеет UILabel
один из своих видов, в Interface Builder сначала установите label.numberOfLines = 0
. Это должно позволить метке иметь более 1 строки. Это изначально не работало для меня, когда было представление стека stackView.alignment = .fill
. Чтобы заставить его работать просто установите stackView.alignment = .center
. Метка теперь может расширяться до нескольких строк в UIStackView
.
Документация Apple гласит
Для всех выравниваний, кроме выравнивания заливки, представление стека использует внутреннее свойство Content Size каждого упорядоченного представления при расчете его размера перпендикулярно оси стека.
Обратите внимание на слово, кроме здесь. При .fill
использовании горизонталь UIStackView
НЕ меняет размеры по вертикали, используя упорядоченные размеры подпредставлений.
.alignment
из UIStackView , что вы должны установить к чему - либо , но .fill
не UILabel, что немного смущает в данном примере label.alignment = .center
. Я думаю, что это должно бытьstackView.alignment = .center
multiLine
пока вы не зададите ему фиксированную ширину. Когда мы фиксируем его ширину, он достигает многострочного, когда эта ширина достигается, как показано:Если мы не дадим фиксированную ширину стековому виду, все станет неоднозначным. Как долго будет расти представление стека с меткой (если значение метки является динамическим)?
Надеюсь, что это может решить вашу проблему.
preferredMaxLayoutWidth
в viewDidLayoutSubviews
для метки в UIViewController
или , layoutSubviews
если подкласс UIView
.
Установка предпочитаемого MaxLayoutWidth для UILabel работала для меня
self.myLabel.preferredMaxLayoutWidth = self.bounds.size.width;
.center
и мне действительно не нужен был мой ярлык в UIView.
Просто установите количество строк равным 0 в инспекторе атрибутов для метки. Это будет работать для вас.
Попробовав все вышеизложенное, я обнаружил, что для UIStackView не нужно менять свойства. Я просто изменяю свойства UILabels следующим образом (метки уже добавлены в представление вертикального стека):
Swift 4 пример:
[titleLabel, subtitleLabel].forEach(){
$0.numberOfLines = 0
$0.lineBreakMode = .byWordWrapping
$0.setContentCompressionResistancePriority(UILayoutPriority.required, for: .vertical)
}
iOS 9+
Позвоните [textLabel sizeToFit]
после установки текста UILabel.
sizeToFit изменяет расположение многострочной метки, используя предпочитаемый параметр MaxWidth. Метка изменит размер stackView, который изменит размер ячейки. Никаких дополнительных ограничений, кроме прикрепления стека к представлению контента, не требуется.
UIStackView
состоящей из многострочных UILabel
s с автоматической высотой.Обтекание меток зависит от ширины стека и высоты стека зависит от обернутой высоты метки. (При таком подходе вам не нужно вставлять метки в 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])
}
}
Добавить UIStackView
свойства,
stackView.alignment = .fill
stackView.distribution = .fillProportionally
stackView.spacing = 8.0
stackView.axis = .horizontal
Вместо добавления метки внутри, UIView
которая не требуется. Если вы используете внутри, UITableViewCell
пожалуйста, перезагрузите данные по ротации.
Ниже приведена реализация многострочной метки на игровой площадке с разрывом строки внутри 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
Системный макет должен определять происхождение, ширину и высоту, чтобы нарисовать его подпредставления, в этом случае все ваши подпредставления имеют одинаковый приоритет, в этом случае возникают конфликты, система компоновки не знает зависимостей между представлениями, из которых одно рисует первым, вторым и т. Д.
Задать сжатие подпредставлений стека поможет решить проблему с несколькими строками, в зависимости от того, является ли ваше представление стека горизонтальным или вертикальным, и какое из них вы хотите сделать несколькими строками. stackOtherSubviews .setContentCompressionResistancePriority(.defaultHight, for: .horizontal)
lblTitle.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
В моем случае я следовал предыдущим предложениям, но мой текст все еще урезался до одной строки, хотя только в альбомной ориентации. Оказывается, я нашел невидимый \0
нулевой символ в тексте метки, который был виновником. Должно быть, он был введен рядом с символом «тире», который я вставил. Чтобы увидеть, происходит ли это и в вашем случае, используйте View Debugger, чтобы выбрать вашу метку и проверить ее текст.
Xcode 9.2:
Просто установите количество строк в 0. Раскадровка будет выглядеть странно после установки этого. Не волнуйтесь, запустите проект. Во время работы все изменится в соответствии с настройками раскадровки. Я думаю, что это своего рода ошибка в раскадровке.
Советы: Установите «номер лайнера на 0» в последнем. сбросьте его, если вы хотите отредактировать другой вид и установите 0 после редактирования.
Что сработало для меня!
stackview: выравнивание: заполнение, распределение: заполнение, ограничение пропорциональной ширине для суперпредставления ex. 0,8,
метка: центр и линии = 0
Для тех, кто до сих пор не может заставить это работать. Попробуйте установить Autoshrink с минимальной шкалой шрифтов на этой UILabel.
Это почти как @ Andy's Answer, но вы можете добавить свою UILabel
дополнительную UIStackview
, вертикальную для меня.
Для меня проблема была в том, что высота стека была слишком короткой. Метка и представление стека были правильно настроены, чтобы метка могла иметь несколько строк, но метка стала первой жертвой сжатия содержимого, которое представление стека использовало для получения достаточно маленькой высоты.