Выравнивание текста не будет работать с использованием AttributedString SwiftUI 3

Я пробовал использовать новый AttributedStringв SwiftUI 3

Я хочу изменить выравнивание, но это не сработает. Все остальное работает нормально, например, я попытался изменить цвет с помощью атрибутаString, он действительно работает! Но я ничего не могу сделать с paragraphStyle

      struct ContentView: View {
    var body: some View {
       
        ZStack {
            
            Color(uiColor: UIColor(red: 0.92, green: 0.92, blue: 0.92, alpha: 1.00)).ignoresSafeArea()
                        
            VStack {
                
                Text("""
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
""" ) { string in
                    let paragraphStyle = NSMutableParagraphStyle()
                    paragraphStyle.alignment = .right

                    string.paragraphStyle = paragraphStyle
                    
                    string.foregroundColor = .blue
                }
                    .padding()
                    .textSelection(.enabled)
                

                Spacer()
                
            }
            
        }
        
    }

}

extension Text {
init(_ string: String, configure: ((inout AttributedString) -> Void)) {
    var attributedString = AttributedString(string) /// create an `AttributedString`
    configure(&attributedString) /// configure using the closure
    self.init(attributedString) /// initialize a `Text`
}
}

3 ответа

The paragraphStyleатрибут определяется в UIKit сфере , но не на SwiftUI, поэтому вы не можете ожидать, что это сработает.

Альтернативой является использование модификатора .multilineTextAlignment(.trailing).

Как ты сказал . AttributedString не работает на SwiftUI. Фактически Textудовлетворять все, что может AttributedString.

параграфStyle полезен, если ваш текст состоит более чем из 1 строки. SwiftUI говорит. если у вас есть 1 линия использования

        Text("bla bla").frame(maxWidth: .infinity, alignment: .trailing)

Если у вас есть текст, который может быть больше 1 строки, используйте

       var body: some View {
   
    ZStack {
        
        Color(UIColor(red: 0.92, green: 0.92, blue: 0.92, alpha: 1.00)).ignoresSafeArea()
                    
        VStack{
          
            
            Text("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.")
           .frame(maxWidth: .infinity, alignment: .trailing)
           .multilineTextAlignment(textAlignment)
            

            Spacer()
            
        }
        
    }
    
}

let textAlignment: TextAlignment = {
    var textAlign = TextAlignment.trailing
    
    
    if UIApplication.shared.userInterfaceLayoutDirection == .leftToRight {
        textAlign = TextAlignment.trailing
       } else {
        textAlign = TextAlignment.leading
       }
    return textAlign
    
}()

Во- первых, спасибо, Омер Текбиик , вы дали мне представление о том, как я могу заставить это работать.

Проблема с зависит ли это от замыкания и опережения, а не от левого и правого , это означает, что если ваше устройство на языке LTR , ведущее будет слева , а замыкающее будет справа , но на RTL это будет противоположное ведущее будет справа , а замыкающее будет слева .

Итак, что я дд, сначала я проверяю сам текстовый язык, если это RTL или LTR , зависит от , затем я проверяю макет устройства, используя это как использовать но в коде SwiftUI.

Обратите внимание, эта строка будет работать, если текст содержит одну строку текста .

.frame(maxWidth: .infinity, выравнивание: naturalAlignment)

но эта строка будет работать с текстом, продолжающим несколько строк текста.

.multilineTextAlignment(naturalTextAlignment)

      import SwiftUI
import NaturalLanguage

struct NaturalText: View {
    @Environment(\.layoutDirection) private var layoutDirection
    var text : String
    var body: some View {
            Text(text)
           .frame(maxWidth: .infinity, alignment: naturalAlignment)
            .multilineTextAlignment(naturalTextAlignment)
    }
    private var naturalAlignment: Alignment {
        guard let dominantLanguage = dominantLanguage else {
            // If we can't identify the strings language, use the system language's natural alignment
            return .leading
        }
        switch NSParagraphStyle.defaultWritingDirection(forLanguage: dominantLanguage) {
        case .leftToRight:
            if layoutDirection == .rightToLeft {
                return .trailing
            } else {
                return .leading
            }
        case .rightToLeft:
            if layoutDirection == .leftToRight {
                return .trailing
            } else {
                return .leading
            }
        case .natural:
            return .leading
        @unknown default:
            return .leading
        }
    }

    private var naturalTextAlignment: TextAlignment {
        guard let dominantLanguage = dominantLanguage else {
            // If we can't identify the strings language, use the system language's natural alignment
            return .leading
        }
        switch NSParagraphStyle.defaultWritingDirection(forLanguage: dominantLanguage) {
        case .leftToRight:
            if layoutDirection == .rightToLeft {
                return .trailing
            } else {
                return .leading
            }
        case .rightToLeft:
            if layoutDirection == .leftToRight {
                return .trailing
            } else {
                return .leading
            }
        case .natural:
            return .leading
        @unknown default:
            return .leading
        }
    }
    private var dominantLanguage: String? {
        let firstChar = "\(text.first ?? " ")"
           return NLLanguageRecognizer.dominantLanguage(for: firstChar)?.rawValue
    }
}

Как это использовать

      struct ContentView: View {
    
    
    var body: some View {
        
        VStack {
        
            NaturalTextView(text: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.")
                .padding()

            
            NaturalTextView(text: "هذا النص هو مثال لنص يمكن أن يستبدل في نفس المساحة، لقد تم توليد هذا النص من مولد النص العربى، حيث يمكنك أن تولد مثل هذا النص أو العديد من النصوص الأخرى إضافة إلى زيادة عدد الحروف التى يولدها التطبيق.إذا كنت تحتاج إلى عدد أكبر من الفقرات يتيح لك مولد النص العربى زيادة عدد الفقرات كما تريد، النص لن يبدو مقسما ولا يحوي أخطاء لغوية، مولد النص العربى مفيد لمصممي المواقع على وجه الخصوص، حيث يحتاج العميل فى كثير من الأحيان أن يطلع على صورة حقيقية لتصميم الموقع.ومن هنا وجب على المصمم أن يضع نصوصا مؤقتة على التصميم ليظهر للعميل الشكل كاملاً،دور مولد النص العربى أن يوفر على المصمم عناء البحث عن نص بديل لا علاقة له بالموضوع الذى يتحدث عنه التصميم فيظهر بشكل لا يليق. هذا النص يمكن أن يتم تركيبه على أي تصميم دون مشكلة فلن يبدو وكأنه نص منسوخ، غير منظم، غير منسق، أو حتى غير مفهوم. لأنه مازال نصاً بديلاً ومؤقتاً.")
                .padding()

         
            Spacer()
        }
        
    }

}

Результат

вы можете использовать

      .environment(\.layoutDirection, .rightToLeft)

чтобы заставить макет быть RTL, вы заметите, что он не изменится, потому что он зависит от самого текстового языка

Другие вопросы по тегам