swiftcocoastoryboardnstoolbarnsslider

How to set NSSlider value in a NSToolbar - Swift Cocoa + Storyboard


I am quite new to Swift programming and I am trying to set a slider min, max and value in a NSToolbar. As an hypothetical exemple, I have a list of client and I want to use the slider in the toolbar to select a client data page. I will firt to load the client database in the NSViewController and count the number of client. Than I would like to set the slider in the toolbar minvalue to 1 and maxvalue to the number of client. I understand how to send slider values from the Windowcontroller to the ViewController but I did not found how to do the inverse , how to send data from the Viewcontroller to the Window controller in order to set the slider values. I have attach an simple code based on this exemple https://github.com/gbdavid2/DavidCodes_macOS/tree/master/NSToolbar%20with%20Storyboards/NSToolbar%20with%20Storyboards

In this exemple, the Toolbar shows a Previous and an Next button that , when clicked, they change a counter value (count). I would like to send back that value from the ViewCoOntroller to the WindowController in order to display it in label and eventually, the slider value in the toolbar. Thanks for your help.

//  WindowController.swift


import Cocoa

class WindowController: NSWindowController {

    @IBOutlet weak var myBoutton: NSToolbarItem!
    
    var viewController: ViewController {
        get {
            return self.window!.contentViewController! as! ViewController
        }
    }
    
    override func windowDidLoad() {
        super.windowDidLoad()
    
        // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
        //viewController.myLabel.stringValue = "boo"
    }
    
    @IBAction func previous(_ sender: Any) {
        viewController.updateMyLabelText(newText: "Prev Button clicked! ")
        }
    
    @IBAction func next(_ sender: Any) {
        viewController.updateMyLabelText(newText: "Next Button clicked! ")
    }

}

import Cocoa

 class ViewController: NSViewController {
    
    var count  : Int = 0
    
    
    @IBOutlet weak var myLabel: NSTextField!
 
    override  func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override  var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }
    
     func updateMyLabelText(newText: String){
        if newText.contains("Prev") {count -= 1}
        else if newText.contains("Next") {count += 1}
        myLabel.stringValue = newText + String(count)
    }


}

Solution

  • Thanks for the proposed solutions. It certainly put me in the wrigth direction.

    Here is what I did. In the WindowController , I set a toolbar with 1) button «previous», 2) button «next» and 3) a slider «slider».

    Those are linked to the proper IBOutler and IBaction in the WindowController. The viewController have a textLabel «myLabel»

    The 2 buttons and the slider change the slider_ptr value in the ViewControler and is sent to myLabel. Also, the slider.label change according to the slider_pointer and the slider_max values. Here is the code for the windowController:

    
    import Cocoa
    
    class WindowController: NSWindowController {
    
     
        @IBOutlet weak var slider: NSSlider!
        @IBOutlet weak var sliderTB: NSToolbarItem!
        
       var viewController: ViewController {
            get {
                return self.window!.contentViewController! as! ViewController
            }
        }
        
        override func windowDidLoad() {
            super.windowDidLoad()
    
            setSlider()   //  set initial value based on ViewController
      
        }
        
     
        
        
        @IBAction func previous(_ sender: Any) {
            
            viewController.previous (WindowController())
            setSlider()
            
            }
        
        @IBAction func next(_ sender: Any) {
            //viewController.updateMyLabelText(newText: "Prev Button clicked! ")
            viewController.next (WindowController())   //send to VC function previous
          // let pt = viewController.slider_ptr + 1
           //let sMax = viewController.slider_max
            setSlider()
            //sliderTB.label = String(pt) + " de " + String(sMax)
        }
        
        
        @IBAction func sliderDidChange(_ sender: Any) {
            
            
            
            viewController.sliderDidSlide (WindowController(), pointer: Int(slider.doubleValue))
            setSlider()
            
        //    viewController.sliderDidSlide(PosiWC(), sValue: myslider.doubleValue)
               
        }
        
    
        func setSlider() {
            
           /* myslider.minValue = 1
            myslider.maxValue = Double(max)
            myslider.integerValue = pointer*/
            
            //print ("WCP58:" , myslider.integerValue )
            
            let pt = viewController.slider_ptr
            let sMax = viewController.slider_max
            //slider (max : pt, pointer: sMax)
            sliderTB.label = String(pt) + " de " + String(sMax)
            
            slider.minValue = 1
            slider.maxValue = Double(sMax)
            slider.integerValue = pt
    
        }
    }
    
    

    and for the Viewcontroller :

     class ViewController: NSViewController {
        
        
        var slider_ptr = 1  // slider position
        var slider_max: Int = 0  //
    
        @IBOutlet weak var myLabel: NSTextField!
     
        override  func viewDidLoad() {
            super.viewDidLoad()
            
           slider_max = 250
           myLabel.stringValue = String(slider_ptr)
            
            
        }
    
        override  var representedObject: Any? {
            didSet {
            }
        }
      
          func previous(_ sender: Any) {          
                 if slider_ptr > 1  {
                      slider_ptr -= 1
                      }
                  else  { NSSound.beep()}
            
            myLabel.stringValue = String(slider_ptr)
            
              }
              
              
         func next(_ sender: Any) {
    
                  if  slider_ptr < slider_max {
                      slider_ptr += 1
    
                  }
                  else  { NSSound.beep()}
                myLabel.stringValue = String(slider_ptr)
              
              }
        
        func sliderDidSlide(_ sender: Any, pointer : Int) {
                    print (pointer)
                    slider_ptr = pointer
                    myLabel.stringValue = String(slider_ptr)
    
                }
    }