Rainbows Part 2 - Saving Preferences and Showing Views

Login to Access Code

Login to access video

In part 1 we created the views and layout for the Onboarding functionality. In this second part, we will save a preference so we only show Onboarding once, as well as transition to other storyboards and identifiers.

Updating the AppDelegate

Open AppDelegate.swift and replace the default method with the following:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
  let userOnBoarded = NSUserDefaults.standardUserDefaults().boolForKey("userOnboarded")

  if userOnBoarded
  {
    let workshops = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("Workshops")
    self.window?.rootViewController = workshops
  }
  else
  {
    self.window?.rootViewController = OnboardingController()
  }

  return true
}

You’ll need to make sure you assign the view controller that you want to transition to, an identifier called “Workshops”.

Creating the Button and Blur Helper Methods

Inside of your Elements.swift file, you will need to add the following helpers:

static func createButton(text: String, screen: CGRect) -> UIButton
{
  let button = RaisedButton()
  button.frame = CGRectMake(screen.width * 0.1, screen.height - 120, screen.width * 0.8, 60)
  button.setTitle(text, forState: .Normal)
  button.setTitleColor(.whiteColor(), forState: .Normal)
  button.layer.borderColor = MaterialColor.blue.lighten4.CGColor
  button.layer.borderWidth = 2.0
  button.layer.cornerRadius = 0.0

  return button
}

static func createBlur(screen: CGRect, x: CGFloat) -> UIVisualEffectView
{
  let blur = UIVisualEffectView(effect: UIBlurEffect(style: .Dark))
  blur.frame = CGRectMake(x, 0, screen.width, screen.height)
  return blur
}

Make sure you import MK at the top of the file as well, and have the MK cocoapod installed.

Adding the Blur and Button to Onboarding

Since the video, we have updated this to take advantage of the latest Swift syntax. Namely the for loop has changed to for (i, slide) in slides.enumerate() and the selectors use the new #selector syntax.

Within your loop, you will need to add the blur view:

scroll.addSubview(Elements.createBlur(screen, x: screen.width * CGFloat(i)))

You will then want to add the button which points to a next() selector method:

let button = Elements.createButton("Got it!", screen: screen)
button.addTarget(self, action: #selector(self.next), forControlEvents: .TouchUpInside)
view.addSubview(button)

Finally, create the next() method:

func next()
{
  let workshops = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("Workshops")
  self.showViewController(workshops, sender: nil)

  NSUserDefaults.standardUserDefaults().setBool(true, forKey: "userOnboarded")
}

Wrapping up

Here’s the full source for the Onboarding Controller:

import UIKit

class OnboardingController : UIViewController, UIScrollViewDelegate
{

  let slides = [
    [
      "image": "onboarding-1",
      "header": "Welcome 1",
      "text": "some filler text for now"
    ],
    [
      "image": "onboarding-2",
      "header": "Welcome 2",
      "text": "some filler text for now"
    ],
    [
      "image": "onboarding-3",
      "header": "Welcome 3",
      "text": "some filler text for now"
    ]
  ]

  let screen = UIScreen.mainScreen().bounds
  var scroll = UIScrollView()
  var pagination = UIPageControl()

  override func viewDidLoad()
  {
    super.viewDidLoad()

    scroll.frame = CGRectMake(0, 0, screen.width, screen.height)
    scroll.showsHorizontalScrollIndicator = false
    scroll.showsVerticalScrollIndicator = false
    scroll.pagingEnabled = true
    scroll.contentSize = CGSizeMake(CGFloat(Int(screen.width) * slides.count), screen.height / 2)
    scroll.delegate = self
    view.addSubview(scroll)

    if slides.count > 1
    {
      pagination.frame = CGRectMake(0, screen.height - 50, screen.width , 50)
      pagination.numberOfPages = slides.count
      pagination.addTarget(self, action: #selector(self.swipe(_:)), forControlEvents: .ValueChanged)
      view.addSubview(pagination)
    }

    for (i, slide) in slides.enumerate()
    {
      let offsetX = CGFloat(i) * screen.width + (screen.width * 0.1)
      let background = UIImageView(frame: CGRectMake(screen.width * CGFloat(i), 0, screen.width, screen.height))
      background.image = UIImage(named: slides[i]["image"]!)
      background.layer.zPosition = -1
      scroll.addSubview(background)
      scroll.addSubview(Elements.createBlur(screen, x: screen.width * CGFloat(i)))

      if let header = slide["header"]
      {
        let h1 = Elements.createh1(header, screen: screen, x: offsetX, y: screen.height / 2 - 20)
        h1.frame.size = CGSizeMake(screen.width * 0.8, 100)
        scroll.addSubview(h1)
      }

      if let text = slide["text"]
      {
        let h2 = Elements.createH2(text, screen: screen, x: offsetX, y: screen.height / 2 + 20)
        h2.frame.size = CGSizeMake(screen.width * 0.8, 100)
        scroll.addSubview(h2)
      }
    }

    let button = Elements.createButton("Got it!", screen: screen)
    button.addTarget(self, action: #selector(self.next), forControlEvents: .TouchUpInside)
    view.addSubview(button)
  }

  func swipe(sender: AnyObject)
  {
    let offsetX = CGFloat(pagination.currentPage) * scroll.frame.size.width
    scroll.setContentOffset(CGPointMake(offsetX, 0), animated: true)
  }

  func scrollViewDidEndDecelerating(scrollView: UIScrollView)
  {
    let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
    pagination.currentPage = Int(pageNumber)
  }

  func next()
  {
    let workshops = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("Workshops")
    self.showViewController(workshops, sender: nil)

    NSUserDefaults.standardUserDefaults().setBool(true, forKey: "userOnboarded")
  }

}