UIStackView'da çok satırlı etiket


154

Çok satırlı etiketi (satır aralığı Word Wrap olarak ayarlanmış olarak) yığın görünümüne yerleştirirken, etiket hemen satır aralığını kaybeder ve bunun yerine etiket metnini bir satırda görüntüler.

Bu neden oluyor ve çok katlı etiketi yığın görünümünde nasıl koruyor?


1
Satır sayısını 0 olarak ayarladınız mı?
dasdom

Bir cevap buldunuz mu?
Brenden

Yanıtlar:


204

Doğru cevap burada:
https://stackoverflow.com/a/43110590/566360


  1. UILabelİçine gömme UIView(Editör -> Göm - - Görünüm)
  2. Kullanım kısıtlamaları uyacak UILabeliçin UIView(örneğin, Superview kısıtlamalarına alanı, üst alan ve gelen alan arka)

O UIStackView, UIViewuygun şekilde oturacak ve birden fazla çizgiyle UIViewsınırlanacaktır UILabel.


36
Çok aptalca ama işe yarıyor! Teşekkürler dostum ! Belki bir gün Apple, SDK'larında yarı kırık olmayan bir şey yayınlayacak ...
Guillaume L.

1
Ah adamım! Sen bir kurtarıcısın! Saatlerdir oradaydım :) Nitelikler Müfettişinde çizgileri 0 olarak ayarlamayı da unutmayın, sadece bu eksikti.
absin

8
bu geçici çözümdür, doğru çözüm burada stackoverflow.com/a/43110590/566360
vietstone

2
Sadece yatay hizalamayı merkeze değiştirmek benim için yeterliydi. Hiçbir UIViewkurnazlık gerekli.
shim

1
@ Lucien tam olarak bu cevapta söylenen buydu. ancak doğru cevap burada: stackoverflow.com/a/43110590/566360
Andy

144

UILabelGörünümlerinden biri olan yatay yığın görünümü için öncelikle Arayüz Oluşturucu'da ayarlanır label.numberOfLines = 0. Bu, etiketin 1'den fazla satıra sahip olmasına izin vermelidir. Bu başlangıçta yığın görünümü vardı benim için işe yaramadı stackView.alignment = .fill. Çalıştırmak için basitçe ayarlayın stackView.alignment = .center. Etiket artık içindeki birden çok satıra genişletilebilir UIStackView.

Elma belgelerine diyor

Dolgu hizalaması dışındaki tüm hizalamalar için yığın görünümü, yığının eksenine dikey olarak boyutunu hesaplarken düzenlenmiş her görünümün gerçek İçerik Boyutu özelliğini kullanır

Kelimeyi Not haricinde burada. Zaman .fillyatay kullanılan UIStackViewkendisini yeniden boyutlandırma DEĞİLDİR dikey olarak düzenlenmiş subviews boyutları kullanılmıştır.


3
Bu, korsan olmadan uygun çözümdür. Belgeleri okumak her zaman işe yarar!
İslam S.

3
Bu kabul edilen çözüm olmalıdır. UIView geçici çözümü ile UILabel'ın metni benim durumumda başka bir alt görünüm üzerinde yüzüyordu.

14
Aslında çalışmıyor ... Yığın görünümümde 3 etiket var. Çizgileri sıfıra ve hizalamayı merkeze ayarladım ... Hala etiketlerin kesildiğini görüyorum.
MatterGoal

11
Bu var .alignmentbir şey için sette ama zorunda UIStackView ait .fill değil verilen örnekte kafa karıştırıcı biraz UILabel, label.alignment = .center. Bence bu olmalıstackView.alignment = .center
ae14

2
Ancak dikey StackView içinde birden fazla satır UILableView çalışmasını nasıl sağlayabilirim?
DàChún

42
  • İlk olarak etiketlerin satır sayısını 0 olarak ayarlayın
  • multiLineSabit bir genişlik sağlamadığınız sürece yığın görünümü yine de büyümez . Genişliğini sabitlediğimizde, bu genişliğe gösterildiği gibi ulaşıldığında çok çizgiye bölünür:

ekran kaydı

Yığın görünümüne sabit bir genişlik vermezsek, işler belirsizleşir. Yığın görünümü etiketle ne kadar uzar (etiket değeri dinamikse)?

Umarım bu sorununuzu çözebilir.


3
Yığın görünümünün genişliği sabit değilse, bunun yerine aygıt (yani denetimin) genişliği ile orantılıysa ne olur?
OutOnAWeekend

Evet, orantılı bir genişliğe de sahip olabiliriz. Mesele, etiketin ne olursa olsun bir genişlikten sonra kırılması gerekiyorsa, ancak tanımlanması gerekiyorsa.
Irfan

Belirtebileceğiniz @AnandKumar preferredMaxLayoutWidthiçinde viewDidLayoutSubviewsdaki etiket için UIViewControllerya da layoutSubviewssen alt sınıfı ise UIView.
Shyngys Kassymov

4
Bu kabul edilen cevap olmalıydı, yığın görüntüsünün bütün amacı yığın görünümü ve öğeleri arasına kısıtlamalar eklemek zorunda kalmamaktır ...
Honey

4
Sabit bir değer vermek, otomatik oynatma amacını bozar
İslam S.

17

UILabel'e tercih edilen MaksLayoutWidth ayarı benim için çalıştı

self.myLabel.preferredMaxLayoutWidth = self.bounds.size.width;

3
Kitabımdaki doğru cevap bu. UILabel's ile uğraştığınız ve birden fazla satırı işlemeniz gerektiğinde, ona bir tercih edilenMaxLayoutWidth vermeniz gerekir. Onsuz da işe yarayabilir, ama işler onsuz çok korkak olabilir.
Mof

