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

Posted

技术标签:

【中文标题】如何在条件展开序列中传递数据?【英文标题】:How to pass data in conditional unwind segue? 【发布时间】:2015-04-12 05:27:21 【问题描述】:

我尝试构建一个 rss 阅读器。在“添加提要”页面,如果我点击“添加”按钮,我希望检查提要是否添加成功。如果添加了,则触发 unwind segue,并返回主页面。如果没有添加,则停留在当前页面。

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

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

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

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

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

我不知道objective-C,所以如果你能快速给我一些解决方案会更好。 :)

【问题讨论】:

【参考方案1】:

就像 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
        
    

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

class OtherViewController: UIViewController 

    weak var delegate: NameOfDelegate?

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

我假设您使用 segue 来访问您的其他 ViewController,因为您在帖子中提到了它。这样,您就可以与 MainViewController 进行“对话”。

编辑:

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

    将:@IBAction func unwindToConfigMenu(sender: UIStoryboardSegue) 添加到您的 MainViewController。 在您的故事板中,OtherViewController 的顶部有 3 个图标。点击里面有一个正方形的圆形黄色,确保选择了 ViewController 而不是里面的一些元素。 控制拖动(或鼠标右键拖动)从带有正方形的同一圆形黄色到最右侧的红色方形图标。这样做会弹出一个菜单,您可以在其中选择展开转场。 单击刚刚创建的新转场。给它一个标识符,如“backToMain” 将类似于以下代码的内容添加到OtherViewController

看来我不能再发布任何代码了? :o 稍后会添加。

【讨论】:

感谢您的回答!我在网上阅读了很多关于委托的文档,但仍然无法理解这个概念。我有一些疑问。 1.我应该在哪里定义协议?在 mainViewController 或 addFeed 页面?你的答案与@Schemetrical 不同,所以我不确定。 2.destination.delegate = self是什么意思? self 表示 mianViewControlleraddFeedViewController 我自己想通了。非常感谢! 嘿,为了确定我会回答以下问题: 1. 在类声明之外。在哪个文件中并不重要,因为它是全局可访问的。 2. 在我的例子中,self 表示它所使用的类的实例。引用:this, self, and Me are keywords used in some computer programming languages to refer to the object, class, or other entity that the currently-running code is part of. 自从我不久前开始学习 swift 并尝试通过帮助他人来改进它以来,请随时问我任何问题 :) 哦,顺便说一句,如果我的回答回答了你的问题,请将其标记为已回答 :)【参考方案2】:

您始终可以使用委托。

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

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

【讨论】:

您好 Schemetrical,您的回答很有帮助。谢谢!【参考方案3】:
- (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];

【讨论】:

以上是关于如何在条件展开序列中传递数据?的主要内容,如果未能解决你的问题,请参考以下文章

对象的传递为啥要 序列化 呢

如何通过具有不可序列化数据的意图传递数组或数组列表?

向后传递数据时,在展开可选值时意外发现 nil

如何传递 WebAPI 控制器数据,以便发布模型在绑定/反序列化或验证时可以访问

如何在WebAPI的控制器的GET请求中传递参数

android activity之间传递对象 对象为啥要序列化