Swift - 使用popViewController并将数据传递给您要返回的ViewController

时间:2015-06-22 03:20:38

标签: swift ios8 uinavigationcontroller

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

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

最好的方法是什么?我不使用故事板,如果这对你的答案很重要。

感谢您的帮助

4 个答案:

答案 0 :(得分:15)

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

S -> BAC A -> AaB | ε C -> CcB | ε B -> Bb | ε 中,在类声明之上,添加以下代码:

SecondViewController

然后在protocol SecondVCDelegate { func didFinishSecondVC(controller: SecondViewController) } 内添加一个类变量:

SecondViewContoller

然后在你的按钮所针对的函数内部添加:

var delegate: MeditationVCDelegate! = nil

我们在这里做的是在self.navigationController?.popViewControllerAnimated(true) delegate.didFinishSecondVC(self) 中进行弹出,而不是传递任何数据,但由于我们已经定义了协议,我们将在SecondViewController来处理数据。

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

ViewController

您需要添加我们在新协议中定义的函数,以使编译器满意。在class ViewController: UIViewController, SecondVCDelegate { ... your code... } 的课程内,添加:

ViewController

在我们调用func didFinishSecondVC(controller: SecondViewController) { self.myBoolVar = true controller.navigationController?.popViewControllerAnimated(true) } 的{​​{1}}中,我们在SecondViewController类中调用此方法,我们正在弹出的控制器。这与我们在didFinishSecondVC中编写此代码类似,但我们在ViewController内编写了代码,我们正在使用委托管理两者之间的消息传递。

最后,在SecondViewController中,在我们定位推送ViewController的函数中,添加以下代码:

ViewController

就是这样!您应该设置为在不使用故事板的情况下在两个视图控制器之间传递代码!

答案 1 :(得分:10)

_ = self.navigationController?.popViewController(animated: true)
        let previousViewController = self.navigationController?.viewControllers.last as! PreviousViewController
        previousViewController.PropertyOrMethod

答案 2 :(得分:0)

我在寻找方法的同时遇到了这个问题。由于我经常使用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];
}

答案 3 :(得分:0)

扩展阿卜杜勒·巴塞尔·汗的答案:

对于当前视图控制器可能已由不同类型的先前视图控制器加载的情况,我们可以使用更安全的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()
  }
}