How to work with IBDesignable and IBInspectable in Swift Language?

IBDesignable with Storyboard
IBDesignable with Storyboard

How to use the @IBDesignable and @IBInspectable?

By giving you a simple example that we can not change the corner radius from the design view. We have to change it run time. If you want to make possible it with design time then you can use the @IBDesignable and @IBInspectable.

So, We are taking an example as IBButtonExtender for this the functionality

  • Border Color
  • Border Width
  • Corner Radius

Create an Custom Class for UIButton with @IBDesignable

Create an @IBInspectable for Inspect the element. the Border Color property will be added to the list in the right panel when you create button with this class.

Set Initialization functions and other @IBInspectable as above.

You can check the code for the ButtonExtender.swift

IBButtonExtender

Presenting the ButtonExtender for Border Color, Border Width and Corner Radius function with the @IBDesignable and @IBInspectable in the Swift Language.

By making some corner radius and colors, You will get neat and clean output.

Output
Output

Github

Find IBButtonExtender on github 🙂

Check other articles on Swift Language.

All suggestions are acceptable. Put it in the comments!

Happy Coding 🙂

How to work with WatchKit in Swift Language – iOS 8 #Tutorial #CounterWithWatch

Apple Watch represents a new chapter in the relationship people have with technology. Now you can deliver innovative new experiences to your customers on their wrist. And by adding WatchKit, you can take your apps even further by extending and enhancing their functionality on Apple Watch.

Lets learn how to work with WatchKit by an Counter Example.

Counter Watch Example
Counter Watch

Create New Project in XCode with Swift Language

New Project
New Project

Add Apple Watch Target in your Application

Add Target
Add Target

Select Apple Watch Target

Add Target Apple Watch
Add Target Apple Watch

Select Options for Target

Target Options
Target Options

Storyborad of watch

By adding target you will find the InterfaceController.swift and Interface.storyboard

Storyboard And Swift Files
Storyboard And Swift Files

Design watch with the controls

Design and reposition the controls with the properties of controls.

Design Controls in Watch
Design Controls in Watch

Now Time to do some code and connect the outlets

Connect Outlets
Connect Outlets

Code:

//  InterfaceController.swift

import WatchKit
import Foundation


class InterfaceController: WKInterfaceController {

    @IBOutlet weak var lblCounter: WKInterfaceLabel!
    var counter:Int = 0

    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)
        
        // Configure interface objects here.
    }

    override func willActivate() {
        // This method is called when watch view controller is about to be visible to user
        super.willActivate()
    }

    override func didDeactivate() {
        // This method is called when watch view controller is no longer visible
        super.didDeactivate()
    }
    
    @IBAction func upButtonPressed() {
        counter = counter + 1
        lblCounter.setText("\(counter)")
    }
    
    @IBAction func downButtonPressed() {
        counter = counter - 1
        lblCounter.setText("\(counter)")
    }
}

Download project with this stuff AppleWatchCounterDemo.zip

Thanks!

Happy Coding 😀

Passing data with Unwind Segue in Swift Language – iOS 8

Unwind Segue Data
Unwind Segue Data

We have learn about Work with Unwind Segue in Swift Language – iOS 8 in first tutorial. Now we will learn how to pass the data with unwind segue.

It just simple.

Continue with the same example project.

Take data variables which you want to get in the parent view.

For example,

class ViewController2: UIViewController {
    var data:String = "view 2 data"
    ....
}

To get data from first view controller we have to get data from source view controller like follows :

    @IBAction func unwindToVC(segue:UIStoryboardSegue) {
        if(segue.sourceViewController .isKindOfClass(ViewController2))
        {
            var view2:ViewController2 = segue.sourceViewController as ViewController2
            let alert = UIAlertView()
            alert.title = "UnwindSegue Data"
            alert.message = view2.data
            alert.addButtonWithTitle("Ok")
            alert.show()
        }
        if(segue.sourceViewController .isKindOfClass(ViewController3))
        {
            var view3:ViewController3 = segue.sourceViewController as ViewController3
            let alert = UIAlertView()
            alert.title = "UnwindSegue Data"
            alert.message = view3.data
            alert.addButtonWithTitle("Ok")
            alert.show()
        }
    }

Download project with this stuff UnwindSegueData.zip

Thanks!

Happy Coding 😀

Work with Unwind Segue in Swift Language – iOS 8

Unwind - Exit
Unwind – Exit

An unwind segue (sometimes called exit segue) can be used to navigate back through push, modal or popover segues (as if you popped the navigation item from the navigation bar, closed the popover or dismissed the modally presented view controller). On top of that you can actually unwind through not only one but a series of push/modal/popover segues, e.g. “go back” multiple steps in your navigation hierarchy with a single unwind action.

To enable the Unwind Segue you need to add some code first.

@IBAction func unwindToVC(segue: UIStoryboardSegue) {
}

You have to add this code in the view controller where you want to unwind (came back).

Unwind To View
Unwind To View

Suppose you want to came back from second or third view to first view then you have to add the code in first view.

Then just connect any control(Which contains action) with the unwind segue.

Unwind Segue
Unwind Segue

For check the particular view controller by unwind segue, use following code :

    @IBAction func unwindToVC(segue:UIStoryboardSegue) {
        if(segue.sourceViewController .isKindOfClass(ViewController2))
        {
            let alert = UIAlertView()
            alert.title = "UnwindSegue"
            alert.message = "Unwind from view 2"
            alert.addButtonWithTitle("Ok")
            alert.show()
        }
        if(segue.sourceViewController .isKindOfClass(ViewController3))
        {
            let alert = UIAlertView()
            alert.title = "UnwindSegue"
            alert.message = "Unwind from view 3"
            alert.addButtonWithTitle("Ok")
            alert.show()
        }
    }

