RxSwift:从子视图控制器内部的TableViewCell观察UITextFields

时间:2018-08-14 10:03:25

标签: ios swift rx-swift

我在父viewController中有一个tableView和childController,ParentViewController中的tableView可以有1-4个单元格,每个单元格都包含一个UITextField。

ChildController也有一个TableView,它根据在ParentViewController tableView单元格中任何TextField中输入的内容列出结果(自动完成)。

我希望childController始终侦听任何UITextField并在tablView上显示结果。这是我目前所拥有的

private var query = Variable<String>("")
var queryDriver: Driver<String> {
    return query.asDriver()
}

TableView

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    guard let cell = tableView
        .dequeueReusableCell(
            withIdentifier: "StopCell", for: indexPath) as? StopCell else {
                fatalError("Cannot dequeue StopCell")
    }
    cell.delegate = self

    cell.locationTextField.rx.text.map {$0 ?? ""}
        .bind(to: query)
        .disposed(by: disposeBag)

    cell.locationTextField.rx.controlEvent(.editingDidEnd)
        .asDriver(onErrorJustReturn: ())
        .drive(onNext: { [unowned self] in
            cell.locationTextField.resignFirstResponder()
        })
        .disposed(by: disposeBag)
    return cell
}

添加子控制器

override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .white
    let noteVC = NoteVc()
    addChildController(viewController: noteVC)
}

NoteVC

class NoteVc: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .white
    view.addSubview(tableView)
    viewModel = SearchLocationViewModel(query: <#T##SharedSequence<DriverSharingStrategy, String>#>)
}

ViewModel

class SearchLocationViewModel {

let disposeBag = DisposeBag()
// MARK: - Properties

var querying: Driver<Bool> { return _querying.asDriver() }
var locations: Driver<[Location]> { return _locations.asDriver() }

// MARK: -

var hasLocations: Bool { return numberOfLocations > 0 }
var numberOfLocations: Int { return _locations.value.count }

// MARK: -

private let _querying = BehaviorRelay<Bool>(value: false)
private let _locations = BehaviorRelay<[Location]>(value: [])

// MARK: -

private let disposeBag = DisposeBag()

// MARK: - Initializtion

init(query: Driver<String>) {
    Behave.shared.queryDriver
        .throttle(0.5)
        .distinctUntilChanged()
        .drive(onNext: { [weak self] (addressString) in
            self?.geocode(addressString: addressString)
        })
        .disposed(by: disposeBag)
}

就像在Uber应用中实现的一样,用户最多可以添加三个目的地,下图中的黄色矩形框是我的ChildViewController

enter image description here

1 个答案:

答案 0 :(得分:2)

这是我能想到的最简单的方法。我将viewModel设置为全局常量,但您可能需要对其进行详细说明。

(?, 4)