1
votes

I'm trying my hand at developing an OSX app. Xcode and Swift are all new to me.

The defaults are all very good at modifying objects when the user changes the window size, but not so good at changing the window size when objects in the view change.

I've seen a couple of examples of recalculating the origin and frame size - I think the math part of it will be straight forward. However, I cannot get a working reference to the NSWindow object. click-drag will not deposit an IBOutlet for the window in any of the .swift files (AppDelegate, ViewController, custom). And typing it in doesn't bind it.

A simplified example of what I am trying to accomplish: Based on user input, change the content of the display, and adjust the window size to encompass the newly modified display. On my main storyboard - Window Controller, segued to - View Controller, containing a Horizontal Slider and a Container view. The container view is segued to - Horizontal Split View Controller, segued to - three repetitive instances of a View Controller.

When the user changes the slider bar, one or more of the three bottom most view controllers will be hidden/unhidden.

The attached pictures show the behavior I am looking for.

Imagine where the text "small group" is, there is a collection of drop down boxes, text boxes, radio buttons, etc.

Slider bar at three, see three groups

Slider bar at two, see two groups

Slider bar at one, see one group

1
I should have mentioned / tagged I am using xcode 7.2. I have found several other solutions that rely on IBOutlet for getting a reference to the window - but I just haven't found a way to make it work. Wondering if it's functionality that was shut down? I imported an example app originally built in 6.x - this very thing prevented it from building. - OldUgly
I don't see how you cannot get a reference to your window. If you create a new project, the app delegate already has an outlet to a window. Compare your project to a new project to see what you're doing wrong. - rocky
@rocky - In the last couple of weeks, I've probably generated a couple of dozen new projects - none have had IBOutlet in the AppDelegate. I just upgraded xcode to 7.3 - no good news. - OldUgly
I found this ... reddit post I tried declaring myWindow as NSWindow and pointing it to NSApp.mainWindow - at runtime it failed, claiming the contents were nil. - OldUgly
I see. Basically, storyboards are something that started in iOS and only quite recently were "ported" to OSX. Traditionally, you could create an app using xibs and (optionally) window controllers. The basic template (no storyboards, non document-based app) gives you an app with a single window owned by the app delegate (as an outlet) and defined in the same xib as the app's main menu. You can add more xibs and NSWindowController subclasses to own those windows if your logic becomes complicated enough. This still works today, if you uncheck "use storyboards" when creating your project. - Nicolas Miari

1 Answers

0
votes

I am answering my own question here - still unable to bind IBOutlet with NSWindow. Anyone with better solutions, please let me know.

Below is a capture of my Main.storyboard. All of the coding is done in the class junkViewController2 that is associated with the 1st view controller.

enter image description here

Here is the code for junkViewController2. I know, it could be more concise ...

//
//  JunkViewController2.swift
//  Scratch1
//

import Cocoa

class JunkViewController2: NSViewController {

    var junkSplitViewController: JunkSplitViewController!
    var myWindow: NSWindow!
    var dy: CGFloat!

    @IBOutlet weak var mySlider: NSSlider!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
        dy = 0.0
    }

    @IBAction func mySlider(sender: NSSlider) {

        let junkSplitViewController = self.childViewControllers[0]
        dy = 0.0
        for controller in junkSplitViewController.childViewControllers {
            if controller.title == "smallGroup1" {
                if mySlider.intValue > 0 {
                    if controller.view.hidden {
                        dy = dy + 30.0
                    }
                    controller.view.hidden = false
                } else {
                    if !controller.view.hidden {
                        dy = dy - 30.0
                    }
                    controller.view.hidden = true
                }
            }
            if controller.title == "smallGroup2" {
                if mySlider.intValue > 1 {
                    if controller.view.hidden {
                        dy = dy + 30.0
                    }
                    controller.view.hidden = false
                } else {
                    if !controller.view.hidden {
                        dy = dy - 30.0
                    }
                    controller.view.hidden = true
                }
            }
            if controller.title == "smallGroup3" {
                if mySlider.intValue > 2 {
                    if controller.view.hidden {
                        dy = dy + 30.0
                    }
                    controller.view.hidden = false
                } else {
                    if !controller.view.hidden {
                        dy = dy - 30.0
                    }
                    controller.view.hidden = true
                }
            }
        }
        resize()
    }

    func resize() {
        var windowFrame = NSApp.mainWindow!.frame
        let oldWidth = windowFrame.size.width
        let oldHeight = windowFrame.size.height
        let old_x = windowFrame.origin.x
        let old_y = windowFrame.origin.y
        let toAdd = CGFloat(dy)
        let newHeight = oldHeight + toAdd
        let new_y = old_y - toAdd
        windowFrame.size = NSMakeSize(oldWidth, newHeight)
        windowFrame.origin = NSMakePoint(old_x, new_y)
        NSApp.mainWindow!.setFrame(windowFrame, display: true)
    }

}