我发现,当使用 RxSwift 时,“view-model”最终是一个单一的纯函数,它从输入 UI 参数中获取可观察的参数并返回可观察的参数,然后绑定到输出的 UI 元素。
tutorial videos for cycle.js 是真正帮助我理解 Rx 的东西。
至于你的具体难题...
您所做的不一定是“向前”运动。这样看... TabBarView 需要一些数据,它并不关心这些数据来自哪里。所以让 TabBarView 访问一个函数,该函数返回一个包含必要数据的可观察对象。该关闭将显示蓝牙视图,建立连接,获取必要的数据,然后关闭蓝牙视图并使用所需的数据调用onNext。
查看this gist 可能有助于理解我在说什么。授予 gist 使用 PromiseKit 而不是 RxSwift,但可以使用相同的原理(而不是 fulfill,您可能想调用 onNext 然后 onCompletion。)在 gist 中,视图控制器只需要数据调用一个函数并订阅结果(在这种情况下,结果包含一个 UIImage。)该函数的工作是确定哪些图像源可用,询问用户他们想从哪个源检索图像并呈现适当的视图控制器来获取图像。
gist 目前的内容如下:
//
// UIViewController+GetImage.swift
//
// Created by Daniel Tartaglia on 4/25/16.
// Copyright © 2016 MIT License
//
import UIKit
import PromiseKit
enum ImagePickerError: ErrorType {
case UserCanceled
}
extension UIViewController {
func getImage(focusView view: UIView) -> Promise<UIImage> {
let proxy = ImagePickerProxy()
let cameraAction: UIAlertAction? = !UIImagePickerController.isSourceTypeAvailable(.Camera) ? nil : UIAlertAction(title: "Camera", style: .Default) { _ in
let controller = UIImagePickerController()
controller.delegate = proxy
controller.allowsEditing = true
controller.sourceType = .Camera
self.presentViewController(controller, animated: true, completion: nil)
}
let photobinAction: UIAlertAction? = !UIImagePickerController.isSourceTypeAvailable(.PhotoLibrary) ? nil : UIAlertAction(title: "Photos", style: .Default) { _ in
let controller = UIImagePickerController()
controller.delegate = proxy
controller.allowsEditing = false
controller.sourceType = .PhotoLibrary
self.presentViewController(controller, animated: true, completion: nil)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
if let cameraAction = cameraAction {
alert.addAction(cameraAction)
}
if let photobinAction = photobinAction {
alert.addAction(photobinAction)
}
alert.addAction(cancelAction)
let popoverPresentationController = alert.popoverPresentationController
popoverPresentationController?.sourceView = view
popoverPresentationController?.sourceRect = view.bounds
presentViewController(alert, animated: true, completion: nil)
let promise = proxy.promise
return promise.always {
self.dismissViewControllerAnimated(true, completion: nil)
proxy.retainCycle = nil
}
}
}
private final class ImagePickerProxy: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
let (promise, fulfill, reject) = Promise<UIImage>.pendingPromise()
var retainCycle: ImagePickerProxy?
required override init() {
super.init()
retainCycle = self
}
@objc func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let image = (info[UIImagePickerControllerEditedImage] as? UIImage) ?? (info[UIImagePickerControllerOriginalImage] as! UIImage)
fulfill(image)
}
@objc func imagePickerControllerDidCancel(picker: UIImagePickerController) {
reject(ImagePickerError.UserCanceled)
}
}