Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transitioning between view controller, OS X

I am trying to write a single window timer application, where when the user presses the start button I want it to show another view controller with countdown etc. I'm also using story board in Xcode, where I have got a segue which connects the start button and the second view controller. However, there are only three different styles i.e. modal, sheet, and pop-over. I want to replace the first view controller the second one in the window. I cannot find a way to do that. I tried using a custom style for the segue, and in that use presentViewController: animator: method but I cannot figure out what to send as the argument for the animator:.

What is the simplest/proper way to transition from one view controller to the other in one window and vice versa?

Also in the storyboard when I select a view controller it shows an attribute called "Presentation" which can be multiple and single, what do those represent?

like image 954
user14492 Avatar asked Feb 11 '15 12:02

user14492


People also ask

How do I switch between view controllers?

From the Library, add a button to the first View Controller and name the button, for example: Show Second View . Select the button, press and hold the Control key on the keyboard and drag from the button to the second View Controller.

How do I segue to another view controller?

Well, in addition to that, Ctrl+dragging also helps set up segues. So, Ctrl+Drag from the “Go to Other View Controller” button, to somewhere in the second View Controller. It can be anywhere in the main box of the second view controller. When you release, it will show you a box like the one below.

How do I change the initial view controller in storyboard?

Specifying the Initial View Controllerstoryboard and select the Tab Bar Controller Scene. On the right, select the Attribute inspector. You'll find a checkbox named Is Initial View Controller. Checking this box will identify the selected view controller as the initial entry point for the storyboard you're on.


1 Answers

I think the simplest way is that swapping contentViewController of NSWindow.

// in NSViewController's subclass @IBAction func someAction(sender: AnyObject) {     let nextViewController = ... // instantiate from storyboard or elsewhere      if let window = view.window where window.styleMask & NSFullScreenWindowMask > 0 {         // adjust view size to current window         nextViewController.view.frame = CGRectMake(0, 0, window.frame.width, window.frame.height)     }      view.window?.contentViewController = nextViewController } 

This is option #1.

If you want to use segue, create custom one and set it to segue class with identifier in IB.

class ReplaceSegue: NSStoryboardSegue {     override func perform() {         if let fromViewController = sourceController as? NSViewController {             if let toViewController = destinationController as? NSViewController {                 // no animation.                 fromViewController.view.window?.contentViewController = toViewController             }         }     } } 

This is option #2.

Last option is using presentViewController:animator: of NSViewController. The code below is custom NSViewControllerPresentationAnimator for dissolve animation.

class ReplacePresentationAnimator: NSObject, NSViewControllerPresentationAnimator {     func animatePresentationOfViewController(viewController: NSViewController, fromViewController: NSViewController) {         if let window = fromViewController.view.window {             NSAnimationContext.runAnimationGroup({ (context) -> Void in                 fromViewController.view.animator().alphaValue = 0             }, completionHandler: { () -> Void in                 viewController.view.alphaValue = 0                 window.contentViewController = viewController                 viewController.view.animator().alphaValue = 1.0             })         }     }      func animateDismissalOfViewController(viewController: NSViewController, fromViewController: NSViewController) {         if let window = viewController.view.window {             NSAnimationContext.runAnimationGroup({ (context) -> Void in                 viewController.view.animator().alphaValue = 0                 }, completionHandler: { () -> Void in                     fromViewController.view.alphaValue = 0                     window.contentViewController = fromViewController                     fromViewController.view.animator().alphaValue = 1.0             })         }             } } 

Then present VC like this.

@IBAction func replaceAction(sender: AnyObject) {     let nextViewController = ... // instantiate from storyboard or elsewhere     presentViewController(nextViewController, animator: ReplacePresentationAnimator()) } 

For dismissal, call presentingViewController's dismissViewController: in the presented VC.

@IBAction func dismissAction(sender: AnyObject) {     presentingViewController?.dismissViewController(self)     } 

Swift4 Version

class ReplacePresentationAnimator: NSObject, NSViewControllerPresentationAnimator { func animatePresentation(of viewController: NSViewController, from fromViewController: NSViewController) {     if let window = fromViewController.view.window {         NSAnimationContext.runAnimationGroup({ (context) -> Void in             fromViewController.view.animator().alphaValue = 0         }, completionHandler: { () -> Void in             viewController.view.alphaValue = 0             window.contentViewController = viewController             viewController.view.animator().alphaValue = 1.0         })     } }  func animateDismissal(of viewController: NSViewController, from fromViewController: NSViewController) {     if let window = viewController.view.window {         NSAnimationContext.runAnimationGroup({ (context) -> Void in             viewController.view.animator().alphaValue = 0         }, completionHandler: { () -> Void in             fromViewController.view.alphaValue = 0             window.contentViewController = fromViewController             fromViewController.view.animator().alphaValue = 1.0         })     } } 

}

Hope this help.

like image 143
bluedome Avatar answered Sep 25 '22 22:09

bluedome