【问题标题】:Storyboards and Swift 2.2 Mac App custom segue replace view controllerStoryboards 和 Swift 2.2 Mac App 自定义 segue 替换视图控制器
【发布时间】:2016-07-18 07:27:19
【问题描述】:

我对 Swift 很陌生,虽然有一些编程知识,并且看过关于 Swift 代码的 Udemy 和 Lynda 的东西,但我在从操场转移到 Xcode 项目时有点挣扎。

我还想创建一个 Mac 应用程序,让查找教程变得更加困难。

我也想使用最新的 Swift 和 Storyboard,我想直观地展示它,WWDC 建议 Storyboard 是新 Mac 应用程序的最佳实践,Lister 就是一个很好的例子。

我可以愉快地创建一个按钮并在视图之间使用 segue 移动,但我不想要弹出窗口、模式或工作表,而是实际上替换视图(也就是留在同一个窗口中)所以我假设这是自定义序列或仅编程连接,这是我卡住的地方,没有很多简单的教程涵盖了 Mac 应用程序,它们在讨论 Storyboard 时都转移到了 iOS。如果有人可以提供帮助,那就太好了,我已经创建了我的 Second ViewController,我相信这是支持它的代码,我已将其连接到属性中的 Second ViewController

import Cocoa

class CreateEditView: NSViewController {

    required init?(coder: (NSCoder!)) {
        super.init(coder:coder)
    }

}

再次,示例似乎有所不同,但可能不是 swift 2.2(如果有人也可以解释这段代码实际上在做什么,那也很棒)

【问题讨论】:

    标签: xcode swift osx-elcapitan xcode-storyboard swift2.2


    【解决方案1】:

    我已经在 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 的观点中减少压缩阻力。)

    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。逻辑应该是可移植的,但我不知道某些语法是否发生了变化。

    【讨论】:

      猜你喜欢
      • 2023-03-04
      • 2015-06-22
      • 1970-01-01
      • 1970-01-01
      • 2012-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-24
      相关资源
      最近更新 更多