Download project with this stuff UnwindSegue.zip

In next tutorial you will find the topic Passing data with Unwind Segue in Swift Language – iOS 8

Thanks!

Happy Coding 😀

Google Place Autocomplete View With Swift Language through Alamofire networking library

Google Place Autocomplete
Google Place Autocomplete

Add the Alamofire CocoaPods in your swift project.

alamofire
alamofire

Find your Google place API key on Google APIs Console.

GOOGLE PLACE API KEY
GOOGLE PLACE API KEY

ViewConroller.swift

import UIKit

class ViewController: UIViewController {
  override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    let gpaViewController = GooglePlacesAutocomplete(
      apiKey: "YOUR API KEY",
      placeType: .Address
    )

    gpaViewController.placeDelegate = self

    presentViewController(gpaViewController, animated: true, completion: nil)
  }
}

extension ViewController: GooglePlacesAutocompleteDelegate {
  func placeSelected(place: Place) {
    println(place.description)
  }

  func placeViewClosed() {
    dismissViewControllerAnimated(true, completion: nil)
  }
}

GooglePlacesAutocomplete.xib

GooglePlacesAutocomplete.xib
GooglePlacesAutocomplete.xib

GooglePlacesAutocomplete.swift

import UIKit
import Alamofire

enum PlaceType: Printable {
  case All
  case Geocode
  case Address
  case Establishment
  case Regions
  case Cities

  var description : String {
    switch self {
    case .All: return ""
    case .Geocode: return "geocode"
    case .Address: return "address"
    case .Establishment: return "establishment"
    case .Regions: return "regions"
    case .Cities: return "cities"
    }
  }
}

struct Place {
  let id: String
  let description: String
}

protocol GooglePlacesAutocompleteDelegate {
  func placeSelected(place: Place)
  func placeViewClosed()
}

// MARK: - GooglePlacesAutocomplete
class GooglePlacesAutocomplete: UINavigationController {
  var gpaViewController: GooglePlacesAutocompleteContainer?

  var placeDelegate: GooglePlacesAutocompleteDelegate? {
    get { return gpaViewController?.delegate }
    set { gpaViewController?.delegate = newValue }
  }

  convenience init(apiKey: String, placeType: PlaceType = .All) {
    let gpaViewController = GooglePlacesAutocompleteContainer(
      apiKey: apiKey,
      placeType: placeType
    )

    self.init(rootViewController: gpaViewController)
    self.gpaViewController = gpaViewController

    let closeButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Stop, target: self, action: "close")

    gpaViewController.navigationItem.leftBarButtonItem = closeButton
    gpaViewController.navigationItem.title = "Enter Address"
  }

  func close() {
    placeDelegate?.placeViewClosed()
  }
}

// MARK: - GooglePlaceSearchDisplayController
class GooglePlaceSearchDisplayController: UISearchDisplayController {
  override func setActive(visible: Bool, animated: Bool) {
    if active == visible { return }

    searchContentsController.navigationController?.navigationBarHidden = true
    super.setActive(visible, animated: animated)

    searchContentsController.navigationController?.navigationBarHidden = false

    if visible {
      searchBar.becomeFirstResponder()
    } else {
      searchBar.resignFirstResponder()
    }
  }
}

// MARK: - GooglePlacesAutocompleteContainer
class GooglePlacesAutocompleteContainer: UIViewController {
  var delegate: GooglePlacesAutocompleteDelegate?
  var apiKey: String?
  var places = [Place]()
  var placeType: PlaceType = .All

  convenience init(apiKey: String, placeType: PlaceType = .All) {
    self.init(nibName: "GooglePlacesAutocomplete", bundle: nil)
    self.apiKey = apiKey
    self.placeType = placeType
  }

  override func viewDidLoad() {
    super.viewDidLoad()

    let tv: UITableView? = searchDisplayController?.searchResultsTableView
    tv?.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
  }
}

// MARK: - GooglePlacesAutocompleteContainer (UITableViewDataSource / UITableViewDelegate)
extension GooglePlacesAutocompleteContainer: UITableViewDataSource, UITableViewDelegate {
  func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return places.count
  }

  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = self.searchDisplayController?.searchResultsTableView?.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell

    // Get the corresponding candy from our candies array
    let place = self.places[indexPath.row]

    // Configure the cell
    cell.textLabel.text = place.description
    cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator

    return cell
  }

  func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    delegate?.placeSelected(self.places[indexPath.row])
  }
}

// MARK: - GooglePlacesAutocompleteContainer (UISearchDisplayDelegate)
extension GooglePlacesAutocompleteContainer: UISearchDisplayDelegate {
  func searchDisplayController(controller: UISearchDisplayController, shouldReloadTableForSearchString searchString: String!) -> Bool {
    getPlaces(searchString)
    return false
  }

  private func getPlaces(searchString: String) {
    Alamofire.request(.GET,
      "https://maps.googleapis.com/maps/api/place/autocomplete/json",
      parameters: [
        "input": searchString,
        "type": "(\(placeType.description))",
        "key": apiKey ?? ""
      ]).responseJSON { request, response, json, error in
        if let response = json as? NSDictionary {
          if let predictions = response["predictions"] as? Array<AnyObject> {
            self.places = predictions.map { (prediction: AnyObject) -> Place in
              return Place(
                id: prediction["id"] as String,
                description: prediction["description"] as String
              )
            }
          }
        }

        self.searchDisplayController?.searchResultsTableView?.reloadData()
    }
  }
}

I have learned this thing from Howard Wilson’s(watsonbox) Github Repository : watsonbox/ios_google_places_autocomplete

Happy coding 🙂