2
Hepsi cevapları denedi ve sizinkiler dışında hepsi yanlıştı. Teşekkürler!
levan

Bu sorunumu mükemmel bir şekilde çözdü ve çok daha az hileli hissediyorum, teşekkürler.
Ethan Zhao

Cevabınız için teşekkürler! Benim durumumda stackView'in hizalaması zaten ayarlanmıştı .centerve gerçekten UIView içindeki etikete ihtiyacım yoktu.
Fariza Zhumat

12

Etiket için Nitelik denetçisinde satır sayısını 0 olarak ayarlamanız yeterlidir. Sizin için çalışacaktır.

resim açıklamasını buraya girin


12
Dikey stackView için, bunun çalışması için Dağıtım "Doldur" olarak ayarlanmış olması gerekir.
SnoopyProtocol

2
Dağıtımın "Dolgu" olarak ayarlanması, düzeltmenin anahtarıdır.
Dylan Moore

Dikey bir UIStackView için, tüm metni genişletmek ve göstermek için bir çocuk UILabel için üst ve alt kısıtlamaları ayarlamak zorunda buldum.
bruce1337

8

Yukarıdaki tüm öneri denedikten sonra hiçbir özellik değişikliği UIStackView için gerekli bulundu. Ben sadece UILabels özelliklerini aşağıdaki gibi değiştiririm (Etiketler zaten dikey yığın görünümüne eklenir):

Swift 4 örneği:

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

5

Benim için sihir bir belirlemekti widthAnchoriçin UIStackView.

Ayar leadingAnchorve trailingAnchorolmayacak işi ancak ayar centerXAnchorve widthAnchordoğru UILabel ekranı yaptı.


4

iOS 9 ve sonraki sürümleri

[textLabel sizeToFit]UILabel metnini ayarladıktan sonra arayın .

sizeToFit, çok satırlı etiketi tercih edilenMaxWidth öğesini kullanarak yeniden düzenler. Etiket, hücreyi yeniden boyutlandıracak olan stackView öğesini yeniden boyutlandırır. Yığın görünümünü içerik görünümüne sabitlemenin yanı sıra ek kısıtlamalar gerekmez.


4

Otomatik yüksekliğe sahip UIStackViewçok satırlı bir dikeyden oluşan tam bir örnek UILabel.

Etiketler, yığın görünümünün genişliğine ve yığın görünümünün yüksekliğine göre etiketin sarılı yüksekliğine bağlıdır. (Bu yaklaşımla etiketleri a'ya yerleştirmenize gerek yoktur UIView.) (Swift 5, iOS 12.2)

resim açıklamasını buraya girin

// 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") }
}

İşte ViewControlleronu kullanan bir örnek .

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])
    }
}

3

Özellik ekle UIStackView,

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

İçine UIViewgerekli olmayan etiket eklemek yerine, UITableViewCelllütfen içeride kullanıyorsanız , döndürme sırasında verileri yeniden yükleyin.


3

Aşağıda, içinde satır sonu bulunan çok satırlı etiketin bir Bahçesi uygulamasıdır UIStackView. UILabelİçine hiçbir şeyin gömülmesini gerektirmez ve Xcode 9.2 ve Swift 4 ile test edilmiştir. Umarım faydalıdır.

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

1

Sistem düzeni, alt görünümleri çizmek için başlangıç ​​noktasını, genişliğini ve yüksekliğini bulmalıdır, bu durumda tüm alt görünümleriniz aynı önceliğe sahiptir, bu nokta çakışma yaratır, düzen sistemi görünümler arasındaki bağımlılıkları bilmez, hangisi birinci, ikinci vb.

Yığın görünümlerini ayarlama sıkıştırma, yığın görünümünüzün yatay veya dikey olmasına ve hangisinin birden çok satır olmasını istediğinize bağlı olarak birden çok satırdaki sorunu çözecektir. stackOtherSubviews .setContentCompressionResistancePriority(.defaultHight, for: .horizontal) lblTitle.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)


0

Benim durumumda, önceki önerileri izledim, ancak metnim hala sadece manzarada olsa da tek bir satıra kesiliyordu. Görünen \0o ki, etikette suçlu olan görünmez bir boş karakter buldum . Eklediğim em tire simgesinin yanında kullanılmalıdır. Durumunuzda da bunun olup olmadığını görmek için, etiketinizi seçmek ve metnini incelemek üzere Hata Ayıklayıcıyı Görüntüle'yi kullanın.


0

Xcode 9.2:

Sadece satır sayısını 0 olarak ayarlayın. Storyboard bunu ayarladıktan sonra garip görünecek. Endişelenme, projeyi çalıştırın. Çalıştırırken her şey film şeridi kurulumunuza göre yeniden boyutlandırılacaktır. Sanırım film şeridindeki bir tür hata. resim açıklamasını buraya girin

İpuçları: Son olarak "astar sayısını 0" olarak ayarlayın. başka bir görünümü düzenlemek istediğinizde sıfırlayın ve düzenledikten sonra 0 olarak ayarlayın.

resim açıklamasını buraya girin


0

Benim için ne işe yaradı!

yığın görünümü: hizalama: dolgu, dağıtım: dolgu, denetleme için kısıtlama oransal genişliği ex. 0.8,

label: merkez ve çizgiler = 0




0

Benim için sorun, yığın görünümünün yüksekliğinin çok kısa olmasıydı. Etiket ve yığın görünümü, etiketin birden fazla satıra sahip olmasını sağlamak için düzgün bir şekilde ayarlandı, ancak etiket, yığın görünümünün yüksekliğini yeterince küçük hale getirmek için kullanılan içerik sıkıştırmasının ilk kurbanı oldu.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.