Introduces a backport for TextInputCapitalization
This commit is contained in:
parent
affe67f2cf
commit
5a294a710f
|
@ -2,22 +2,64 @@ import SwiftUI
|
|||
import SwiftBackports
|
||||
|
||||
#if os(iOS)
|
||||
extension Backport where Wrapped: View {
|
||||
@available(iOS, deprecated: 15)
|
||||
public extension Backport where Wrapped: View {
|
||||
/// Sets how often the shift key in the keyboard is automatically enabled.
|
||||
///
|
||||
/// Use `backport.textInputAutocapitalization(_:)` when you need to automatically
|
||||
/// capitalize words, sentences, or other text like proper nouns.
|
||||
///
|
||||
/// In example below, as the user enters text the shift key is
|
||||
/// automatically enabled before every word:
|
||||
///
|
||||
/// TextField("Last, First", text: $fullName)
|
||||
/// .backport.textInputAutocapitalization(.words)
|
||||
///
|
||||
/// The ``TextInputAutocapitalization`` struct defines the available
|
||||
/// autocapitalizing behavior. Providing `nil` to this view modifier does
|
||||
/// not change the autocapitalization behavior. The default is
|
||||
/// `Backport<Any>.TextInputAutocapitalization.sentences`.
|
||||
///
|
||||
/// - Parameter autocapitalization: One of the capitalizing behaviors
|
||||
/// defined in the `Backport<Any>.TextInputAutocapitalization` struct or nil.
|
||||
@ViewBuilder
|
||||
func textInputAutocapitalization(_ autocapitalization: Backport<Any>.TextInputAutocapitalization?) -> some View {
|
||||
wrapped.modifier(
|
||||
AutoCapitalizationModifier(
|
||||
capitalization: autocapitalization?.capitalization ?? .none
|
||||
)
|
||||
)
|
||||
Group {
|
||||
if #available(iOS 16, *) {
|
||||
var type: SwiftUI.TextInputAutocapitalization {
|
||||
switch autocapitalization {
|
||||
case .none:
|
||||
return .sentences
|
||||
case .some(let wrapped):
|
||||
switch wrapped {
|
||||
case .never: return .never
|
||||
case .words: return .words
|
||||
case .sentences: return .sentences
|
||||
case .characters: return .characters
|
||||
default: return .sentences
|
||||
}
|
||||
}
|
||||
}
|
||||
wrapped.textInputAutocapitalization(type)
|
||||
} else {
|
||||
wrapped.modifier(
|
||||
AutoCapitalizationModifier(
|
||||
capitalization: autocapitalization?.capitalization ?? .none
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
.environment(\.textInputAutocapitalization, autocapitalization)
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS, introduced: 13, deprecated: 15)
|
||||
@available(macOS, unavailable)
|
||||
@available(tvOS, unavailable)
|
||||
@available(watchOS, unavailable)
|
||||
@available(iOS, deprecated: 15)
|
||||
extension Backport<Any> {
|
||||
public struct TextInputAutocapitalization {
|
||||
/// The kind of autocapitalization behavior applied during text input.
|
||||
///
|
||||
/// Pass an instance of `Backport<Any>.TextInputAutocapitalization` to the
|
||||
/// ``View/backport.textInputAutocapitalization(_:)`` view modifier.
|
||||
public struct TextInputAutocapitalization: Equatable {
|
||||
internal let capitalization: UITextAutocapitalizationType
|
||||
|
||||
fileprivate init(capitalization: UITextAutocapitalizationType) {
|
||||
|
@ -38,27 +80,41 @@ extension Backport<Any> {
|
|||
/// Defines an autocapitalizing behavior that will capitalize every letter.
|
||||
public static var characters: TextInputAutocapitalization { .init(capitalization: .allCharacters) }
|
||||
|
||||
/// Creates a new `Backport<Any>.TextInputAutocapitalization` struct from a
|
||||
/// `UITextAutocapitalizationType` enum.
|
||||
public init?(_ type: UITextAutocapitalizationType) {
|
||||
self.capitalization = type
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS, deprecated: 15)
|
||||
private struct AutoCapitalizationModifier: ViewModifier {
|
||||
let capitalization: UITextAutocapitalizationType
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content
|
||||
.inspect { inspector in
|
||||
inspector.ancestor(ofType: UITextField.self)
|
||||
inspector.any(ofType: UITextField.self)
|
||||
} customize: { view in
|
||||
view.autocapitalizationType = capitalization
|
||||
}
|
||||
.inspect { inspector in
|
||||
inspector.ancestor(ofType: UITextView.self)
|
||||
inspector.any(ofType: UITextView.self)
|
||||
} customize: { view in
|
||||
view.autocapitalizationType = capitalization
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct AutoCapitalizationEnvironmentKey: EnvironmentKey {
|
||||
static var defaultValue: Backport<Any>.TextInputAutocapitalization? = .sentences
|
||||
}
|
||||
|
||||
internal extension EnvironmentValues {
|
||||
var textInputAutocapitalization: Backport<Any>.TextInputAutocapitalization? {
|
||||
get { self[AutoCapitalizationEnvironmentKey.self] }
|
||||
set { self[AutoCapitalizationEnvironmentKey.self] = newValue }
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -9,7 +9,7 @@ public extension Backport where Wrapped: View {
|
|||
/// Different views may have different triggers for the provided action. A TextField, or SecureField will trigger this action when the user hits the hardware or software return key. This modifier may also bind this action to a default action keyboard shortcut. You may set this action on an individual view or an entire view hierarchy.
|
||||
///
|
||||
/// TextField("Username", text: $username)
|
||||
/// .onSubmit {
|
||||
/// .backport.onSubmit {
|
||||
/// guard viewModel.validate() else { return }
|
||||
/// viewModel.login()
|
||||
/// }
|
||||
|
@ -31,7 +31,7 @@ public extension Backport where Wrapped: View {
|
|||
/// A semantic label describing the label of submission within a view hierarchy.
|
||||
///
|
||||
/// A submit label is a description of a submission action provided to a
|
||||
/// view hierarchy using the ``View/onSubmit(of:_:)`` modifier.
|
||||
/// view hierarchy using the ``View/backport.onSubmit(of:_:)`` modifier.
|
||||
@ViewBuilder
|
||||
func submitLabel(_ label: Backport<Any>.SubmitLabel) -> some View {
|
||||
Group {
|
||||
|
|
|
@ -18,7 +18,7 @@ extension Backport where Wrapped == Any {
|
|||
/// @State private var fullText: String = "This is some editable text..."
|
||||
///
|
||||
/// var body: some View {
|
||||
/// TextEditor(text: $fullText)
|
||||
/// Backport.TextEditor(text: $fullText)
|
||||
/// .foregroundColor(Color.gray)
|
||||
/// .font(.custom("HelveticaNeue", size: 13))
|
||||
/// .lineSpacing(5)
|
||||
|
@ -42,7 +42,7 @@ extension Backport where Wrapped == Any {
|
|||
/// @State private var fullText: String = "This is some editable text..."
|
||||
///
|
||||
/// var body: some View {
|
||||
/// TextEditor(text: $fullText)
|
||||
/// Backport.TextEditor(text: $fullText)
|
||||
/// .foregroundColor(Color.gray)
|
||||
/// .font(.custom("HelveticaNeue", size: 13))
|
||||
/// .lineSpacing(5)
|
||||
|
@ -100,6 +100,7 @@ extension Backport where Wrapped == Any {
|
|||
view.backgroundColor = .clear
|
||||
view.dataDetectorTypes = []
|
||||
view.returnKeyType = parent.environment.backportSubmitLabel.returnKeyType
|
||||
view.autocapitalizationType = parent.environment.textInputAutocapitalization?.capitalization ?? .sentences
|
||||
|
||||
switch parent.environment.autocorrectionDisabled {
|
||||
case true:
|
||||
|
|
Loading…
Reference in New Issue