Xcode 6 Storyboard Unwind Segue with Swift Not Con

2019-01-10 07:31发布

When trying to connect a Navigation Bar Button to the Exit item of a ViewController in Xcode 6 (not really sure if it's an Xcode 6 problem but worth mentioning as it is in beta) it does not find the Swift function in the custom class.

Button to Exit with whip

The function it should be finding:

@IBAction func unwindToList(segue: UIStoryboardSegue) {

}

I made another button on the view just to make sure I could get an IBAction working with Swift and that I was writing it correctly. This works fine:

@IBAction func test(sender: AnyObject) {

    NSLog("Test")
}

I have seen this question that seems like the same issue but according to the answers there this should be working.

Xcode 6 is in beta and, of course, Swift is very new, but wanted to see if anyone has come across this before considering it a potential bug.

11条回答
Lonely孤独者°
2楼-- · 2019-01-10 07:53

I had the same problem, also with Xcode Beta 4 at the beginning.. till I found out, that I simply forgot to add the @IBOutlet for the Cancel and Save Buttons in the respective controller. After this, I could connect the buttons with the Exit-Icon :))

查看更多
Fickle 薄情
3楼-- · 2019-01-10 07:55

In Xcode 6 Beta 4 which is available for download, unwind segues and interface builder is supported. I have tested it by myself in a little project.

查看更多
看我几分像从前
4楼-- · 2019-01-10 08:00

This is a known issue with Xcode 6:

Unwind segue actions declared in Swift classes are not recognized by Interface Builder

In order to get around it you need to:

  1. Change class MyViewController to @objc(MyViewController) class MyViewController
  2. Create an Objective-C header file with a category for MyViewController that redeclares the segue action.

    @interface MyViewController (Workaround)
    - (IBAction)unwindToMyViewController: (UIStoryboardSegue *)segue;
    @end
    
  3. In the storyboard, select the instance of MyViewController, clear its custom class, then set it back to MyViewController.

After these steps you are able to connect buttons to the exit item again.

Xcode 6 Release Notes PDF, Page 10

查看更多
干净又极端
5楼-- · 2019-01-10 08:02

It appears that Xcode 6.1 has fixed this issue. You can now set up unwind segues in Swift with the following code:

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

This method - which can remain empty - needs to have a method signature with the UIStoryboardSegue type and not AnyObject or Interface Builder will not see it.

For more detail check the TechNote 2298

查看更多
做个烂人
6楼-- · 2019-01-10 08:02

The answers above rely on ObjC to fix the issue, I have found a pure Swift solution. While adding the segue handler in Swift allowed me to create the unwind segue in Interface Builder (Xcode 6.3), the handler was not being called.

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

So after digging in, the canPerformUnwindSegueAction:fromViewController:withSender from the super class returns false. So I've overridden the implementation, and it works:

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

Update
The code above is incorrect, as I resolved the issue without overriding canPerformUnwindSegueAction:fromViewController:withSender. The fundamental error was to make the distinction between the presenting viewcontroller and the presented viewcontroller.

When an unwind segue is initiated, it must first locate the nearest view controller in the navigation hierarchy which implements the unwind action specified when the unwind segue was created. This view controller becomes the destination of the unwind segue. If no suitable view controller is found, the unwind segue is aborted.
source: Technical Note TN2298

So, define the @IBAction on the presenting viewcontroller, not on the presented view controller. That way the segue will have meaningful values for the properties destinationViewController and sourceViewController as well, being respectively the presenting and presented viewcontroller.

查看更多
在下西门庆
7楼-- · 2019-01-10 08:03

In Swift 2.3 I found the external name of the parameter must be "withUnwindSegue":

@IBAction func unwindToThisView(withUnwindSegue unwindSegue: UIStoryboardSegue) {
    ...
}
查看更多
登录 后发表回答