Dismissing View Controller for osx - xcode

I'm trying to learn swift code for mac OSX but there isn't much tutorials for it as ios. and i have been struggling already with closing or dismissing the view controller when i launch through a button another connected view controller
class ViewController: NSViewController {
#IBOutlet weak var username: NSTextField!
#IBOutlet weak var password: NSTextField!
#IBAction func login(sender: AnyObject) {
}
#IBAction func signUp(sender: AnyObject) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
}
I tried to add [self dismissModalViewControllerAnimated:YES]; to dismiss it but it doesn't work it only shows errors. if anybody could point me to somewhere i can get more information or what i'm doing wrong?

Use
dismissViewController(self)
to dismiss the presented view controller.
About dismissViewController: from the NSViewController docs:
Dismisses a presented view controller, using the same animator that presented it.
and
In OS X, this is the universal way to dismiss a view controller, no matter how it was presented.

Related

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:
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)
}
}
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:
…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
}
}
}

Access an IBOutlet from another class in Swift

I'm new to Swift and Mac App.
So I'm writing an Mac App today and I still confuse how to access an IBOutlet from another class after searching a lot.
I'm using StoryBoard and there are two NSTextField path mirror in my ViewController.
I have created a custom class Path.swift for the first NSTextField path to know when the text in path has changed.
class Path: NSTextField, NSTextFieldDelegate
{
override func drawRect(dirtyRect: NSRect)
{
super.drawRect(dirtyRect)
// Drawing code here.
self.delegate = self
}
var current = ""
override func controlTextDidChange(obj: NSNotification)
{
current = self.stringValue
println("Current is \(current)")
}
}
And there are two outlets defined in ViewController.swift
class ViewController: NSViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
#IBOutlet weak var path: NSTextField!
#IBOutlet weak var mirror: NSTextField!
}
And when user type something in the first NSTextField path, I want the second NSTextField mirror shows the same string as path.
I tried to use ViewController().mirror.stringValue = current, but I got fatal error: unexpectedly found nil while unwrapping an Optional value
After googling a lot, I knew that I have created a new instance of ViewController instead of accessing the current existing instance of ViewController.
So my question is how I can access the IBOutlet in ViewController.swift from Path.swift class (how to access the current existing instance of ViewController).
Any help will be greatly appreciated.
Thanks in advance.

Trigger Segue Artificially

I am trying to pass data between two viewContollers in an OS X storyboard application using Swift. When I press a button on VC1, it opens VC2, and prepareForSegue is run. However, I can't pass data back to VC1 because a. prepareForSegue isn't being run (because a window isn't being opened) and b. because even if it were, VC1 doesn't know data is being sent and I can't figure out a function (something like viewDidBecomeFocus, if such a function existed) to let it know to look. I feel like there must be a way to do this.
If you know of a way to do this in IOS but not OSX, it could still be useful.
Thanks!
Let assume that in your first ViewController you have one label and one button. When pressed, that button open popover (SecondViewController) with one textfield (and one button what says ready or close etc.), where you want take its value and assign it to your label. That is where delegates and protocols come handy.
SecondViewController:
#objc protocol TextDelegate {
func passedString(textValue: String)
}
class SecondViewController: NSViewController {
#IBOutlet weak var textField: NSTextField!
weak var delegate: TextDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
}
#IBAction func closePopOver(sender: AnyObject) {
if delegate != nil {
delegate!.passedString(textField.stringValue)
}
self.dismissViewController(self)
}
}
This is ViewController:
#IBOutlet weak var myLabel: NSTextField!
override func prepareForSegue(segue: NSStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "mySegue" {
let vc = segue.destinationController as! SecondViewController
vc.delegate = self
}
}
func passedString(textValue: String) {
myLabel.stringValue = textValue
}

Setting Label text in swift

My first question here. I'm making the jump from Delphi and Pascal to Xcode and Swift and feeling totally overwhelmed by the change.
I'm simply attempting to change the text of a label when a button is clicked. Here is my code from ViewController.swift
import Cocoa
class ViewController: NSViewController {
#IBOutlet weak var Label1: NSTextField!
#IBOutlet weak var ChangeText: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func ButtonPressed(sender: AnyObject) {
Label1.stringValue = "Hello World"
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
When I run the application as soon as I click the button the application hangs.
I've also tried exchanging stringValue with text but NSTextField does not use this. I can't seem to make the label show up as UITextField.
What am I doing wrong?

Changing image of UIButton via click - XCode 6 Swift

Im simply trying to make it so when I click on a UIButton (for which it currently shows the image of a shell), the image changes into something else (in this case, a coin).
This is what i tried so far and have not had any success. I cant find anything to do this for Swift.Thanks.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var lblOutput: UILabel!
#IBOutlet weak var lblWin: UILabel!
#IBOutlet weak var lblLost: UILabel!
#IBOutlet weak var lblWinsAmt: UILabel!
#IBOutlet weak var lblLossesAmt: UILabel!
let coin = UIImage(named: "penny_head") as UIImage;
override func viewDidLoad() {
super.viewDidLoad()
//imgShell1.hidden = true //doesnt work
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func btnStart(sender: UIButton) {
}
#IBAction func btnShell1(sender: UIButton) {
sender.setImage(coin,forState: UIControlState.Highlighted);
}
The way you're setting up the control is incorrect. Assuming you have a button property named btnShell (and it's the button you want to setup) change your viewDidLoad() method to:
override func viewDidLoad()
{
super.viewDidLoad()
btnShell.setImage(imgShell1, forState:.Normal);
btnShell.setImage(coin, forState:.Highlighted);
}
And then remove the setImage(_:forState:) call from the action method:
#IBAction func btnShell1(sender: UIButton) {
sender.setImage(coin,forState: UIControlState.Highlighted);
}
To permanently change the button image on tap, you have to use the .Normal enum case and not .Highlighted for the control state:
sender.setImage(coin,forState: UIControlState.Normal)
Setting the image for the .Highlighted state makes the new image appear only when the button is in that state, i.e. when it is tapped.
If you are looking to change the UIButton's background image permanently you have to use Antonio's method:
sender.setImage(coin,forState: UIControlState.Normal)
This won't change the UIKit's default highlighting when you tap the button. When you don't want the button to be highlighted when you touch it or have different appearances for different states, then you might be better off using an UIImageView.
In viewDidLoad():
imgView?.image = imgOne
imgView?.userInteractionEnabled = true
imgView?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "changeImage:"))
The function that changes the image:
func changeImage(recognizer: UITapGestureRecognizer){
self.imgView?.image = imgTwo
}
You can also use isSelected.
button.setImage(image2, for: .normal)
button.setImage(image1, for: .selected)

Resources