我已经在 Objective-C 中完成了这种类型的自定义 segue,但这并不容易……而且获得正确的约束更糟糕。在 Apple 发现视图控制器不一定需要自己的窗口之前,我建议使用容器视图。
对于这个例子,我设置了ViewController
一个容器视图,并FirstContained
在情节提要中将一个视图控制器链接到它。它有一个“下一步”按钮。
@IBAction func goToNext(sender: NSButton) {
NSNotificationCenter.defaultCenter().postNotificationName(ViewController.SecondController, object: nil)
}
我在情节提要中创建了一个SecondContained
视图控制器,并给它一个标识符“second_contained”。它有一个“返回”按钮。
@IBAction func goBack(sender: NSButton) {
NSNotificationCenter.defaultCenter().postNotificationName(ViewController.FirstController, object: nil)
}
为过渡做所有的ViewController
工作。SecondContained
(请注意,获得正确的约束仍然需要一些努力。从减少's view中的压缩阻力开始。)
import Cocoa
class ViewController: NSViewController {
static let FirstController = "FirstController"
static let SecondController = "SecondController"
@IBOutlet weak var container: NSView!
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "firstSelected:", name: ViewController.FirstController, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "secondSelected:", name: ViewController.SecondController, object: nil)
// This puts the "SecondContained" controller at location zero in the childViewControllers array.
let storyboard = NSStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateControllerWithIdentifier("second_contained") as? SecondContained
if let second = controller {
addChildViewController(second)
}
}
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func removePreviousView() {
if let oldView: NSView = container.subviews[0] {
oldView.removeFromSuperview()
} else {
print("No previous view found")
}
}
// This is a hack.
// It would be better to search for the controller by a reliable identifier rather than a number.
func useController(offset: Int) {
guard childViewControllers.count > offset else {
print("Bad offset \(offset) for \(childViewControllers.count)-long array")
return
}
if let controller: NSViewController = childViewControllers[offset] {
container.addSubview(controller.view)
} else {
print("No view controller!?")
}
}
func firstSelected(notification: NSNotification) {
removePreviousView()
useController(1)
}
func secondSelected(notification: NSNotification) {
removePreviousView()
useController(0)
}
}
请注意,这是 Swift 2.1。逻辑应该是可移植的,但我不知道某些语法是否发生了变化。