【问题标题】:Swift – Using popViewController and passing data to the ViewController you're returning toSwift – 使用 popViewController 并将数据传递给您要返回的 ViewController
【发布时间】:2015-06-22 03:20:38
【问题描述】:

我的第一个视图控制器名为ViewController 上有一个可选的bool 变量showSettings,我从SecondViewController 弹出回到ViewController

在弹出之前,我想将 bool 设置为 true。实例化另一个视图控制器似乎是错误的,因为ViewController 在内存中。

最好的方法是什么?我没有使用情节提要,如果这对您的回答很重要的话。

感谢您的帮助

【问题讨论】:

标签: swift ios8 uinavigationcontroller


【解决方案1】:

所以我想通了,主要来自这篇文章 – http://makeapppie.com/2014/09/15/swift-swift-programmatic-navigation-view-controllers-in-swift/

SecondViewController的类声明上方,添加以下代码:

protocol SecondVCDelegate {
    func didFinishSecondVC(controller: SecondViewController)
}

然后在SecondViewContoller里面添加一个类变量:

var delegate: MeditationVCDelegate! = nil

然后在按钮所针对的函数内部,添加以下内容:

self.navigationController?.popViewControllerAnimated(true)
delegate.didFinishSecondVC(self)

我们在这里所做的是在SecondViewController 中进行弹出,并且传递任何数据,但是由于我们已经定义了一个协议,我们将在@987654328 中使用它@ 处理数据。

接下来,在ViewController 中,将您在SecondViewController 中定义的协议添加到ViewController 继承自的类列表中:

class ViewController: UIViewController, SecondVCDelegate { ... your code... }

您需要添加我们在新协议中定义的函数,以使编译器满意。在ViewController 的类中,添加:

func didFinishSecondVC(controller: SecondViewController) {
    self.myBoolVar = true
    controller.navigationController?.popViewControllerAnimated(true)
}

在我们调用didFinishSecondVCSecondViewController 中,我们在ViewController 类内部调用这个方法,我们要弹出的控制器。这类似于我们在 SecondViewController 内编写此代码,但我们已将其编写在 ViewController 内,并且我们使用委托来管理两者之间的消息传递。

最后,在ViewController 中,在我们要pushSecondViewController 的函数中,添加以下代码:

let secondVC = secondViewController()
secondVC.delegate = self
self.navigationController?.pushViewController(secondVC, animated: true)

就是这样!你应该准备好在两个视图控制器之间传递代码而不使用故事板!

【讨论】:

  • 我认为var delegate: MeditationVCDelegate! = nil 应该是var delegate: SecondVCDelegate! = nil,对吧?
  • 不错的解决方案!谢谢扎克!
【解决方案2】:
_ = self.navigationController?.popViewController(animated: true)
        let previousViewController = self.navigationController?.viewControllers.last as! PreviousViewController
        previousViewController.PropertyOrMethod

【讨论】:

    【解决方案3】:

    我在寻找方法时遇到了这个问题。由于我更频繁地使用 Storyboard,我发现我可以在导航堆栈中获取控制器数组,获取位于顶部的当前控制器之前的控制器,检查它是否是我的委托,如果是,将其转换为委托,设置我的方法,然后将自己从堆栈中弹出。虽然代码在 ObjC 中,但应该很容易翻译成 swift:

    // we need to get the previous view controller
    NSArray *array = self.navigationController.viewControllers;
    if ( array.count > 1) {
        UIViewController *controller = [array objectAtIndex:(array.count - 2)];
        if ( [controller conformsToProtocol:@protocol(GenreSelectionDelegate)]) {
            id<GenreSelectionDelegate> genreDelegate = (id<GenreSelectionDelegate>)controller;
            [genreDelegate setGenre:_selectedGenre];
        }
        [self.navigationController popViewControllerAnimated:YES];
    }
    

    【讨论】:

      【解决方案4】:

      扩展 Abdul Baseer Khan 的答案:

      对于当前视图控制器可能已经被不同类型的先前视图控制器加载的情况,我们可以使用更安全的as?调用而不是as!,如果控制器不是我们的控制器,它将返回nil正在寻找:

      let previousVC = self.navigationController?.viewControllers.last as? AnExampleController
      previousVC?.doSomething()
      

      虽然,您需要为每个可以加载当前视图控制器的不同视图控制器重复此操作。

      因此,您可能希望改为实现一个协议以分配给所有可能的先前视图控制器:

      protocol PreviousController: UIViewController {
        func doSomething()
      }
      
      class AnExampleController: UIViewController, PreviousController {
        // ...
        func doSomething() {}
      }
      
      class AnotherController: UIViewController, PreviousController {
        // ...
        func doSomething() {}
      }
      
      class CurrentController: UIViewController {
        // ...
        func goBack() {
          let previousVC = self.navigationController?.viewControllers.last as? PreviousController
          previousVC?.doSomething()
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-21
        • 1970-01-01
        • 1970-01-01
        • 2020-05-30
        • 1970-01-01
        • 2017-11-08
        相关资源
        最近更新 更多