-1

我尝试AttributedString在 SwiftUI 3 中使用新功能

我想改变对齐方式,但它不起作用。其他任何事情都可以正常工作,例如我尝试使用属性字符串更改颜色它确实有效!。但我无能为力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`
}
}

在此处输入图像描述

4

3 回答 3

1

paragraphStyle属性是在UIKit 范围内定义的,但不在范围内SwiftUI,因此您不能指望它起作用。

另一种方法是使用修饰符.multilineTextAlignment(.trailing)

于 2022-02-14T12:43:48.863 回答
1

如你所说 。AttributedString 在 SwiftUI 上不起作用。实际上Text满足做 AttributedString 所能做的一切。

如果您的文本多于 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
    
}()
于 2022-02-14T14:34:15.280 回答
0

首先谢谢Omer Tekbiyik ,你给了我如何让它工作的想法。

问题TextAlignment在于它取决于尾随前导而 不是左右,这意味着如果您的设备在LTR语言上,前导将在 ,但在RTL,相反的前导将在

所以我要做什么,首先我检查文本语言本身是RTL还是LTRNaturalLanguage,然后我检查设备布局layoutDirection,就像使用SwiftUIUIApplication.shared.userInterfaceLayoutDirection 代码一样。

请注意,如果文本内容为一行文本,则此行将起作用

.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,您会注意到它不会改变,因为它取决于文本语言本身

于 2022-02-15T08:11:35.213 回答