如何在条件展开 segue 中传递数据?

How to pass data in conditional unwind segue?

我尝试建立一个 rss reader。在 "adding feed" 页面上,如果我点击 "add" 按钮,我希望检查是否已成功添加提要。如果添加,则触发unwind segue,并返回主页面。如果没有添加,则停留在当前页面。

我知道我可以在 "add" 按钮上构建一个 IBAction,并检查是否添加了提要。但是,要添加提要,我需要满足两个要求。

首先,在解析 url 之后,我需要知道解析结果是否可以生成提要。要解析 url,我需要使用 mainViewController 中定义的方法。

其次,我需要检查提要是否已经存在。如果此提要已存在,请不要添加它。要检查这一点,我需要从 mainViewController 获取提要数据。

目前我使用 prepareForSegue 将数据从 main viewController 传递到这个视图。但是对于有条件的展开 segue,我不知道如何传递数据并检查 feed 是否已经存在。因为 prepareForSegue 仅在将要触发 segue 时使用。如果没有触发segue,我无法检查条件。

除了segue,还有其他方法可以从其他视图传递数据吗?

我不知道objective-C,所以如果你能在swift中给我一些解决方案就更好了。 :)

您始终可以使用委托。

在您的添加提要页面中设置一个委托,并让 mainViewController 符合该委托。添加委托方法 (- (BOOL)canGenerateFeed:(NSURL *)url) 和委托 属性 (@property (weak, nonatomic) id <AddFeedControllerDelegate> delegate)。

当您的添加提要页面调用 [self.delegate canGenerateFeed:url] 并且您的 mainViewController 符合委托时,将调用 mainViewController 中的方法(应如方法声明中所述回复 BOOL) .然后您可以相应地回复“是”或“否”,这将被发送回添加提要页面。

正如 Schemetrical 所说,使用委托是访问 MainViewController 中方法的一种简单方法。

既然你把它标记为 Swift,我也会在 Swift 中给你一个委托的小例子。

首先你创建一个协议:

protocol NameOfDelegate: class {     // ":class" isn't mandatory, but it is when you want to set the delegate property to weak
    func someFunction() -> String    // this function has to be implemented in your MainViewController so it can access the properties and other methods in there
}

在您的 MainViewController 中您必须添加:

class MainViewController: UIViewController, NameOfDelegate {

    // your code

    @IBAction func button(sender: UIButton) {
        performSegueWithIdentifier("toOtherViewSegue", sender: self)
    }

    fun someFunction() -> String {
        // access the other methods and return it
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "toOtherViewSegue" {
            let destination = segue.destinationViewController as! OtherViewController
            destination.delegate = self
        }
    }
}

最后一步,您必须添加一个 属性 委托,这样您就可以 "talk" 了。我个人认为 属性 是某种门,位于两个视图控制器之间,因此它们可以相互交谈。

class OtherViewController: UIViewController {

    weak var delegate: NameOfDelegate?

    @IBAction func button(sender: UIButton) {
        if delegate != nil {
            let someString = delegate.someFunction()
        }
    }
}

我假设你使用了 segue 来访问你的另一个 ViewController,因为你在你的 post 中提到了它。这样,您就可以 "talk" 到 MainViewController.

编辑:

至于放松。这也可以通过 segue 来完成。

  1. 添加:@IBAction func unwindToConfigMenu(sender: UIStoryboardSegue) { } 到您的 MainViewController。
  2. 在您的情节提要中,OtherViewController 顶部有 3 个图标。单击内部有正方形的黄色圆形,以确保 ViewController 是 selected 而不是内部的某些元素。
  3. 控制拖动(或鼠标右键拖动)从同一个圆形黄色内有一个正方形到最右边的红色正方形图标。这样做会弹出一个菜单,您可以在其中 select 展开 segue。
  4. 单击您刚刚创建的新 segue。给它一个像 "backToMain"
  5. 这样的标识符
  6. OtherViewController
  7. 中添加类似于以下代码的内容

看来我不能再post任何代码了? :o 稍后再补充。

- (UIViewController*)viewControllerForStoryboardName:(NSString*)storyboardName class:(id)class
{
    UIStoryboard* storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
    NSString* className = nil;

    if ([class isKindOfClass:[NSString class]])
        className = [NSString stringWithFormat:@"%@", class];
    else
        className = [NSString stringWithFormat:@"%s", class_getName([class class])];

    UIViewController* viewController = [storyboard instantiateViewControllerWithIdentifier:[NSString stringWithFormat:@"%@", className]];
    return viewController;
}

// get the view controller
    ViewController* viewController = (ViewController*)[self viewControllerForStoryboardName:@"MyStoryboard" class:[OtherViewController class]];
    // Pass data here
    viewController.data = myData;

// or you can push it
    [self.navigationController pushViewController:viewController animated:YES];