Segue 在 macOS 中不起作用
Posted
技术标签:
【中文标题】Segue 在 macOS 中不起作用【英文标题】:Segue doesn't work in 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()
(如果它具有根据文档中的正确声明)。
【参考方案1】:
错误不在代码中。
您必须将 segue 连接到 ViewController
,而不是连接到 WindowController
。
将滑块操作连接到IBAction
(而不是segue)和从ViewController
到SecondViewController
的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:] 进行运行时访问的标识符 基本上可以删除第二个窗口控制器。要在同一窗口中显示第二个视图控制器,请查看 ***.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?)
是否可以用文档中的正确更改。以上是关于Segue 在 macOS 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Unwind segue 在 Swift 3 和 iOS 10 中不起作用