ud788 »

Lesson 6 Code Reference Sheet

This outline is intended as a quick way to reference code snippets from this lesson. It includes any code you were expected to write yourself and git branch names for code provided for you.

Picking Images

Launch the image picker:

@IBAction func pickAnImage() {
    let pickerController = UIImagePickerController()
    presentViewController(pickerController, animated: true, completion:nil)
}

Researching the UIImagePickerDelegate

Launch the image picker and set the UIImagePickerControllerDelegate:

@IBAction func pickAnImage(sender: AnyObject) {
    let imagePicker = UIImagePickerController()
    imagePicker.delegate = self
    presentViewController(imagePicker, animated: true, completion: nil)
}

Add two protocols to the ViewController.swift class declaration:

class ViewController: UIViewController, UIImagePickerControllerDelegate,    
UINavigationControllerDelegate {
}

Dismiss the image picker:

dismissViewControllerAnimated(true, completion: nil)

Receiving the image using the delegate pattern

Retrieve the image from the image picker:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
    if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
        imageView.image = image
        dismissViewControllerAnimated(true, completion: nil)
    }
}

What about the camera?

Launching the image picker

The action method connected to the album button in your Meme Editor:

@IBAction func pickAnImageFromAlbum (sender: AnyObject) {
    let imagePicker = UIImagePickerController()
    imagePicker.delegate = self
    presentViewController(imagePicker, animated: true, completion: nil)
}

The action method for the camera button:

@IBAction func pickAnImageFromCamera (sender: AnyObject) {
    let imagePicker = UIImagePickerController()
    imagePicker.delegate = self
    presentViewController(imagePicker, animated: true, completion: nil)
}

Specifying source type

To specify source type, add the following line to the action method connected to the album button in your Meme Editor:

imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary

Add a similar line to the action method connected to the camera button in your Meme Editor:

imagePicker.sourceType = UIImagePickerControllerSourceType.Camera

Disabling the Camera Button

To disable the camera button on devices without cameras, add the following line to viewWillAppear:

cameraButton.enabled = UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)

Working with text attributes

Setting font style and color with textAttributes Configure the text attributes for your meme text fields:

let memeTextAttributes = [
    NSStrokeColorAttributeName : //TODO: Fill in appropriate UIColor,
    NSForegroundColorAttributeName : //TODO: Fill in appropriate UIColor,
    NSFontAttributeName : UIFont(name: "HelveticaNeue-CondensedBlack", size: 40)!,
    NSStrokeWidthAttributeName : //TODO: Fill in appropriate Float 
]

Setting the defaultTextAttributes property:

yourTextField.defaultTextAttributes = memeTextAttributes   
yourOtherTextField.defaultTextAttributes = memeTextAttributes

Move View, Get Out the Way

Subscribe to keyboard notifications in viewWillAppear:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)        
    // Subscribe to keyboard notifications to allow the view to raise when necessary
    subscribeToKeyboardNotifications()
}

Observe UIKeyboardWillShowNotification:

func subscribeToKeyboardNotifications() {
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
}

Shift the view in response to the UIKeyboardWillShowNotification:

    
func keyboardWillShow(notification: NSNotification) {
    if bottomField.isFirstResponder() {
        view.frame.origin.y -= getKeyboardHeight(notification)
    }
}

Get the keyboard height from the notification’s userInfo dictionary:

func getKeyboardHeight(notification: NSNotification) -> CGFloat {
    let userInfo = notification.userInfo
    let keyboardSize = userInfo![UIKeyboardFrameEndUserInfoKey] as NSValue // of CGRect
    return keyboardSize.CGRectValue().height
}

Unsubscribe from keyboard notifications in viewWillDisappear:

// Unsubscribe
override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)       
    unsubscribeFromKeyboardNotifications()
}

Generating a Meme Object

Initialize a Meme model object:

func save() {
    //Create the meme
    var meme = Meme( text: textField.text!, image:       
    imageView.image, memedImage: memedImage) 
}

Combine image and text using an image context to render the view hierarchy as a UIImage:

// Create a UIImage that combines the Image View and the Textfields
func generateMemedImage() -> UIImage {        
    // render view to an image
    UIGraphicsBeginImageContext(view.frame.size)
    view.drawViewHierarchyInRect(view.frame, afterScreenUpdates: true)
    let memedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return memedImage
}

Here’s a good place to hide the toolbar and navigation bar:

// Create a UIImage that combines the Image View and the Textfields
func generateMemedImage() -> UIImage {
    // TODO: Hide toolbar and navbar       

    // render view to an image
    UIGraphicsBeginImageContext(self.view.frame.size)
    view.drawViewHierarchyInRect(self.view.frame, afterScreenUpdates: true)
    let memedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

     // TODO:  Show toolbar and navbar      
    return memedImage
}

Code for using a shared model

Here is the code you will need to access your shared model:

In AppDelegate.swift:

var memes = [Meme]()

In your Meme Editor:

func save() {
    //Create the meme
    var meme = Meme( text: textField.text!, image:       
    imageView.image, memedImage: memedImage()) 

    // Add it to the memes array in the Application Delegate
        (UIApplication.sharedApplication().delegate as  
        AppDelegate).memes.append(meme)
}

In the files governing the Sent Memes Table and Collection Views:

var memes: [Meme]!
override func viewWillAppear() {
    super.viewWillAppear() 
    let object = UIApplication.sharedApplication().delegate as AppDelegate
    let appDelegate = object as AppDelegate
    memes = appDelegate.memes
}

Example code: Tabs & Collection Views

To set up a Tab Bar Controller in the BondVillains app checkout step6.1-bondVillains-noTabs for a project to start with and step6.2-bondVillains-tabs to find the completed code.

Setting up the Sent Memes Collection View

After you’ve set up a custom UICollectionViewCell, implement cellForItemAtIndexPath:

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {    
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier
        ("CustomMemeCell", forIndexPath: indexPath) as CustomMemeCell
        let meme = memes[indexPath.item]
        cell.setText(meme.top, bottomString: meme.bottom)        
        let imageView = UIImageView(image: meme.image)
        cell.backgroundView = imageView

        return cell
    }

Also implement didSelectItemAtIndexPath:; it will look similar to the excerpt below from the BondVillains-MasterDetail app:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {       
     //Grab an instance of the DetailViewController from the storyboard
    let detailController = storyboard!.instantiateViewControllerWithIdentifier
    ("VillainDetailViewController")! as VillainDetailViewController            

    //Populate view controller with data according to the selected cell
    detailController.villain = allVillains[indexPath.row]

    //Present the view controller using navigation
    navigationController!.pushViewController(detailController, animated: true)        
}