【问题标题】:Xcode 6 Storyboard Unwind Segue with Swift Not Connecting to ExitXcode 6 Storyboard Unwind Segue with Swift Not Connecting to Exit
【发布时间】:2014-07-24 15:21:36
【问题描述】:

当尝试在 Xcode 6 中将导航栏按钮连接到 ViewController 的退出项时(不确定这是否是 Xcode 6 的问题,但值得一提,因为它处于测试阶段)它在自定义中找不到 Swift 函数类。

它应该找到的功能:

@IBAction func unwindToList(segue: UIStoryboardSegue) {

}

我在视图上制作了另一个按钮,以确保我可以让 IBAction 与 Swift 一起使用并且我正在正确编写它。这工作正常:

@IBAction func test(sender: AnyObject) {

    NSLog("Test")
}

我看到this question 似乎是同样的问题,但根据那里的答案,这应该可以工作。

Xcode 6 处于测试阶段,当然,Swift 是非常新的,但在将其视为潜在错误之前,想看看是否有人遇到过这个问题。

【问题讨论】:

  • 请查看 Xcode 发行说明。
  • @JackLawrence 谢谢杰克。那里有一个关于这个的注释,我能够弄清楚。我会在这里更新这个答案。
  • 听起来你也在快速学习苹果的 ToDo 应用教程。这是一个快速工作的版本,以防你卡住:github.com/SimpleAsCouldBe/ios-swift-todo
  • @SimpleAsCouldBe 谢谢,是的,我是。我会看看你的回购。
  • 您好!每个人。我正在使用 Xcode 6.3,我遇到了上面提到的同样的问题。但是对我来说,出口可以识别除我的 ViewController.swift 之外的视图控制器中的 IBAction,即如果用其他视图控制器编写的 IBAction 函数会显示在出口中,但不会显示在 ViewController.swift 中编写的那些。任何帮助将不胜感激!

标签: ios swift xcode uibarbuttonitem


【解决方案1】:

这是 Xcode 6 的一个已知问题:

Interface Builder 无法识别在 Swift 类中声明的展开转场动作

为了绕过它,您需要:

  1. class MyViewController 更改为@objc(MyViewController) class MyViewController
  2. 为 MyViewController 创建一个包含重新声明 segue 操作的类别的 Objective-C 头文件。

    @interface MyViewController (Workaround)
    - (IBAction)unwindToMyViewController: (UIStoryboardSegue *)segue;
    @end
    
  3. 在情节提要中,选择 MyViewController 的实例,清除其自定义类,然后 将其设置回 MyViewController。

完成这些步骤后,您可以再次将按钮连接到退出项目。

Xcode 6 Release NotesPDF,第 10 页

【讨论】:

  • 你说得对,文档确实说这是解决问题的方法,但我似乎无法让它发挥作用。我已经添加了头文件并编辑了 swift 类文件(并重置了视图控制器的自定义类),但似乎没有任何效果。有什么我可能会想念的东西吗?
  • @itsmequinn 我遇到了和你一样的问题。请参阅下面 rajeev 的答案——对我有用。
  • Xcode 发行说明链接不再有效。有谁知道它现在在哪里?
  • @aseba 更新了发行说明链接。
  • 这已在 Xcode 6 GM 中修复。不知道它是否在以前的测试版中工作。
【解决方案2】:

现在可以安装的 Xcode 6 Beta 4 不再使用 Objective-C 解决方法,而是支持在 Interface Builder 中连接展开转场。您现在可以从 iOS 开发中心进行更新。按住 Control 键单击并从要触发 segue 的 UI 项拖动到退出图标,然后在目标视图控制器中放入以下代码后选择函数 unwindToSegue。

@IBAction func unwindToSegue (segue : UIStoryboardSegue) {}

【讨论】:

  • 变通方法中不清楚的一点是展开转场功能必须在展开转场的目标视图中。即它必须在您放松的视图中,而不是您放松的视图中。这让我很失望,但一旦我修复它就可以了。
  • @IBAction func unwindToSegue(segue: UIStoryboardSegue) {} UIUnwindSegue 不可用
  • @Laurent Gorse 在长时间尝试破解此问题后救了我
  • @LaurentGorse 谢谢,如果没有你,我将无法解决它。
  • 真是头疼
【解决方案3】:

我终于可以让它工作了; xcode6 IB 现在真的很脆弱(也经常崩溃)。在将导航栏按钮项连接到退出项之前,我必须重新启动 IDE。我最终重新创建了我的测试项目,并按照上述建议(Xcode 6 Release Notes PDF,第 10 页)让它工作。此外,在添加 .h 文件时,我确保选择了我的项目目标,默认情况下未选中。我还通过 Cocoa Touch Class 模板(与空的 swift 文件)创建了我的控制器 swift 存根。我在导航控制器中使用了模态序列。

ListTableViewController.h

#import <UIKit/UIKit.h>

