Perataan teks SwiftUI

90

Di antara banyak properti Texttampilan, saya tidak dapat menemukan yang terkait dengan perataan teks. Saya telah melihat dalam demo yang menangani RTL secara otomatis, dan ketika menempatkan barang menggunakan View body, itu selalu memusatkan secara otomatis.

Apakah ada beberapa konsep yang saya lewatkan tentang sistem tata letak SwiftUIdan jika tidak, bagaimana cara mengatur properti perataan teks ke Text?

inokey
sumber

Jawaban:

144

Anda dapat melakukannya melalui pengubah .multilineTextAlignment(.center).

Dokumentasi Apple

vrwim
sumber
8
Apakah ada sesuatu untuk membenarkan teks?
theMouk
85

Dari SwiftUI beta 3 ke depan, Anda dapat memusatkan tampilan teks dengan pengubah bingkai:

Text("Centered")
    .frame(maxWidth: .infinity, alignment: .center)
Jim Marquardt
sumber
39

Mencoba memahami ini sendiri karena jawaban lain di sini menyebutkan Text.multilineTextAlignment(_:)/ VStack(alignment:)/ frame(width:alignment:)tetapi setiap solusi memecahkan masalah tertentu. Akhirnya itu tergantung pada persyaratan UI dan kombinasi keduanya.


VStack(alignment:)

Di alignmentsini untuk pandangan batin masing-masing satu sama lain.
Jadi menentukan .leadingakan mengaitkan semua tampilan dalam agar memimpin selaras satu sama lain.

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

gambar


.frame

Dalam frame(width:alignment:)atau frame(maxWidth:alignment:), alignmentadalah untuk konten dalam lebar yang ditentukan.

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

Tampilan dalam memimpin masing-masing selaras satu sama lain tetapi tampilan itu sendiri mengikuti selaras masing-masing VStack.

gambar


.multilineTextAlignment

Ini menentukan perataan teks di dalamnya dan dapat dilihat paling baik ketika ada beberapa baris jika tidak tanpa ditentukan frame(width:alignment), lebar secara otomatis disesuaikan dan terpengaruh oleh default alignment.

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

gambar


Tes dengan kombinasi:

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

gambar

staticVoidMan
sumber
1
Itu jawaban yang sangat meyakinkan. Terima kasih. Saya akan mempertimbangkan untuk membuat ini menjadi jawaban yang diterima juga.
inokey
1
@inokey senang berbagi pengamatan saya :) Saya kemudian menemukan artikel menarik yang membahas lebih dalam tentang keselarasan tampilan secara umum: Panduan Penyelarasan di SwiftUI
staticVoidMan
hal-hal yang mengagumkan. SwiftUI benar-benar berkembang sejak saya pertama kali memposting pertanyaan itu.
inokey
17

Saya sebenarnya mengalami masalah di mana saya harus meratakan teks pada satu baris. Apa yang saya temukan untuk bekerja adalah ini:

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

Jika Anda menggabungkan ini dengan parameter lebar bingkai Anda bisa mendapatkan beberapa format blok teks yang bagus untuk label dan semacamnya.

Lekyaira
sumber
14

Saya kira SwiftUIingin kita menggunakan pembungkus seperti tumpukan untuk hal-hal seperti itu.

Jadi, alih-alih menulis sesuatu seperti Text("Hello World").aligned(.leading), berikut ini disarankan:

VStack(alignment: .leading) {
    Text("Hello World")
}
fredpi
sumber
1
Jadi saya tidak bisa begitu saja menjatuhkan label yang tidak tergantung pada tumpukan?
inokey
@inokey Saya tidak menemukan pengubah untuk ini setidaknya.
fredpi
Saya juga tidak. Sepertinya saya merindukan semacam konsep dasar dari SUI. Saya bahkan tidak bisa menjatuhkan seperti hanya "tampilan" di antara dua hal, dan memberinya warna, seperti mereka tidak memiliki objek a-la-uiview biasa di sana.
inokey
Pengubah bingkai memiliki parameter penyelarasan
EmilioPelaez
Tampaknya konyol untuk dilakukan (meskipun berhasil). Di mana Anda mendengar bahwa ini didorong?
MobileMon
6

Jika Anda ingin menjaga lebar konstan untuk Teks, ".multilineTextAlignment (.leading)" tidak akan berpengaruh sampai hanya ada satu baris teks.

Ini adalah solusi yang berhasil untuk saya:

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


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

Pemakaian:

Text("Hello").leftAligned().frame(width: 300)
Kamil Zaborowski
sumber
5

Kita perlu menyelaraskan Teks dan bukan Tumpukan itu masuk Jadi memanggil multilineTextAlignment(.center)dan mengatur batas baris saya bisa melihat teks diratakan ke tengah. Saya tidak tahu mengapa saya harus menetapkan batas baris, saya pikir itu akan meluas jika Anda memiliki teks yang besar.

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

Anda dapat menyetel perataan untuk Vertical stackView sebagai yang terdepan. Seperti dibawah ini

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

masukkan deskripsi gambar di sini

Kathiresan Murugan
sumber
0

Saya ingin menggunakan tampilan Spacer () untuk meratakan blok teks. Contoh ini menunjukkan teks di sisi belakang:

                HStack{
                    Spacer()
                    Text("Wishlist")
                }
Oleksii Radetskyi
sumber