Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/118.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 导航堆栈之前的视图之间的协议委托_Ios_Swift_Delegates_Segue_Protocols - Fatal编程技术网

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 to
View3

我正在尝试创建从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,那么使用展开段可能是最简单/最干净的

  • 在VC1中创建界面生成器操作:

    class VC1:UIViewController{
    @iAction func backToVC1(segue:UIStoryboardSegue){
    self.showAddress()
    }
    func showAddress(){
    addressView.isHidden=false
    }
    }
    
  • 在VC3控件的故事板中,单击视图控制器图标,将鼠标拖动到退出图标上,然后释放。单击以选择在VC1中创建的展开序列

  • 创建segue后,在文档大纲中选择它

  • 并在属性检查器中将其命名

  • 最后,在VC3代码中调用segue

    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()
    
        }
    
        }