Search code examples
iosswiftuisearchbaruisearchcontrollerrx-swift

RxSwift only trigger once


searchController.searchBar.rx.text
            .asDriver()
            .map{ $0 == "" || $0 == nil }
            .drive(onNext: { (empty) in
                if empty {
                    print("Search empty")
                } else {
                    print("!!!!!!!!!!!!! empty")
                }
            }).disposed(by: disposeBag)

This will be called once the first time it is started, the second one when I type the first string, but will not be valid anymore,where the error? thank!!!


Solution

  • I have checked your code and found that setting UISearchBar's delegate makes the driver to fire only once. For example:

    self.searchController.searchBar.delegate = self
    

    If the delegate isn't set - the driver fires as you expect. So you should do something with search delegates and check whether it helps you to solve the problem.

    This is a sample project which represents this behavior:

    import Foundation
    import UIKit
    import RxCocoa
    import RxSwift
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    
        var window: UIWindow? = UIWindow(frame: UIScreen.main.bounds)
    
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            window?.rootViewController = UINavigationController(rootViewController: Controller())
            window?.makeKeyAndVisible()
            return true
        }
    }
    
    final class Controller: UIViewController, UISearchResultsUpdating, UISearchControllerDelegate, UISearchBarDelegate {
    
        lazy var disposeBag = DisposeBag()
        lazy var searchController = UISearchController(searchResultsController: nil)
    
        init() {
            super.init(nibName: nil, bundle: nil)
            self.view.backgroundColor = UIColor.orange
            self.searchController.searchResultsUpdater = self
            self.searchController.hidesNavigationBarDuringPresentation = false
            self.navigationItem.titleView = self.searchController.searchBar
            self.definesPresentationContext = true
            self.searchController.delegate = self
            self.searchController.dimsBackgroundDuringPresentation = false
            // self.searchController.searchBar.delegate = self
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            searchController.searchBar.rx.text
                .asDriver()
                .map{ $0 == "" || $0 == nil }
                .drive(onNext: { (empty) in
                    if empty {
                        print("Search empty")
                    } else {
                        print("!!!!!!!!!!!!! empty")
                    }
                })
                .disposed(by: disposeBag)
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        func updateSearchResults(for searchController: UISearchController) {
            //
        }
    }