I have NSSlider
in ViewController
that must pass integer value to SecondViewController
via segue of type Show
and update a View every time I move it. So, moving slider I interactively shuffle images in SecondViewController
's window.
I spent a week trying to implement such a behaviour of NSSlider
but I failed. Maybe I made wrong connections in Interface Builder. I don't know. If you know any other method to make NSSlider
work for shuffling images, tell me, please.
See updated answer for detailed information.
Really appreciate any help!!!
ViewController
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)
}
}
But it doesn't work. What's wrong in my code?
Any help appreciated.
UPDATED ANSWER
VIEW CONTROLLER
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
}
}
}
}
SECOND VIEW CONTROLLER
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)
}
}
}
The mistake is not in the code.
You have to connect the segue to the
ViewController
, not to theWindowController
.Connect the slider action to the
IBAction
(not to the segue) and the segue fromViewController
toSecondViewController
(not from the slider).And if the class of the second view controller is
SecondViewController
it should be indicated in the window controller. Where doesSecondVC
come from?And once again the suggestion to create an extension of
NSStoryboardSegue.Identifier
and to use it in these two methods. And force cast the
segue.destinationController
. It must not crash if everything is hooked up properly.Finally
NSImage
got its own initializer taking an URLShould be
Because you have a method inside another while they should be one after the other.
Now, you need to modify
passData(_sender:)
. You need to call insideperformSegue(withIdentifier:sender)
inside it.If will trigger at some point
prepare(for:sender:)
. I'm saying at "some point" because there is at least ashouldPerformSegue(withIdentifier:sender:)
call before theprepare(for:sender:)
is called.So now do: