Wednesday, February 18, 2015

Code Jam : Swift : Working with Segues.

Today we are going to see about Segues. There is a sudden shift from particle effects to segues from my previous blog. That is because I was digging into the Swift book that I have, and found segues to be interesting. Hence shifting gears for this week. 

Segues can be considered as connection between two view controllers, which can be created as easy as click dragging between two view controllers. It seems like creating delegates to get information back might be more difficult. But one thing at a time. 

Note : Optionals are not considered boolean values. Hence if(optional1 != nill) will work and not if(optional1) . 

Step1: In storyboard, click on view controller. I expect things to be interesting, since this is not a new project, and I already have a mini module running. I wonder if the views will be overlay’ed on the existing game. 

Step2: Embed this view controller in a navigation controller. Navigation Controller is a controller that has a stack of view controllers from which they can be pushed and popped. It automatically takes care of bringing in the pushed view controller to display with animations, and taking the existing view controller out of display, with animation when it is popped out. 

Step3: Add a label from objects library (normally at the bottom right side of screen) . Navigation controller does not allow you to add a label to it, because it is the work of view controller. Hence, on the top of the view subwindow single click on Main.Storyboard Base and you would see “Game View Controller scene” and “Navigation Controller Scene”. Chose Game view controller scene and add label to it. Set its text to anything you want. Or if you scroll the view you can see a connection between the navigation controller scene and the view controller scene. Click on the view controller scene and add label to it. 

Step4. In similar way add a bar button to the view controller. 

Step5. Create a second view. File->new->File -> Cocoa touch class that subclasses UIViewController. Chose the language to be Swift. 
Go back to story board, and create a new view controller. Now control+ drag from the bar button to the new view controller, and chose : Action Segue - show. 
In the identity inspector, set the custom class to be view2 (class name of the second view). This step links the view controller in the story board with the new class. 

Step6. Now add label, navigation item, bar button item, and three buttons. Navigation item represents state of the navigation bar including the title. The bar button has to be added to the navigation bar. 


Step 7. Open Assistant editor in Xcode if it is not already there. This editor shows the code for the view controller on a side-by-side  basis, to help with faster and easier code implementation. Control+Click drag the label to the the first empty line in  class view2. This will bring a popup menu showing options to create an Outlet (Links between objects to enable communication between them) or an Outlet Collection (Simply an array of outlets). Object: specifies the view controller. It cannot be changed. Name: provide “textLabel” as name of the outlet, because we are going to change the text of the label with button click. Type: UILabel. This also cannot be changed, because you know, it is a label. Storage: Weak is the default option for outlets, except for those from File Owner’s to top level objects in nib file or in iOS a storyboard scene, which should be strong as per Apple Docs (https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html#//apple_ref/doc/uid/10000051i-CH4-SW6)

Normally strong outlets are used by framework classes like UIViewController’s view outlet or NSWindowController’s window outlet. They should be generally weak because normally they do not own the objects in subviews of view controller or windows’ controller. 

I am going to set the storage as strong because this outlet is in iOS storyboard scene, and from the docs it looks like the right thing to do. 

Click on “Connect”. This creates following line inside the class 
class GameViewController: UIViewController {
    @IBOutlet var TextLabel: UILabel!

Step8. Similarly control drag from the bar button to the view2 class, and create an action. 

Step9. Similarly command+select all three color buttons and control drag them to view2 class. Create an action for UIButton. Inside this color button action function, add the code to change the label of the text to that of the button title. 
labelOutlet.text = sender.titleLabel!.text!

Step10. In ViewDidLoad() function add this line to set the label’s text in the beginning. 
labelOutlet.text = colorString. 
Create a var colorString =“” as global member in the view2 class. 

Here is code snippet for view2 class:
class view3: UIViewController {
    @IBOutlet var labelOutlet: UILabel!
    var colorString = "new"
    @IBAction func greenAction(sender: UIButton, forEvent event: UIEvent) {
        labelOutlet.text = sender.titleLabel!.text!
    }
    @IBAction func bbuttonaction(sender: UIBarButtonItem) {
    }
    @IBAction func blueaction(sender: UIButton) {
        labelOutlet.text = sender.titleLabel!.text
    }
    @IBAction func redaction(sender: UIButton) {
        labelOutlet.text = sender.titleLabel!.text
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        labelOutlet.text = colorString;

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

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.

    }
 }


Here is code from the first view:
class ViewController: UIViewController {

    @IBOutlet var colorLabel: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

And here is how the story board looks like. 
It has default names. You can set the names of the labels to whatever you might like. 

Data via Segue:

Now that a segue connection has been made, data needs to be passed from one view to the other via the segue.

Step1. For this purpose, prepareForSegue has to be overridden. Start typing prepareForSegue in the first view class, and XCode automatically fills in the override keyword and function signature for you. 

Step2. Set the identifier name of the segue in attributes inspector as “mySegue"

Step3. Inside prepareForSegue write this line of code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "mySegue"{
            let vc = segue.destinationViewController as view3
            vc.colorString = colorLabel.text! // color label is the outlet for the label.
        }
    }

UIStoryboardSegue object is responsible for transitioning between view controllers. It also prepares the target view with data from the first view. 

When you hit run, text label from the first view is passed on to the second view when segue activates during navigation bar button press/touch by user. 



Code Jam for the week of Feb 9

No comments:

Post a Comment