gpt4 book ai didi

mvvm - 传递数据 MVVM 和 RxSwift

转载 作者:行者123 更新时间:2023-12-03 10:25:18 25 4
gpt4 key购买 nike

我目前正在学习 MVVM 和 RxSwift。在我的主视图 Controller 中,我有一张我想传入的图像。我成功地使用了 mvc 和 RxSwift,但是因为 MVVM 对我来说是新的。我不知道如何在 MVVM 中实现。这是我的代码。

// This is the work version MVC RxSwift
class GProfilePickAlertVC: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

private let selectedSubjectPhoto = PublishSubject<UIImage>()
var selectedPhoto: Observable<UIImage> {
return selectedSubjectPhoto.asObservable()
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let editedImage = info[.editedImage] as? UIImage {
self.selectedSubjectPhoto.onNext(editedImage)
dismiss(animated: true, completion: nil)
}
dismiss(animated: true, completion: nil)
}
}

class BasicInfoViewController: UITableViewController {
let profileImageView = GProfileImage(img: #imageLiteral(resourceName: "ic-tab-profile"), renderingMode: .alwaysTemplate)

@objc private func handlePickPhoto() {
let pickPhotoVC = GProfilePickAlertVC()
pickPhotoVC.selectedPhoto.subscribe(onNext: { image in
self.profileImageView.clipsToBounds = true
self.profileImageView.image = image
}).disposed(by: disposeBag)
pickPhotoVC.modalPresentationStyle = .overFullScreen
pickPhotoVC.modalTransitionStyle = .crossDissolve
present(pickPhotoVC, animated: true)
}
}

// This is my MVVM setup
struct BasicInfoViewModel {

let selectedImage: BehaviorRelay<UIImage>
}

class BasicInfoViewController: UITableViewController {

let disposeBag = DisposeBag()

var BasicInfoViewModel: BasicInfoViewModel!
}

最佳答案

这就是我最终的结果。在这种情况下, View 模型实际上并没有太多可做的事情,因为只有一行逻辑。

代码的基本结构与您的 MVC 示例相同,只是我的代码使用 RxImagePickerDelegateProxy而不是 GProfilePickAlertVC .前者是一个通用委托(delegate),它会根据需要由 Rx 系统自动附加到任何 UIImagePickerController。
imagePickerScene(on:modalPresentationStyle:modalTransitionStyle:)函数负责呈现和关闭图像选择器。它充当协调器。
castOrThrow(_:_:) function 是处理强制转换的通用助手。你可以在任何地方使用它。

final class BasicInfoViewController: UIViewController {

private let profileImageView = GProfileImage(img: #imageLiteral(resourceName: "ic-tab-profile"), renderingMode: .alwaysTemplate)
private let disposeBag = DisposeBag()

override func viewDidLoad() {
super.viewDidLoad()

let imagePicker = imagePickerScene(
on: self,
modalPresentationStyle: .overFullScreen,
modalTransitionStyle: .crossDissolve
)

pickPhotoButton.rx.tap
.flatMapLatest { Observable.create(imagePicker) }
.compactMap { $0[.editedImage] as? UIImage }
.bind { image in
self.profileImageView.clipsToBounds = true
self.profileImageView.image = image
}
.disposed(by: disposeBag)
}
}

func imagePickerScene(on presenter: UIViewController, modalPresentationStyle: UIModalPresentationStyle? = nil, modalTransitionStyle: UIModalTransitionStyle? = nil) -> (_ observer: AnyObserver<[UIImagePickerController.InfoKey: AnyObject]>) -> Disposable {
return { [weak presenter] observer in
let controller = UIImagePickerController()
if let presentationStyle = modalPresentationStyle {
controller.modalPresentationStyle = presentationStyle
}
if let transitionStyle = modalTransitionStyle {
controller.modalTransitionStyle = transitionStyle
}
presenter?.present(controller, animated: true)
return controller.rx.didFinishPickingMediaWithInfo
.do(onNext: { _ in
presenter?.dismiss(animated: true)
})
.subscribe(observer)
}
}

final class RxImagePickerDelegateProxy: DelegateProxy<UIImagePickerController, UINavigationControllerDelegate & UIImagePickerControllerDelegate>, DelegateProxyType, UINavigationControllerDelegate & UIImagePickerControllerDelegate {

static func currentDelegate(for object: UIImagePickerController) -> (UIImagePickerControllerDelegate & UINavigationControllerDelegate)? {
return object.delegate
}

static func setCurrentDelegate(_ delegate: (UIImagePickerControllerDelegate & UINavigationControllerDelegate)?, to object: UIImagePickerController) {
object.delegate = delegate
}

static func registerKnownImplementations() {
self.register { RxImagePickerDelegateProxy(parentObject: $0, delegateProxy: RxImagePickerDelegateProxy.self) }
}
}

extension Reactive where Base: UIImagePickerController {

var didFinishPickingMediaWithInfo: Observable<[UIImagePickerController.InfoKey: AnyObject]> {
return RxImagePickerDelegateProxy.proxy(for: base)
.methodInvoked(#selector(UIImagePickerControllerDelegate.imagePickerController(_:didFinishPickingMediaWithInfo:)))
.map({ (a) in
return try castOrThrow(Dictionary<UIImagePickerController.InfoKey, AnyObject>.self, a[1])
})
}
}

func castOrThrow<T>(_ resultType: T.Type, _ object: Any) throws -> T {
guard let returnValue = object as? T else {
throw RxCocoaError.castingError(object: object, targetType: resultType)
}

return returnValue
}

关于mvvm - 传递数据 MVVM 和 RxSwift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60669173/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com