Ios 导航堆栈之前的视图之间的协议委托
Ios 导航堆栈之前的视图之间的协议委托,ios,swift,delegates,segue,protocols,Ios,Swift,Delegates,Segue,Protocols,View1segues to导航控制器-View2segues toView3 我正在尝试创建从View3到View1的协议委托 在视图1中 class NormalUser: UIViewController, NormalUserDelegate { @objc func showAddressView() { addressView.isHidden = false } override func viewDidLoad() {
View1
segues to导航控制器-View2
segues toView3
我正在尝试创建从View3到View1的协议委托
在视图1中
class NormalUser: UIViewController, NormalUserDelegate {
@objc func showAddressView() {
addressView.isHidden = false
}
override func viewDidLoad() {
super.viewDidLoad()
if let conn = self.storyboard?.instantiateViewController(withIdentifier: "View") as? View
{
conn.delegate = self
}
}
}
在视图3中
weak var delegate: NormalUserDelegate?
func test() {
self.delegate?.showAddressView()
}
协议
protocol NormalUserDelegate: class {
func showAddressView()
}
我不能让它工作。有什么想法吗?如果我正确理解您的场景,您需要两个代理,每个代理将数据传递回以前的UIViewController。据我所知,您不能绕过辅助UIViewController。您缺少的是一个路由器类,这是一个简单的示例,说明了如何实现它
protocol RoutingView1{
func openView2()
}
protocol RoutingView2{
func openView3()
}
protocol RoutingView3{
func foo()
}
class View1{
func foo(){
//this will get called when View3 calls its RootingView3.foo()
}
}
class Router: RoutingView1, RoutingView2{
var rootView: View1
func start() -> UIViewController{
view.routingDelegate = self
rootView = view1
}
func openView2(){
let vc = View2()
vc.routingDelegate = self
rootView.push()
}
func openView3(){
let vc = View3()
vc.routingDelegate = self
rootView.push()
}
func foo(){
rootView.foo()
}
在我看来,使用委托模式有两个不错的选择。一个可怕的选择,它会工作,但它的黑客和懒惰,然后你有广播接收机模式 2个不错的选择 1-将代表向前传递
类VC1:UIViewController,SomeDelegate{
func delegateFunction(){}
func showNextVC(){
让next=VC2()
next.forwardingDelegate=self
当前(下一个,动画:true)
}
}
VC2类:UIViewController{
var forwardingDelegate:SomeDelegate?=nil
func showNextVC(){
设next=VC3()
next.delegate=forwardingDelegate
当前(下一个,动画:true)
}
}
2-将第三个控制器传递给第二个控制器
类VC1:UIViewController,SomeDelegate{
func delegateFunction(){}
func showNextVC(){
设final=VC3()
final.delegate=self
让next=VC2(带控制器ToPresent:final)
当前(下一个,动画:true)
}
}
VC2类:UIViewController{
let控制器:UIViewController
初始化(带控制器当前控制器:UIViewController){
self.controller=控制器
super.init(带nibName:nil,bundle:nil
}
func showNextVC(){
存在(控制器,动画:真)
}
}
类VC3:UIViewController{
变量委托:SomeDelegate?=nil
}
一个糟糕的选择
使用单例/全局变量…(请不要)
个人意见
我已经完成了前两个选项……它们都可以工作。但是广播接收器模式可能更好,因为它会更干净。VC2不需要将任何内容转发到3。只需确保通知的名称空间足够具体,以便以后不会被任何其他内容捕获。展开分段
如果您使用的是interface builder,那么使用展开段可能是最简单/最干净的
class VC1:UIViewController{
@iAction func backToVC1(segue:UIStoryboardSegue){
self.showAddress()
}
func showAddress(){
addressView.isHidden=false
}
}
class VC3:UIViewController{
func测试(){
self.performsgue(带有标识符:“unwindToVC1”,发送方:self)
}
}
我想您可以使用
SwiftEventBus
来解决这种情况
示例:
@IBAction func clicked(sender: AnyObject) {
count++
SwiftEventBus.post("doStuffOnBackground")
}
@IBOutlet weak var textField: UITextField!
var count = 0
override func viewDidLoad() {
super.viewDidLoad()
SwiftEventBus.onBackgroundThread(self, name: "doStuffOnBackground") { notification in
println("doing stuff in background thread")
SwiftEventBus.postToMainThread("updateText")
}
SwiftEventBus.onMainThread(self, name: "updateText") { notification in
self.textField.text = "\(self.count)"
}
}
//Perhaps on viewDidDisappear depending on your needs
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
SwiftEventBus.unregister(self)
}
我想在这种情况下最好使用NSnotifications。你得不到答案的原因是你的问题一点也不清楚。不要让我们破译你的代码来找出你想问什么,并给我们更多关于你失败原因的信息,而不是“我无法让它工作”此外,视图控制器不是视图,因此将其称为“视图1”和“视图3”只会使您的问题更难理解。在您的示例中,
conn
在viewDidLoad
之后超出范围。View3的委托
成员被标记为弱
,因此当viewDidLoad
返回时,对它的引用将丢失。要使代码工作,您必须使conn
成为成员或者删除View1类的delegate
成员上的weak
关键字。@UtkuDalmaz,请共享一个演示项目,该项目再现了您面临的相同问题。注意,这不使用故事板。尽管我认为您仍然可以这样做,但只需将文件中的属性设置为IBoutlet,并将它们连接到故事中即可板
**Just set delegate of view 2 as a delegate of view 3 as below:**
class View1: UIViewController, NormalUserDelegate {
@objc func showAddressView() {
addressView.isHidden = false
}
// Going to view 2 by any means i.e segue , navigation set
func goToView2Controller(){
if let view2 = self.storyboard?.instantiateViewController(withIdentifier: "View2") as? View2
{
view2.delegate = self
}
self.navigationController?.pushViewController(view2, animated: true)
}
}
class View2: UIViewController {
weak var delegate: NormalUserDelegate?
// Going to view 3 by any means i.e segue or other means
func goToView3Controller(){
if let view3 = self.storyboard?.instantiateViewController(withIdentifier: "View3") as? View3
{
view3.delegate = self.delegate
}
self.navigationController?.pushViewController(view3, animated: true)
}
}
class View3: UIViewController {
weak var delegate: NormalUserDelegate?
func test() {
self.delegate?.showAddressView()
}
}