-
-
Save X901/44a07f65ec9e1b7c83b71b31b650f1f8 to your computer and use it in GitHub Desktop.
Allow .natural on Text and TextEditor in SwiftUI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //// | |
| //NaturalText.swift | |
| //NaturalText | |
| // | |
| //Created by Basel Baragabah on 18/02/2022. | |
| //Copyright © 2022 Basel Baragabah. All rights reserved. | |
| // | |
| 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 | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //// | |
| //NaturalTextEditor.swift | |
| //NaturalText | |
| // | |
| //Created by Basel Baragabah on 18/02/2022. | |
| //Copyright © 2022 Basel Baragabah. All rights reserved. | |
| // | |
| 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 !!")) | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The code above is detected the app layout direction and text content to decide if the text should be RTL or LTR
That means it won't change depending on layout direction only as you can see on the image below
Text
instead of using
Text, useNaturalTextNaturalText(text: "Try one line of text")TextEditor
instead of
TextEditor, useNaturalTextEditorNotice here the app uses RTL language (Arabic) but the text show depend on text content, not app layout direction (default)
on This Video, you will see how the TextEditor will change direction depending on text content direction
Feb-18-2022.18-18-32.mp4