【问题标题】:Segue doesn't work in macOSSegue 在 macOS 中不起作用
【发布时间】:2018-03-25 17:07:32
【问题描述】:

我在ViewController 中有NSSlider,它必须通过Show 类型的segue 将整数值传递给SecondViewController,并在每次移动时更新视图。所以,移动滑块我会在SecondViewController 的窗口中交互地洗牌图像。

我花了一周的时间试图实现NSSlider 这样的行为,但我失败了。也许我在 Interface Builder 中建立了错误的连接。我不知道。如果您知道使NSSlider 用于洗牌图像的任何其他方法,请告诉我。

有关详细信息,请参阅更新的答案。

非常感谢任何帮助!!!

视图控制器

import Cocoa

class ViewController: NSViewController {

    @IBOutlet weak var slider: NSSlider!

    @IBAction func passData(_ sender: NSSlider) {        
        func prepare(for segue: NSStoryboardSegue, sender: NSSlider?) {
            if segue.identifier!.rawValue == "SegueIdentifierForSecondVC" {
                if let secondViewController = segue.destinationController as? SecondViewController {
                    secondViewController.imagesQuantity = slider.intValue 
                }
            }
        }
    }
}

SecondViewController

import Cocoa

class SecondViewController: NSViewController {

    var imagesQuantity: Int = 1

    override func viewWillAppear() {
        super.viewWillAppear()

        print(imagesQuantity)
    }
}

但它不起作用。我的代码有什么问题?

任何帮助表示赞赏。

更新答案

查看控制器

import Cocoa

extension NSStoryboardSegue.Identifier {
    static let secondVC = NSStoryboardSegue.Identifier("SegueIdentifierForSecondVC")
}

class ViewController: NSViewController {

    @IBOutlet weak var slider: NSSlider!

    @IBAction func segueData(_ sender: NSSlider) {
        self.performSegue(withIdentifier: .secondVC, sender: slider)
    }
    override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
        if segue.identifier! == .secondVC {
            if let secondViewController =
                segue.destinationController as? SecondViewController {
                secondViewController?.imagesQty = slider.integerValue 
            }
        }
    }
}

第二视图控制器

import Cocoa

class SecondViewController: NSViewController {

    var imagesQty = 30  

    override func viewWillAppear() {
        super.viewWillAppear()
        //let arrayOfViews: [NSImageView] = [view01...view12]

        let url = URL(fileURLWithPath: NSHomeDirectory()).appendingPathComponent("Desktop/ArrayOfElements")

        do {
            let fileURLs = try FileManager.default.contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: [.skipsHiddenFiles]).reversed()
            let photos = fileURLs.filter { $0.pathExtension == "jpg" }

            for view in arrayOfViews {
                //"imagesQty" is here
                let i = Int(arc4random_uniform(UInt32(imagesQty-1)))
                let image = NSImage(data: try Data(contentsOf: photos[i]))
                view.image = image
            }
        } catch {
            print(error)
        }
    }
}

【问题讨论】:

  • 为什么func prepare(for segue: NSStoryboardSegue, sender: NSSlider?)IBAction 方法中?把它放在外面,然后在里面写self.perform(segue: SegueIdentifierForSecondVC sender:slider)
  • 您似乎对编码有所了解。你没有看到你在另一个里面有一个方法吗? @IBAction func passData(_ sender: NSSlider){}func prepare(for segue: NSStoryboardSegue, sender: NSSlider?) {}@IBAction func passData(_ sender: NSSlider){unc prepare(for segue: NSStoryboardSegue, sender: NSSlider?) {}} 而不是一个接一个?所以在passData() 调用performSegue() 它应该触发prepareForSegue() (如果它具有根据文档中的正确声明)。

标签: swift macos segue swift4 viewcontroller


【解决方案1】:

错误不在代码中。

您必须将 segue 连接到 ViewController,而不是连接到 WindowController