@interface ListTableViewController
- (IBAction)unwindToList: (UIStoryboardSegue *)segue;
@end

ListTableViewController.swift

import UIKit

@objc(ListTableViewController) class ListTableViewController: UITableViewController {

    @IBAction func unwindToList(s:UIStoryboardSegue) {
        println("hello world");
    }

}

希望对你有帮助

【讨论】:

  • 也为我工作,其他帮助中缺少的是您仍需要在 Swift 文件以及 .h 中声明 @IBAction func unwindToList 的事实
【解决方案4】:

在可供下载的 Xcode 6 Beta 4 中,支持展开转场和界面构建器。我自己在一个小项目中测试过。

【讨论】:

    【解决方案5】:

    在 Swift 2.3 中我发现参数的外部名称必须是“withUnwindSegue”:

    @IBAction func unwindToThisView(withUnwindSegue unwindSegue: UIStoryboardSegue) {
        ...
    }
    

    【讨论】:

    • Xcode 8 中的 Interface Builder 似乎使用 Swift 3 语法(即使是 2.3 项目),所以如果你有 unwindToThisView(unwindSegue:) 它需要 unwindToThisViewWithUnwindSegue: 而不是 unwindToThisView:。我通过将方法重命名为unwindToThisView(_ unwindSegue:) 解决了这个问题
    【解决方案6】:

    Xcode 6.1 似乎已经修复了这个问题。您现在可以使用以下代码在 Swift 中设置展开转场:

    @IBAction func unwindToList(segue: UIStoryboardSegue) {
        // Nothing needed here, maybe a log statement
        // print("\(segue)")
    }
    

    此方法 - 可以保持为空 - 需要具有 UIStoryboardSegue 类型的方法签名,而不是 AnyObject 或 Interface Builder 不会看到它。

    更多详情请查看TechNote 2298

    【讨论】:

    • 是的,但它似乎没有真正连接,即它没有被调用
    • @vim 嗯,这很奇怪。它似乎对我有用。你还记得连接到 IB 中的退出 segue 吗?
    【解决方案7】:

    我遇到了同样的问题,一开始也是 Xcode Beta 4.. 直到我发现,我只是忘记为相应控制器中的取消和保存按钮添加 @IBOutlet。在此之后,我可以将按钮与 Exit-Icon 连接起来:))

    【讨论】:

    • 我在 Beta 4 上并且也有出口,但它仍然不会解除我以模态方式呈现的 segue。有什么想法吗?
    【解决方案8】:

    如果你想放松的总是同一个呈现视图控制器,你总是可以这样做:

    self.navigationController?.popViewControllerAnimated(true)
    

    【讨论】:

      【解决方案9】:

      您可能想要验证您尝试展开的原始控制器目标是否未嵌入到 Container 对象中。 Xcode 6 没有。

      【讨论】:

        【解决方案10】:

        上面的答案依赖于 ObjC 来解决这个问题,我找到了一个纯粹的 Swift 解决方案。虽然在 Swift 中添加 segue 处理程序允许我在 Interface Builder (Xcode 6.3) 中创建 unwind segue,但没有调用处理程序。

        @IBAction func unwindToParent(sender: UIStoryboardSegue) {
            dismissViewControllerAnimated(true, completion: nil)
        }
        

        所以在深入挖掘之后,超类中的canPerformUnwindSegueAction:fromViewController:withSender 返回false。所以我已经覆盖了实现,它可以工作:

        override func canPerformUnwindSegueAction(action: Selector, fromViewController: UIViewController, withSender sender: AnyObject) -> Bool {
            return action == Selector("unwindToParent:")
        }
        

        更新
        上面的代码不正确,因为我在没有覆盖canPerformUnwindSegueAction:fromViewController:withSender 的情况下解决了这个问题。根本的错误在于区分 presenting viewcontroller 和 presented viewcontroller。

        当一个展开转场启动时,它必须首先在导航层次结构中找到最近的视图控制器,该控制器实现在创建展开转场时指定的展开动作。这个视图控制器成为展开转场的目的地。如果找不到合适的视图控制器,则取消展开转场。
        来源:Technical Note TN2298

        所以,在呈现的视图控制器上定义@IBAction,而不是在呈现的视图控制器上。这样,segue 将为属性 destinationViewControllersourceViewController 具有有意义的值,分别是呈现和呈现的视图控制器。

        【讨论】:

        • 是的,将展开放置在呈现视图控制器中是正确的。您也不需要上面显示的dismissViewControllerAnimated。凭借 unwind segue,它会自动处理它。
        【解决方案11】:

        Xcode --version 6.4 斯威夫特 1.2

        @IBAction func backButton(sender: AnyObject) { 解雇视图控制器动画(真,完成:无) }

        【讨论】:

          猜你喜欢
          • 2018-04-06
          • 1970-01-01
          • 2012-11-07
          • 2012-09-29
          • 2016-02-29
          • 1970-01-01
          • 2016-12-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多