import SwiftUI /// A view modifier that intercepts newlines in a text field and transfers focus to another field. /// /// This modifier monitors text changes in a `TextField` component and prevents newlines /// from being added. Instead, when a newline is detected, it updates the focus state to move to /// a specified field. struct OnNewlineFocusModifier: ViewModifier { // MARK: Properties /// Binding to the text being edited. @Binding private var text: String /// Binding to the focus state. private let focusState: FocusState.Binding /// The field to focus when a newline is detected. private let targetField: Field // MARK: Initializers /// Creates a modifier that transfers focus on newline. /// /// - Parameters: /// - text: A binding to the text being edited. /// - focusState: A binding to the focus state. /// - targetField: The field to focus when a newline is detected. init( text: Binding, focusState: FocusState.Binding, targetField: Field ) { self._text = text self.focusState = focusState self.targetField = targetField } // MARK: Body /// The content and behavior of the view modifier. func body(content: Content) -> some View { content .onChange(of: text) { oldValue, newValue in guard newValue.contains(.newline) else { return } text = oldValue focusState.wrappedValue = targetField } } } // MARK: - View Extension extension View { /// Transfers focus to another field when the user presses return in a text field. /// /// This modifier prevents newlines from being added and instead moves keyboard focus /// to the specified field. Useful for creating a form-like flow between text fields. /// /// - Parameters: /// - text: A binding to the text being edited. /// - field: The field to focus when return is pressed. /// - focusState: A binding to the focus state. /// - Returns: A modified view with focus transfer behavior. func onNewlineFocus( _ text: Binding, to field: Field, on focusState: FocusState.Binding ) -> some View { modifier( OnNewlineFocusModifier( text: text, focusState: focusState, targetField: field ) ) } }