Skip to content

Commit

Permalink
Support unwind segues
Browse files Browse the repository at this point in the history
  • Loading branch information
mac-cain13 committed Jan 18, 2016
1 parent c034d11 commit 61c5a70
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 19 deletions.
48 changes: 32 additions & 16 deletions R.swift/Generators/SegueGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,13 @@ struct SegueGenerator: Generator {
let seguesWithInfo = storyboards.flatMap { storyboard in
storyboard.viewControllers.flatMap { viewController in
viewController.segues.flatMap { segue -> SegueWithInfo? in
let destinationViewControllerType = storyboard.viewControllers
.filter { $0.id == segue.destination }
.first?
.type

let destinationViewControllerPlaceholderType = storyboard.viewControllerPlaceholders
.filter { $0.id == segue.destination }
.first
.flatMap { storyboard -> Type? in
switch storyboard.resolveWithStoryboards(storyboards) {
case .CustomBundle: return Type._UIViewController // Not supported, fallback to UIViewController
case let .Resolved(vc): return vc?.type
}
}

guard let destinationType = destinationViewControllerType ?? destinationViewControllerPlaceholderType else {
guard let destinationType = SegueGenerator.resolveDestinationTypeForSegue(
segue,
inViewController: viewController,
inStoryboard: storyboard,
allStoryboards: storyboards)
else
{
warn("Destination view controller with id \(segue.destination) for segue \(segue.identifier) in \(viewController.type) not found in storyboard \(storyboard.name). Is this storyboard corrupt?")
return nil
}
Expand Down Expand Up @@ -74,6 +65,31 @@ struct SegueGenerator: Generator {
)
}

private static func resolveDestinationTypeForSegue(segue: Storyboard.Segue, inViewController: Storyboard.ViewController, inStoryboard storyboard: Storyboard, allStoryboards storyboards: [Storyboard]) -> Type? {
if segue.kind == "unwind" {
return Type._UIViewController
}

let destinationViewControllerType = storyboard.viewControllers
.filter { $0.id == segue.destination }
.first?
.type

let destinationViewControllerPlaceholderType = storyboard.viewControllerPlaceholders
.filter { $0.id == segue.destination }
.first
.flatMap { storyboard -> Type? in
switch storyboard.resolveWithStoryboards(storyboards) {
case .CustomBundle:
return Type._UIViewController // Not supported, fallback to UIViewController
case let .Resolved(vc):
return vc?.type
}
}

return destinationViewControllerType ?? destinationViewControllerPlaceholderType
}

private static func seguesWithInfoForSourceTypeToStruct(seguesWithInfoForSourceType: [SegueWithInfo]) -> Struct? {
guard let sourceType = seguesWithInfoForSourceType.first?.sourceType else { return nil }

Expand Down
9 changes: 6 additions & 3 deletions R.swift/ResourceTypes/Storyboard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ struct Storyboard: WhiteListedExtensionsResourceType, ReusableContainer {
struct Segue {
let identifier: String
let type: Type
let destination: String?
let destination: String
let kind: String
}
}

Expand Down Expand Up @@ -137,11 +138,13 @@ private class StoryboardParserDelegate: NSObject, NSXMLParserDelegate {
warn("Set the segue of class \(customType) with identifier '\(attributeDict["identifier"] ?? "-no identifier-")' to type custom, using segue subclasses with other types can cause crashes on iOS 8 and lower.")
}

if let segueIdentifier = attributeDict["identifier"]
if let segueIdentifier = attributeDict["identifier"],
destination = attributeDict["destination"],
kind = attributeDict["kind"]
{
let type = customType ?? Type._UIStoryboardSegue

let segue = Storyboard.Segue(identifier: segueIdentifier, type: type, destination: attributeDict["destination"])
let segue = Storyboard.Segue(identifier: segueIdentifier, type: type, destination: destination, kind: kind)
currentViewController?.1.addSegue(segue)
}

Expand Down

0 comments on commit 61c5a70

Please sign in to comment.