Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace NSViewController under Swift2 Storyboard MAC OSX

I am new to Mac OSX and with Apple promoting the fact that the bodies of code are becoming similar decided to tell the folk I am writing code for we should be able to do a Mac OSX version. iPhone and iPad versions are all good and about to release second version so no issues there.

So I am subclassing NSWindowController to get access to the Toolbar and worked out how to remove and add items on the toolbar, but for the life of me I can not get one NSViewController (firstViewController) to dismiss and bring up the second NSViewController (secondViewController) in the same NSWindowController.

So the 2 issues are that 1. I want to be able to performSegueWithIdentifier from the first NSViewController in code and 2. bring up the second NSViewController by replacing the first NSViewController in the same NSWindowController.

If I add a button to the firstViewController and put a segue to the secondViewController then when I select the button the secondViewController comes up just fine but in a seperate window not the same NSWindowController that I want it to and the firstViewController does not get replaced but stays in the NSWindowController.

So I know the segue idea will work but its not working in code and when I do insert the segue from a button it works but into a seperate NSViewController that is not part of the NSWindowController.

I am trying to find some programming guide from Apple on the issue but no luck so far.

Here is an overview from my Storyboard:

Storyboard overview

Here is my NSWindowController subclassed and the func loginToMe2Team is trigger from the NSToolBar and its working just find as the print statements show up on the console.

import Cocoa

class me2teamWindowsController: NSWindowController {

@IBOutlet var mySignUp : NSToolbarItem!
@IBOutlet var myToolbar : NSToolbar!
let controller =  ViewController()

override func windowDidLoad() {
    super.windowDidLoad()
    print("window loaded")
}

override func windowWillLoad() {
    print("window will load")
}


@IBAction func logInToMe2Team(sender: AnyObject){

    controller.LogIn() //THIS IS THE FUNC I AM TESTING WITH

}

@IBAction func signUpToMe2Team(sender: AnyObject){

    controller.signUp()


}

Here is my NSViewController subclassed with the func LogIn. Its getting selected just fine but the performSegueWithIdentifier is not. And I did cut and past the Identifier to make absolutely sure it was the same.

import Cocoa
import WebKit

class ViewController: NSViewController {

@IBOutlet weak var theWebPage: WebView!
@IBOutlet weak var progressIndicator: NSProgressIndicator!

override func viewDidLoad() {
    super.viewDidLoad()

    let urlString = "https://thewebpage.com.au"
    self.theWebPage.mainFrame.loadRequest(NSURLRequest(URL: NSURL(string: urlString)!))
}

override func viewDidAppear() {
}

func LogIn() {
    print("I logged in")
    self.performSegueWithIdentifier("goToTeamPage", sender: self)
    //THIS IS THE BIT THATS NOT WORKING
}

func signUp() {
    print("I have to sign up now")
}

override var representedObject: AnyObject? {
    didSet {
    }
}

func webView(sender: WebView!, didStartProvisionalLoadForFrame frame: WebFrame!)
{
    self.progressIndicator.startAnimation(self)
}

func webView(sender: WebView!, didFinishLoadForFrame frame: WebFrame!)
{
    self.progressIndicator.stopAnimation(self)
}

}

enter image description here

like image 337
timv Avatar asked Oct 27 '15 01:10

timv


1 Answers

You need to use a custom segue class (or possibly NSTabViewController if it’s enough for your needs). Set the segue’s type to Custom, with your class name specified:

enter image description here

…and implement it. With no animation, it’s simple:

class ReplaceSegue: NSStoryboardSegue {
    override func perform() {
        if let src = self.sourceController as? NSViewController,
           let dest = self.destinationController as? NSViewController,
           let window = src.view.window {
            // this updates the content and adjusts window size
            window.contentViewController = dest
        }
    }
}

In my case, I was using a sheet and wanted to transition to a different sheet with a different size, so I needed to do more:

class ReplaceSheetSegue: NSStoryboardSegue {
    override func perform() {
        if let src = self.sourceController as? NSViewController,
           let dest = self.destinationController as? NSViewController,
           let window = src.view.window {
            // calculate new frame:
            var rect = window.frameRectForContentRect(dest.view.frame)
            rect.origin.x += (src.view.frame.width - dest.view.frame.width) / 2
            rect.origin.y += src.view.frame.height - dest.view.frame.height
            // don’t shrink visible content, prevent minsize from intervening:
            window.contentViewController = nil
            // animate resizing (TODO: crossover blending):
            window.setFrame(window.convertRectToScreen(rect), display: true, animate: true)
            // set new controller
            window.contentViewController = dest
        }
    }
}
like image 91
Václav Slavík Avatar answered Sep 17 '22 18:09

Václav Slavík