gpt4 book ai didi

ios - 如何在不在 ViewController 类中时以编程方式更改 View Controller

转载 作者:行者123 更新时间:2023-11-28 06:21:39 25 4
gpt4 key购买 nike

我知道这个问题已经被问过无数次了,而且我已经看到了很多变体,包括

func performSegue(withIdentifier identifier: String, 
sender: Any?)

以及此处提到的所有其他变体:How to call a View Controller programmatically

但是您将如何更改 ViewController 类之外的 View Controller ?例如,用户当前在 ViewController_A 上,当蓝牙设备断开连接(超出范围、信号弱等)时,CBCentral< 的 didDisconnectPeripheral 方法 被触发。在同一个方法中,我想将当前 View 更改为 ViewController_B,但是此方法不会出现在 ViewController 类中,所以方法如 performSegue 不会工作。

我在我的 AppDelegate 中实现的一个建议似乎有效(用于获取适合 iphone 屏幕尺寸的 Storyboard文件/我讨厌太多的 AutoLayout热情)

    var storyboard: UIStoryboard = self.grabStoryboard()
display storyboard
self.window!.rootViewController = storyboard.instantiateInitialViewController()
self.window!.makeKeyAndVisible()

然后我尝试在我的非ViewController 类中做同样的事情

    var window: UIWindow?
var storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) //assume this is the same storyboard pulled in `AppDelegate`
self.window!.rootViewController = storyboard.instantiateViewController(withIdentifier: "ViewController_B")
self.window!.makeKeyAndVisible()

但是我得到一个异常抛出说 fatal error: unwrappedly found nil while unwrapping an Optional value 大概来自 window!

关于我可以做什么以及正确的设计模式是什么有什么建议吗?

最佳答案

试试这个:

protocol BTDeviceDelegate {
func deviceDidDisconnect()
func deviceDidConnect()
}

class YourClassWhichIsNotAViewController {

weak var deviceDelegate: BTDeviceDelegate?


func yourMethod() {
deviceDelegate?.deviceDidDisconnect()
}
}


class ViewController_A {

var deviceManager: YourClassWhichIsNotAViewController?

override func viewDidLoad() {

deviceManager = YourClassWhichIsNotAViewController()
deviceManager.delegate = self
}
}

extension ViewController_A: BTDeviceDelegate {
func deviceDidDisconnect() {
DispatchQueue.main.async {
// change the VC however you want here :)

// updated answer with 2 examples.
// The DispatchQueue.main.async is used here because you always want to do UI related stuff on the main queue
// and I am fairly certain that yourMethod is going to get called from a background queue because it is handling
// the status of your BT device which is usually done in the background...

// There are numerous ways to change your current VC so the decision is up to your liking / use-case.
// 1. If you are using a storyboard - create a segue from VC_A to VC_B with an identifier and use it in your code like this
performSegue(withIdentifier: "YourSegueIdentifierWhichYouveSpecifiedInYourSeguesAttibutesInspector", sender: nil)

// 2. Instantiate your VC_B from a XIB file which you've created in your project. You could think of a XIB file as a
// mini-storyboard made for one controller only. The nibName argument is the file's name.
let viewControllerB = ViewControllerB(nibName: "VC_B", bundle: nil)
// This presents the VC_B modally
present(viewControllerB, animated: true, completion: nil)

}
}

func deviceDidConnect() {}

}

YourClassWhichIsNotAViewController 是处理蓝牙设备状态的类。在 VC_A 内部启动它并适本地响应委托(delegate)方法。这应该是您正在寻找的设计模式。

关于ios - 如何在不在 ViewController 类中时以编程方式更改 View Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43264459/

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