SwiftUI metin hizalama


98

TextGörünümün birçok özelliği arasında, metin hizalamasıyla ilgili hiçbir şey bulamadım. Bir demoda otomatik olarak RTL'yi işlediğini ve View'leri kullanarak bir şeyler yerleştirirken bodyher zaman otomatik olarak ortaladığını gördüm .

Yerleşim sistemi hakkında kaçırdığım bir kavram var mı SwiftUIve yoksa metin hizalama özelliklerini nasıl ayarlayabilirim Text?

Yanıtlar:


157

Bunu değiştirici aracılığıyla yapabilirsiniz .multilineTextAlignment(.center).

Apple Belgeleri


10
Metni haklı çıkarmak için bir şey var mı?
theMouk

96

SwiftUI beta 3'ten itibaren, çerçeve değiştiriciyle bir metin görünümünü ortalayabilirsiniz:

Text("Centered")
    .frame(maxWidth: .infinity, alignment: .center)

50

Bunu kendim anlamaya çalışıyordum, burada bahsedilen diğer cevaplar Text.multilineTextAlignment(_:)/ VStack(alignment:)/ frame(width:alignment:)ancak her çözüm belirli bir sorunu çözüyor. Sonunda, UI gereksinimine ve bunların bir kombinasyonuna bağlıdır.


VStack(alignment:)

alignmentBurada birbirine karşılık gelen iç görüntülemeler içindir.
Bu nedenle, belirtmek .leading, tüm iç görüşleri birbiriyle hizalı olacak şekilde ilişkilendirir.

VStack(alignment: .leading, spacing: 6) {
  Text("Lorem ipsum dolor")
        .background(Color.gray.opacity(0.2))
  Text("sit amet")
        .background(Color.gray.opacity(0.2))
}
.background(Color.gray.opacity(0.1))

görüntü


.frame

Olarak frame(width:alignment:)ya da frame(maxWidth:alignment:), alignmentbelirli bir genişlik içinde içeriği içindir.

VStack(alignment: .leading, spacing: 6) {
  Text("Lorem ipsum dolor")
      .background(Color.gray.opacity(0.2))
  Text("sit amet")
      .background(Color.gray.opacity(0.2))
}
.frame(width: 380, alignment: .trailing)
.background(Color.gray.opacity(0.1))

İç görünümler, birbirlerine göre hizalı olarak önde gidiyor, ancak görünümlerin kendileri VStack,.

görüntü


.multilineTextAlignment

Bu, içindeki metnin hizalamasını belirtir ve en iyi şekilde birden çok satır olduğunda görülebilir, aksi takdirde tanımlanmadan frame(width:alignment)genişlik otomatik olarak ayarlanır ve varsayılan ' alignmentler tarafından etkilenir .

VStack(alignment: .trailing, spacing: 6) {
  Text("0. automatic frame\n+ view at parent's specified alignment\n+ multilineTA not set by default at leading")
    .background(Color.gray.opacity(0.2))
  Text("1. automatic frame\n+ view at parent's specified alignment\n+ multilineTA set to center")
  .multilineTextAlignment(.center)
  .background(Color.gray.opacity(0.2))
  Text("2. automatic frame\n+ view at parent's specified alignment\n+ multilineTA set to trailing")
  .multilineTextAlignment(.trailing)
  .background(Color.gray.opacity(0.2))
}
.frame(width: 380, alignment: .trailing)
.background(Color.gray.opacity(0.1))

görüntü


Kombinasyonlu testler:

VStack(alignment: .trailing, spacing: 6) {
  Text("1. automatic frame, at parent's alignment")
  .background(Color.gray.opacity(0.2))
  Text("2. given full width & leading alignment\n+ multilineTA at default leading")
  .frame(maxWidth: .infinity, alignment: .leading)
  .background(Color.gray.opacity(0.2))
  Text("3. given full width & center alignment\n+ multilineTA at default leading")
  .frame(maxWidth: .infinity, alignment: .center)
  .background(Color.gray.opacity(0.2))
  Text("4. given full width & center alignment\n+ multilineTA set to center")
  .multilineTextAlignment(.center)
  .frame(maxWidth: .infinity, alignment: .center)
  .background(Color.gray.opacity(0.2))
  Text("5. given full width & center alignment\n+ multilineTA set to trailing")
  .multilineTextAlignment(.trailing)
  .frame(maxWidth: .infinity, alignment: .center)
  .background(Color.gray.opacity(0.2))
  Text("6. given full width but no alignment\n+ multilineTA at default leading\n+ leading is based on content, looks odd sometimes as seen here")
  .frame(maxWidth: .infinity)
  .background(Color.gray.opacity(0.2))
}
.frame(width: 380)
.background(Color.gray.opacity(0.1))

görüntü


1
Bu çok ikna edici bir cevap. Teşekkür ederim. Bunu da kabul edilen bir cevap olarak değerlendireceğim.
inokey

1
@inokey, gözlemlerimi paylaşmaktan mutluluk duyar :) Daha sonra genel olarak görünüm hizalamaları ile daha derinlemesine giden ilginç bir makale buldum: SwiftUI'de Hizalama Kılavuzları
staticVoidMan

harika şeyler adamım. SwiftUI, bu soruyu ilk gönderdiğimden beri gerçekten gelişti.
inokey

17

Aslında metni tek bir satıra hizalamam gereken problemle karşılaştım. Çalışmak için bulduğum şey şu:

Text("some text")
    .frame(alignment: .leading)

Bunu çerçeve genişliği parametresiyle birleştirirseniz, etiketler ve benzeri için güzel bir metin bloğu biçimlendirmesi elde edebilirsiniz.


15

Sanırım SwiftUIbu tür şeyler için yığın gibi sarmalayıcılar kullanmamızı istiyor.

Bu nedenle, bunun gibi bir şey yazmak yerine Text("Hello World").aligned(.leading), aşağıdakiler teşvik edilir:

VStack(alignment: .leading) {
    Text("Hello World")
}

1
Yani yığından bağımsız bir etiketi öylece bırakamam?
inokey

@inokey En azından bunun için bir değiştirici bulamadım.
fredpi

Ben de yapmadım. Bana SUI'den bir tür temel konsepti özlemiş gibi geliyor. İki şey arasına sadece "manzara" gibi düşüp ona bir renk veremiyorum, sanki içinde düz bir a-la-uiview nesnesi yokmuş gibi.
inokey

Çerçeve değiştiricinin bir hizalama parametresi var
EmilioPelaez

Yapmak zorunda olmak aptalca görünüyor (işe yarasa da). Bunun teşvik edildiğini nereden duydunuz?
MobileMon

7

Metni içinde bulunduğu Yığını değil hizalamalıyız. Bu yüzden çağırarak multilineTextAlignment(.center)ve satır sınırlarını belirleyerek metinleri merkeze hizalı olarak görebiliyorum. Neden satır sınırlarını belirlemem gerektiğini bilmiyorum, büyük bir metniniz varsa genişleyeceğini düşündüm.

Text("blahblah")
        .font(.headline)
        .multilineTextAlignment(.center)
        .lineLimit(50)

6

Metin için sabit genişliği korumak isterseniz, ".multilineTextAlignment (.leading)", yalnızca bir metin satırı kalana kadar herhangi bir etkiye sahip olmayacaktır.

Bu benim için çalışan çözüm:

struct LeftAligned: ViewModifier {
    func body(content: Content) -> some View {
        HStack {
            content
            Spacer()
        }
    }
}


extension View {
    func leftAligned() -> some View {
        return self.modifier(LeftAligned())
    }
}

Kullanım:

Text("Hello").leftAligned().frame(width: 300)

4

Dikey stackView için hizalamayı satır aralığı olarak ayarlayabilirsiniz. Aşağıdaki gibi

 VStack(alignment: .leading) {
            Text("Turtle Rock")
                .font(.title)
            Text("Joshua Tree National Park")
                .font(.subheadline)
        }

görüntü açıklamasını buraya girin


2

Spacer()Metin bloğunu hizalamak için görünümü kullanmak istiyorum . Bu örnek, metni arka tarafta gösterir:

HStack{
    Spacer()
    Text("Wishlist")
}
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.