55import Combine
66import UIKit
77import SwiftUI
8+ import CombineSchedulers
89
910// MARK: - Main Interface
1011
@@ -71,6 +72,9 @@ public struct ResponsiveTextField {
7172 @Environment ( \. textFieldTextAlignment)
7273 var textAlignment : NSTextAlignment
7374
75+ @Environment ( \. responderScheduler)
76+ private var responderScheduler : AnySchedulerOf < RunLoop >
77+
7478 /// A calllback function that will be called whenever the first responder state changes.
7579 var onFirstResponderStateChanged : FirstResponderStateChangeHandler ?
7680
@@ -344,25 +348,25 @@ extension ResponsiveTextField: UIViewRepresentable {
344348
345349 switch ( uiView. isFirstResponder, firstResponderDemand? . wrappedValue) {
346350 case ( true , . shouldResignFirstResponder) :
347- RunLoop . main . schedule { uiView. resignFirstResponder ( ) }
351+ responderScheduler . schedule { uiView. resignFirstResponder ( ) }
348352 case ( false , . shouldBecomeFirstResponder) :
349- RunLoop . main . schedule { uiView. becomeFirstResponder ( ) }
353+ responderScheduler . schedule { uiView. becomeFirstResponder ( ) }
350354 case ( _, nil ) :
351355 // If there is no demand then there's nothing to do.
352356 break
353357 default :
354358 // If the current responder state matches the demand then
355359 // the demand is already fulfilled so we can just reset it.
356- resetFirstResponderDemandAfterViewUpdate ( )
360+ resetFirstResponderDemand ( )
357361 }
358362 }
359363
360- fileprivate func resetFirstResponderDemandAfterViewUpdate ( ) {
364+ fileprivate func resetFirstResponderDemand ( ) {
361365 // Because the first responder demand will trigger a view
362366 // update when it is set, we need to wait until the next
363367 // runloop tick to reset it back to nil to avoid runtime
364368 // warnings.
365- RunLoop . main . schedule {
369+ responderScheduler . schedule {
366370 firstResponderDemand? . wrappedValue = nil
367371 }
368372 }
@@ -382,7 +386,7 @@ extension ResponsiveTextField: UIViewRepresentable {
382386 if let canBecomeFirstResponder = parent. onFirstResponderStateChanged? . canBecomeFirstResponder {
383387 let shouldBeginEditing = canBecomeFirstResponder ( )
384388 if !shouldBeginEditing {
385- parent. resetFirstResponderDemandAfterViewUpdate ( )
389+ parent. resetFirstResponderDemand ( )
386390 }
387391 return shouldBeginEditing
388392 }
@@ -391,14 +395,14 @@ extension ResponsiveTextField: UIViewRepresentable {
391395
392396 public func textFieldDidBeginEditing( _ textField: UITextField ) {
393397 parent. onFirstResponderStateChanged ? ( true )
394- parent. resetFirstResponderDemandAfterViewUpdate ( )
398+ parent. resetFirstResponderDemand ( )
395399 }
396400
397401 public func textFieldShouldEndEditing( _ textField: UITextField ) -> Bool {
398402 if let canResignFirstResponder = parent. onFirstResponderStateChanged? . canResignFirstResponder {
399403 let shouldEndEditing = canResignFirstResponder ( )
400404 if !shouldEndEditing {
401- parent. resetFirstResponderDemandAfterViewUpdate ( )
405+ parent. resetFirstResponderDemand ( )
402406 }
403407 return shouldEndEditing
404408 }
@@ -407,7 +411,7 @@ extension ResponsiveTextField: UIViewRepresentable {
407411
408412 public func textFieldDidEndEditing( _ textField: UITextField ) {
409413 parent. onFirstResponderStateChanged ? ( false )
410- parent. resetFirstResponderDemandAfterViewUpdate ( )
414+ parent. resetFirstResponderDemand ( )
411415 }
412416
413417 public func textFieldShouldReturn( _ textField: UITextField ) -> Bool {
0 commit comments