При помещении многострочной метки (с переводом строки в Word Wrap) в представление стека метка сразу теряет перевод строки и отображает текст метки в одну строку.
Почему это происходит и как сохранить многострочную метку в виде стека?
Используйте ограничения , чтобы соответствовать UILabelк UIView(например, задний пространство, верхнее пространство, и ведущее пространство для SuperView ограничений)
UIStackViewБудет растянуть , UIViewчтобы соответствовать должным образом, и UIViewбудет сдерживать UILabelна несколько строк.
Для горизонтального стека, который имеет UILabelодин из своих видов, в Interface Builder сначала установите label.numberOfLines = 0. Это должно позволить метке иметь более 1 строки. Это изначально не работало для меня, когда было представление стека stackView.alignment = .fill. Чтобы заставить его работать просто установите stackView.alignment = .center. Метка теперь может расширяться до нескольких строк в UIStackView.
Для всех выравниваний, кроме выравнивания заливки, представление стека использует внутреннее свойство Content Size каждого упорядоченного представления при расчете его размера перпендикулярно оси стека.
Обратите внимание на слово, кроме здесь. При .fillиспользовании горизонталь UIStackViewНЕ меняет размеры по вертикали, используя упорядоченные размеры подпредставлений.
Это правильное решение без хаков. Чтение документов всегда окупается!
Ислам Q.
3
Это должно быть принятым решением. С обходным решением UIView текст UILabel всплыл над другим подпредставлением в моем случае.
14
Это не работает на самом деле ... У меня есть 3 метки в моем стеке просмотра. Я установил линии на ноль и выровнял по центру ... Я все еще вижу, как метки обрезаются.
MatterGoal
11
Это .alignmentиз UIStackView , что вы должны установить к чему - либо , но .fillне UILabel, что немного смущает в данном примере label.alignment = .center. Я думаю, что это должно бытьstackView.alignment = .center
ae14
2
Но как я могу заставить работать несколько строк UILableView в вертикальном StackView?
Дахун
42
Сначала установите количество строк в метке 0
Представление стека по-прежнему не будет расти, multiLineпока вы не зададите ему фиксированную ширину. Когда мы фиксируем его ширину, он достигает многострочного, когда эта ширина достигается, как показано:
Если мы не дадим фиксированную ширину стековому виду, все станет неоднозначным. Как долго будет расти представление стека с меткой (если значение метки является динамическим)?
Что, если ширина стекового представления не фиксирована, а пропорциональна ширине устройства (т.е. суперпредставления).
OutOnAWekend
Да, у нас тоже может быть пропорциональная ширина. Дело в том, что метка должна ломаться после некоторой ширины, какой бы она ни была, но должна быть определена.
Ирфан
@AnandKumar вы можете указать preferredMaxLayoutWidthв viewDidLayoutSubviewsдля метки в UIViewControllerили , layoutSubviewsесли подкласс UIView.
Шынгыс Касымов
4
Это должен был быть принятый ответ, весь смысл стека в том, чтобы не нужно было добавлять ограничения между стэком и его элементами ...
Дорогой,
4
Присвоение фиксированной стоимости побеждает цель автопоставки
Ислам Q.
17
Установка предпочитаемого MaxLayoutWidth для UILabel работала для меня
Это правильный ответ в моей книге. Если вам когда-либо нужно связываться с UILabel и вам нужно обрабатывать несколько строк, вам действительно нужно присвоить ему предпочтительный MaxLayoutWidth. Это может работать без него, но без него все может стать довольно быстро.
Mof
2
Все перепробовали все ответы, и все они были не правы, кроме вашего. Спасибо!
Леван
Это прекрасно решило мою проблему и кажется намного менее хакерским, спасибо.
Итан Чжао
Спасибо за Ваш ответ! В моем случае выравнивание моего stackView уже было установлено, .centerи мне действительно не нужен был мой ярлык в UIView.
Фариза Жумат
12
Просто установите количество строк равным 0 в инспекторе атрибутов для метки. Это будет работать для вас.
Для вертикального стека просмотра вам необходимо установить для параметра Распределение значение «Заполнить», чтобы это работало.
SnoopyProtocol
2
Установка Распределения на «Fill» является ключом к исправлению.
Дилан Мур
Я обнаружил, что для вертикального UIStackView мне пришлось установить верхние и нижние ограничения для дочернего UILabel, чтобы развернуть и показать весь текст.
bruce1337
8
Попробовав все вышеизложенное, я обнаружил, что для UIStackView не нужно менять свойства. Я просто изменяю свойства UILabels следующим образом (метки уже добавлены в представление вертикального стека):
Позвоните [textLabel sizeToFit]после установки текста UILabel.
sizeToFit изменяет расположение многострочной метки, используя предпочитаемый параметр MaxWidth. Метка изменит размер stackView, который изменит размер ячейки. Никаких дополнительных ограничений, кроме прикрепления стека к представлению контента, не требуется.
Вот полный пример вертикали, UIStackViewсостоящей из многострочных UILabels с автоматической высотой.
Обтекание меток зависит от ширины стека и высоты стека зависит от обернутой высоты метки. (При таком подходе вам не нужно вставлять метки в UIView.) (Swift 5, iOS 12.2)
// A vertical stackview with multiline labels and automatic height.classThreeLabelStackView:UIStackView{let label1 =UILabel()let label2 =UILabel()let label3 =UILabel()
init(){super.init(frame:.zero)self.translatesAutoresizingMaskIntoConstraints =falseself.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который использует это.
classViewController: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. Он не требует встраивания UILabelчего-либо внутри и был протестирован с Xcode 9.2 и Swift 4. Надеюсь, это полезно.
importUIKitimportPlaygroundSupportlet 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 =truePlaygroundPage.current.liveView = containerView
Системный макет должен определять происхождение, ширину и высоту, чтобы нарисовать его подпредставления, в этом случае все ваши подпредставления имеют одинаковый приоритет, в этом случае возникают конфликты, система компоновки не знает зависимостей между представлениями, из которых одно рисует первым, вторым и т. Д.
Задать сжатие подпредставлений стека поможет решить проблему с несколькими строками, в зависимости от того, является ли ваше представление стека горизонтальным или вертикальным, и какое из них вы хотите сделать несколькими строками. stackOtherSubviews .setContentCompressionResistancePriority(.defaultHight, for: .horizontal)lblTitle.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
В моем случае я следовал предыдущим предложениям, но мой текст все еще урезался до одной строки, хотя только в альбомной ориентации. Оказывается, я нашел невидимый \0нулевой символ в тексте метки, который был виновником. Должно быть, он был введен рядом с символом «тире», который я вставил. Чтобы увидеть, происходит ли это и в вашем случае, используйте View Debugger, чтобы выбрать вашу метку и проверить ее текст.
Просто установите количество строк в 0. Раскадровка будет выглядеть странно после установки этого. Не волнуйтесь, запустите проект. Во время работы все изменится в соответствии с настройками раскадровки. Я думаю, что это своего рода ошибка в раскадровке.
Советы: Установите «номер лайнера на 0» в последнем. сбросьте его, если вы хотите отредактировать другой вид и установите 0 после редактирования.
Для меня проблема была в том, что высота стека была слишком короткой. Метка и представление стека были правильно настроены, чтобы метка могла иметь несколько строк, но метка стала первой жертвой сжатия содержимого, которое представление стека использовало для получения достаточно маленькой высоты.
Ответы:
Правильный ответ здесь:
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 гласит
Обратите внимание на слово, кроме здесь. При
.fill
использовании горизонтальUIStackView
НЕ меняет размеры по вертикали, используя упорядоченные размеры подпредставлений.источник
.alignment
из UIStackView , что вы должны установить к чему - либо , но.fill
не UILabel, что немного смущает в данном примереlabel.alignment = .center
. Я думаю, что это должно бытьstackView.alignment = .center
multiLine
пока вы не зададите ему фиксированную ширину. Когда мы фиксируем его ширину, он достигает многострочного, когда эта ширина достигается, как показано:Если мы не дадим фиксированную ширину стековому виду, все станет неоднозначным. Как долго будет расти представление стека с меткой (если значение метки является динамическим)?
Надеюсь, что это может решить вашу проблему.
источник
preferredMaxLayoutWidth
вviewDidLayoutSubviews
для метки вUIViewController
или ,layoutSubviews
если подклассUIView
.Установка предпочитаемого MaxLayoutWidth для UILabel работала для меня
источник
.center
и мне действительно не нужен был мой ярлык в UIView.Просто установите количество строк равным 0 в инспекторе атрибутов для метки. Это будет работать для вас.
источник
Попробовав все вышеизложенное, я обнаружил, что для UIStackView не нужно менять свойства. Я просто изменяю свойства UILabels следующим образом (метки уже добавлены в представление вертикального стека):
Swift 4 пример:
источник
Магический трюк для меня было положить а
widthAnchor
вUIStackView
.Установка
leadingAnchor
иtrailingAnchor
не будет работать, но установкаcenterXAnchor
иwidthAnchor
заставила UILabel отображаться правильно.источник
iOS 9+
Позвоните
[textLabel sizeToFit]
после установки текста UILabel.sizeToFit изменяет расположение многострочной метки, используя предпочитаемый параметр MaxWidth. Метка изменит размер stackView, который изменит размер ячейки. Никаких дополнительных ограничений, кроме прикрепления стека к представлению контента, не требуется.
источник
Вот полный пример вертикали,
UIStackView
состоящей из многострочныхUILabel
s с автоматической высотой.Обтекание меток зависит от ширины стека и высоты стека зависит от обернутой высоты метки. (При таком подходе вам не нужно вставлять метки в
UIView
.) (Swift 5, iOS 12.2)Вот пример,
ViewController
который использует это.источник
Добавить
UIStackView
свойства,Вместо добавления метки внутри,
UIView
которая не требуется. Если вы используете внутри,UITableViewCell
пожалуйста, перезагрузите данные по ротации.источник
Ниже приведена реализация многострочной метки на игровой площадке с разрывом строки внутри
UIStackView
. Он не требует встраиванияUILabel
чего-либо внутри и был протестирован с Xcode 9.2 и Swift 4. Надеюсь, это полезно.источник
Системный макет должен определять происхождение, ширину и высоту, чтобы нарисовать его подпредставления, в этом случае все ваши подпредставления имеют одинаковый приоритет, в этом случае возникают конфликты, система компоновки не знает зависимостей между представлениями, из которых одно рисует первым, вторым и т. Д.
Задать сжатие подпредставлений стека поможет решить проблему с несколькими строками, в зависимости от того, является ли ваше представление стека горизонтальным или вертикальным, и какое из них вы хотите сделать несколькими строками.
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.
Скриншот UILabel Настройки автоусадки
источник
Это почти как @ Andy's Answer, но вы можете добавить свою
UILabel
дополнительнуюUIStackview
, вертикальную для меня.источник
Для меня проблема была в том, что высота стека была слишком короткой. Метка и представление стека были правильно настроены, чтобы метка могла иметь несколько строк, но метка стала первой жертвой сжатия содержимого, которое представление стека использовало для получения достаточно маленькой высоты.
источник