Apple not suppourt .natrual
in SwiftUI, they add suppourt for AttributedString in SwiftUI but paragraphstyle
not suppourted
There is a trick that is working and depend only in pure SwiftUI
I have created it here
for Text use NaturalText
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
}
}
for TextEditor use NaturalTextEditor
import SwiftUI
import NaturalLanguage
struct NaturalTextEditor: View {
@Environment(\.layoutDirection) private var layoutDirection
@Binding var text: String
var body: some View {
ZStack {
TextEditor(text: $text)
.frame(alignment: naturalAlignment)
.multilineTextAlignment(naturalTextAlignment)
.onAppear {
UITextView.appearance().backgroundColor = .clear
}
}
}
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 NaturalTextEditor_Previews: PreviewProvider {
static var previews: some View {
NaturalTextEditor(text: .constant("Test !!"))
}
}
how I solved this issue ?
1- I checked the app language
2- I checked the text content itself depend on first letters using Apple AI NaturalLanguage
3- depend on app language if it's English that mean leading is left and trailing is right, but if app language is Arabic that mean leading is right and trailing is left
so now I know if app lagnuage is English but text is Arabic it will be RTL
if the text is english it will be LTR
same thing if the app lagnuage is Arabic, if the text is English it will be LTR but if the text is arabic it will be RTL
I'm using this code in all my production apps, working 100% fine
the result will be as you want it