将滑块操作连接到IBAction(而不是segue)和从ViewControllerSecondViewController 的segue(不是从滑块)。

如果第二个视图控制器的类是SecondViewController,它应该在窗口控制器中指明。 SecondVC来自哪里?

再次建议创建NSStoryboardSegue.Identifier的扩展

extension NSStoryboardSegue.Identifier {
    static let secondVC = NSStoryboardSegue.Identifier("SegueIdentifierForSecondVC")
}

并在这两种方法中使用它。并强制转换segue.destinationController。如果一切都正确连接,它一定不会崩溃。

@IBAction func segueData(_ sender: NSSlider) {
    self.performSegue(withIdentifier: .secondVC, sender: nil)
}

override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
    if let identifier = segue.identifier, identifier == .secondVC {
        let secondViewController = segue.destinationController as! SecondViewController
        secondViewController.imagesQty = slider.integerValue
    }
}  

终于NSImage 有了自己的初始化程序,获取一个 URL

let image = NSImage(contentsOf: photos[i])

【讨论】:

  • 但照片仅在关闭/打开第二个窗口后才会更新。如何在不关闭窗口的情况下更新照片?
  • 还有黄色三角形:file:///Users/me/Desktop/Pixie/Pixie/Base.lproj/Main.storyboard:警告:不支持的配置:“辅助窗口控制器”无法访问,因为它没有入口点,也没有通过 -[NSStoryboard instantiateControllerWithIdentifier:] 进行运行时访问的标识符
  • 基本上可以删除第二个窗口控制器。要在同一窗口中显示第二个视图控制器,请查看 stackoverflow.com/questions/28139294/…theiconmaster.com/2015/03/…
  • 我删除了第二个窗口控制器。但是如何实时更新移动滑块的视图呢?
  • 嗯,你可以在 SO 上看到很多真正奇怪的东西 ?
【解决方案2】:
@IBAction func passData(_ sender: NSSlider) {        
    func prepare(for segue: NSStoryboardSegue, sender: NSSlider?) {
        if segue.identifier!.rawValue == "SegueIdentifierForSecondVC" {
            if let secondViewController = segue.destinationController as? SecondViewController {
                secondViewController.imagesQuantity = slider.intValue 
            }
        }
    }
}

应该是

@IBAction func passData(_ sender: NSSlider) {        

}

func prepare(for segue: NSStoryboardSegue, sender: NSSlider?) {
    if segue.identifier!.rawValue == "SegueIdentifierForSecondVC" {
        if let secondViewController = segue.destinationController as? SecondViewController {
            secondViewController.imagesQuantity = slider.intValue 
        }
    }
}

因为你在另一个里面有一个方法,而它们应该是一个接一个。

现在,您需要修改passData(_sender:)。您需要在里面调用performSegue(withIdentifier:sender)
如果将在某个时候触发prepare(for:sender:)。我是在“某个时候”说的,因为在调用 prepare(for:sender:) 之前至少有一个 shouldPerformSegue(withIdentifier:sender:) 调用。

所以现在做:

@IBAction func passData(_ sender: NSSlider) {        
    self.performSegue(withIdentifier: "SegueIdentifierForSecondVC"  sender:nil)
}

【讨论】:

  • prepare(for segue:sender:) 被调用了吗?对于标识符,似乎是正确的,只是我更习惯iOS而不是macOS。它打开什么窗口?第二个VC?新的一个?当您要更新值时,第二个VC 是否已经显示在屏幕上?
  • 滑块打开SecondVC的窗口,不更新值(((
  • 再次:prepare(for segue:sender:) 被调用了吗?你能在里面加一个print()吗?另外,如果被调用,是在print(imagesQuantity)之前还是之后打印?
  • 我想知道func prepare(for segue: NSStoryboardSegue, sender: NSSlider?) { 是否可以用文档中的正确更改。
猜你喜欢
  • 2012-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多