Structure
FirstResponderStateChangeHandler
public struct FirstResponderStateChangeHandler
Initializers
init(handleStateChange:)
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(handleStateChange:canBecomeFirstResponder:canResignFirstResponder:)
public init(
handleStateChange: @escaping (Bool) -> Void,
canBecomeFirstResponder: (() -> Bool)? = nil,
canResignFirstResponder: (() -> Bool)? = nil
)
Properties
handleStateChange
public var handleStateChange: (Bool) -> Void
A closure that will be called when the first responder state changes.
Parameters
Name | Type | Description |
---|---|---|
Bool | A boolean indicating if the text field is now the first responder or not. |
canBecomeFirstResponder
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
.
canResignFirstResponder
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
Name | Type | Description |
---|---|---|
animation | Animation? |
The animation to perform, or |
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
Name | Type | Description |
---|---|---|
scheduler | S |
The scheduler to schedule the callback on when the first responder state changes. |
options | S.SchedulerOptions? |
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
Name | Type | Description |
---|---|---|
binding | Binding<Bool> |
A binding to some Boolean state property that should be updated. |