ResponsiveTextField Documentation

Structure First​Responder​State​Change​Handler

public struct FirstResponderStateChangeHandler  

Initializers

init(handle​State​Change:​)

public init(handleStateChange: @escaping (Bool) -> Void)  

Initialises a state change handler with a handleStateChange callback.

Most of the time this is the only callback that you will need to provide so this initialiser can be called with trailing closure syntax.

init(handle​State​Change:​can​Become​First​Responder:​can​Resign​First​Responder:​)

public init(
        handleStateChange: @escaping (Bool) -> Void,
        canBecomeFirstResponder: (() -> Bool)? = nil,
        canResignFirstResponder: (() -> Bool)? = nil
    )  

Properties

handle​State​Change

public var handleStateChange: (Bool) -> Void

A closure that will be called when the first responder state changes.

Parameters

Bool

A boolean indicating if the text field is now the first responder or not.

can​Become​First​Responder

public var canBecomeFirstResponder: (() -> Bool)? 

Allows fine-grained control over if the text field should become the first responder.

This will be called when the text field's shouldBeginEditing delegate method is called and provides a final opportunity to prevent the text field becoming first responder.

If the responder change was triggered programatically by a FirstResponderDemand and this returns false the demand will still be marked as fulfilled and reset to nil.

can​Resign​First​Responder

public var canResignFirstResponder: (() -> Bool)? 

Allows fine-grained control over if the text field should resign the first responder.

This will be called when the text field's shouldEndEditing delegate method is called and provides a final opportunity to prevent the text field from resigning first responder.

If the responder change was triggered programatically by a FirstResponderDemand and this returns false the demand will still be marked as fulfilled and reset to nil.

Methods

animation(animation:​)

public func animation(animation: Animation? = .default) -> Self  

Returns a new state change handler that wraps the underlying state change handler in a withAnimation closure - this is useful if your state change handler is performing some state change and you want that change to be animated.

Parameters

animation Animation?

The animation to perform, or nil if you want to explicitly disable animations.

receive(on:​options:​)

public func receive<S: Scheduler>(on scheduler: S, options: S.SchedulerOptions? = nil) -> Self  

Returns a new state change handler that scheduldes the callback to the original state change handler on the given scheduler.

This modifier is useful when your first responder state change handler needs to perform some state mutation that will trigger a new view update and you are programatically triggering the first responder state change.

When a text field becomes first responder naturally, e.g. because the user tapped on the text field, it is safe to perform state changes that perform a view update inside this callback. However, programatic first responder state changes (where you change the demand state connected to the firstResponderDemand binding passed into ResponsiveTextField) happen as part of a view update - i.e. the demand change will trigger a view update and the becomeFirstResponder() call will happen in the updateUIView as part of that view change event.

This means that the change handler callback will be called as part of the view update and if that change handler does something to trigger a view update itself, you will receive a runtime warning about the nested view updates.

To break this loop, ResponsiveTextField could ensure that it always wraps its calls to the change handler on the next runloop tick, or in an async DispatchQueue call however this would be a pretty brute-force approach and would result in an unnecessary queue hop on every callback, even if it wasn't needed.

Instead, if you are programatically triggering a first responder change and the text field and also triggering a view update in your state change handler, you can explicitly force that callback to happen after the view update cycle completes using this method. You can pass in any suitable scheduler, such as RunLoop.main or DispatchQueue.main.

Parameters

scheduler S

The scheduler to schedule the callback on when the first responder state changes.

options S.​Scheduler​Options?

Options to be passed to the scheduler when scheduling.

updates(_:​)

public static func updates(_ binding: Binding<Bool>) -> Self  

Returns a change handler that updates a Bool binding with the isFirstResponder value whenever it changes.

Parameters

binding Binding<Bool>

A binding to some Boolean state property that should be updated.