簡體   English   中英

如何解決在 Swift 中通過 Coordinator 的操作打開 ViewController 的問題?

[英]How to fix problem with opening ViewController by action from Coordinator in Swift?

我正在嘗試通過點擊 tableView 的單元格來打開另一個 controller。 我正在使用 MVVM 和協調器模式進行編碼。

一開始我們看到這個屏幕 - 它在方法 start() 中聲明

let service = Service()
private(set) weak var navigationController: UINavigationController?

func start() -> UINavigationController {
    let vm = ContinentsViewModel(service: service)
    let vc = ContinentsViewController(viewModel: vm)
    let navigationController = UINavigationController()
    self.navigationController = navigationController
    navigationController.setViewControllers([vc], animated: false)
    bindContinentsViewModel(viewModel: vm)
    return navigationController
}

pic.1 - func start()

后來,我的目標是打開該大陸的所有國家/地區列表,但現在我只需要通過點擊單元格(例如非洲或南極洲)來打開空的 ViewController。 這是我的方法,但它們不起作用。

private func showCountries() {
    let vc = ViewController()
    navigationController?.pushViewController(vc, animated: true)
}

private func bindContinentsViewModel(viewModel: ContinentsViewModel) {
    viewModel
        .flow
        .bind { [weak self] flow in
            switch flow {
            case .onContinentTap:
                self?.showCountries() // don't work
              //  print("show \(continent)") // work - continent is a param of .onContinentTap, which prints an geo-id of the continent, just if you need to know.
            }
        }
        .disposed(by: viewModel.bag)
}

太感謝了!

以下工作按預期進行。 你在做什么不同?

@main
final class AppDelegate: UIResponder, UIApplicationDelegate {
    
    var window: UIWindow?
    var viewModel: ViewModel?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        viewModel = ViewModel()
        let controller = viewModel?.start()

        window = UIWindow(frame: UIScreen.main.bounds)
        window?.rootViewController = controller
        window?.makeKeyAndVisible()

        return true
    }
}

final class ViewModel {
    private(set) weak var navigationController: UINavigationController?

    func start() -> UINavigationController {
        let vm = ContinentsViewModel()
        let vc = ContinentsViewController(viewModel: vm)
        let navigationController = UINavigationController()
        self.navigationController = navigationController
        navigationController.setViewControllers([vc], animated: false)
        bindContinentsViewModel(viewModel: vm)
        return navigationController
    }

    private func showCountries() {
        let vc = UIViewController()
        vc.view.backgroundColor = .blue
        navigationController?.pushViewController(vc, animated: true)
    }

    private func bindContinentsViewModel(viewModel: ContinentsViewModel) {
        viewModel.flow
            .bind { [weak self] flow in
                switch flow {
                case .onContinentTap:
                    self?.showCountries()
                }
            }
            .disposed(by: viewModel.bag)
    }
}

final class ContinentsViewModel {
    enum Flow {
        case onContinentTap
    }
    let flow: Observable<Flow>
    let bag = DisposeBag()

    init() {
        flow = .just(.onContinentTap)
            .delay(.seconds(3), scheduler: MainScheduler.instance)
    }
}

final class ContinentsViewController: UIViewController {
    var viewModel: ContinentsViewModel
    init(viewModel: ContinentsViewModel) {
        self.viewModel = viewModel
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .red
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM