Friday, December 8, 2017

Passing Data with Delegates/Protocols (iOS, Xcode 9, Swift 4)

How do you use delegation to pass data between classes? In this video you are going to learn the 3 steps to implementing the delegate pattern. This is a popular pattern in iOS so you will gain a greater understanding of how many other parts of UIKit actually work by implementing it yourself.

You will also learn what a protocol is and how it plays a part in the delegate example we have in this tutorial.




Thursday, November 30, 2017

Passing Data with Callback Functions Tutorial (iOS, Xcode 9, Swift 4)

What is a callback function in Swift and what do they have to do with Function Types?
In this video you will learn what Function Types are and how to use them to create "Callbacks". We use this pattern to pass data between view controllers.

Callbacks (or closures) are essentially a way to pass code from one class to another in Swift.




Tuesday, November 28, 2017

Passing Data to Your Popup View Controller (iOS, Xcode 9, Swift 4)

In this video you will learn how to pass data from the view controller to the popup. You will learn to do this through a segue and through code by instantiating your popup.



Monday, November 27, 2017

Reusable Custom Popups (iOS, Xcode 9, Swift 4)

You will learn how to create a popup and then display it modally with the use of a segue and also through code.



Thursday, November 16, 2017

Named Colors (iOS, Xcode 9, Swift 4)

Learn about a new Xcode 9 feature called Named Colors or Color Sets. They provide another option to putting all your app's colors in one place. You can reference Named Colors from the storyboard or from code.


Friday, August 11, 2017

Sunday, July 16, 2017

How to Make a Custom Segmented Control (iOS, Xcode 8, Swift 3)

If you watch this video and want to implement this custom segmented control then there are two changes you should make for it work better:

1. Change to sv.distribution = .fillEqually (instead of using .fillProportionally)

2. Add `updateView()` to the draw function



Some of my subscribers pointed out these better ways. Thanks!



3 Methods of Masking Images (iOS, Xcode 8, Swift 3)

Mask images the easy way. And one way that's not too easy but allows shadows on your masked images.



Friday, June 30, 2017

Prototyping Apps in Xcode: Populating, Animating UITableViewCells: Part ...

Let's wrap up this series by working on the UITableView!



  • You will learn how to populate the table using 2 distinct prototype UITableViewCells. 
  • You will also learn about dynamically populating the profile images into a UIStackView. 
  • Then we wrap it up by animating the UITableViewCells into the table view.




Prototyping Apps in Xcode: Modeling Data and Populating UI: Part 6 (iOS,...

Let's take a look on how we handle model data and use it to populate the UI!

 

Tuesday, June 20, 2017

Customizing Appearance of iOS Composite Controls

An example of a "composite control" is a Search Bar.
If you want to customize one of the controls in the composite control and there is no direct property for it, then you can use the UIAppearance protocol that controls implement.

Example

 
let textfieldsInSearchBars = UITextField.appearance
    (whenContainedInInstancesOf: [UISearchBar.self])
textfieldsInSearchBars.tintColor = .lightGray
textfieldsInSearchBars.backgroundColor = .darkGray
textfieldsInSearchBars.textColor = .lightGray
 

(Swift 3)

Friday, June 16, 2017

Prototyping Apps in Xcode: Working With Icons and Sketch: Part 4

In this video you will learn how I go about finding and creating icons with Sketch and then implement them in my iOS apps. What size should icons be? What different sizes should you support? How do you change the color to match the button's tint color? I'll answer all of these questions.



Prototyping Apps in Xcode: Floating Action Button Expanding Menu: Part 3

In this video you will learn how to build an expanding menu from the floating action button that looks like Google's Material Design.



Prototyping Apps in Xcode: Creating A Floating Action Button - Part 2 (i...

Let's create a floating action button (Material Design).

Monday, June 5, 2017

Make It Rain Or Snow Images With The CAEmitterLayer (iOS, Xcode 8, Swift 3)


How do you make images fall randomly from the top of the screen, like it is raining or snowing?



It is done with a thorough knowledge of the CAEmitterLayer! But do not worry, I make this super easy for you to understand and use the CAEmitterLayer. You can do a lot of very cool things with the emitter but I will be showing you just one cool thing: how to make it "snow" images.



You will learn how to setup and position the CAEmitterLayer. You will learn how to add images and information on how that image should be shown with the CAEmitterCell object.



At the end of this video you will have the understand and skill to create your own emitters and show your own images coming from the emitter.

Monday, May 15, 2017

UIScrollView Setup

I ALWAYS forget these steps. So I am finally going to blog them so I remember.

1. Setup UIScrollView and Your Content UIView

  1. Add UIScrollView to Storyboard. Size to your liking.
  2. Set the top, trailing, bottom and leading constraints.
  3. Add a UIView to the UIScrollView.
  4. Set zero point constraints for your top, trailing, bottom and leading constraints.

2. Horizontal or Vertical Scrolling?

Horizontal Scrolling

  1. Add a WIDTH constraint to the UIView with a number that is wider than the main view's width.
  2. Right-click drag from the UIView to the main view and set constraint: Equal Heights
    (Note that you want to scroll sideways so the height will not be changing.)

Vertical Scrolling

  1. Add a HEIGHT constraint to the UIView with a number that is longer than the main view's height.
  2. Right-click drag from the UIView to the main view and set constraint: Equal Widths

3. Setup Storyboard

  1. Select your Scene (ViewController)
  2. In the Size Inspector, change Simulated Size from Fixed to Freeform.
  3. Change the Width or Height to whatever you set in the previous step.

(Xcode 8)

Sunday, May 14, 2017

Create a Horizontal UIPickerView! (iOS, Xcode 8, Swift 3)

Horizontal Picker views look great and are fairly easy to implement after you know how. Watch the video to learn!



Monday, May 1, 2017

Friday, April 21, 2017

Introduction to Transitions

Transitions are another way of doing a specific kind of animation from one UIView to another UIView. In Xcode we can setup UIViews to transition from one to another and back again using preset animations that Apple provides.



Wednesday, April 19, 2017

Sunday, March 26, 2017

Transparent TableView - Zelda App (iOS, Xcode 8, Swift 3)

Learn how to make your table view transparent so you can see the background through it. You will also learn a little about customizing the tableview's separator.



Closures - Zelda App (iOS, Xcode 8, Swift 3)

You may not be creating closures all the time but it is good to know about them and how they work because you will be using them ALL the time.


Wednesday, March 22, 2017

Play A Movie That Is In Your Project

On your Storyboard, add a "AVKit Player View Controller". Connect it with a Segue from a UIButton you put on the View Controller.

Like this:
 
import UIKit
import AVKit
import AVFoundation

class ViewController: UIViewController {
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        let destination = segue.destination as! AVPlayerViewController
        let url = Bundle.main.url(forResource: "myMovieName", withExtension: "m4v")
        
        if let movieURL = url {
            destination.player = AVPlayer(url: movieURL)
        }
    }
}
 

(Xcode 8.2, Swift 3)

Saturday, March 18, 2017

Introduction to iOS Threading - Zelda App (Xcode 8, Swift 3)

Get an introduction to threading in iOS to make your apps more responsive when another process is taking a long time.

Sunday, March 12, 2017

Show Execution Time (Elapsed Time)

Sometimes you want to see how long it took some code to execute. Here is an example of one way you could do this.
 
func myLongRunningFunction() {
    let start = Date()

    // Do you work

    let end = Date()
    let elapsedTime = end.timeIntervalSince(start)
    print("Elapsed Time: \(elapsedTime)")
}
 

(Swift 3)

Friday, March 10, 2017

iOS Tinder-Like Swipe - Part 5 - Scaling the Card (Xcode 8, Swift 3)

The final part! As you slide the card closer to the edge of the screen, we also want to scale the card down (make smaller). Here is how you do that:



iOS Tinder-Like Swipe - Part 4 - Rotating the Card (Xcode 8, Swift 3)

As you swipe the card side-to-side, we want to apply a rotation transform to the card. The closer you get to the edge, the more rotation. I walk you through all the steps.



iOS Tinder-Like Swipe - Part 3 - Animating card off screen (Xcode 8, Swi...

When the card gets close to the edge of the screen, we want it to continue off the screen by animating it off.



iOS Tinder-Like Swipe - Part 2 - Fading image in and out (Xcode 8, Swift 3)

Show the thumbs up or thumbs down while doing the Tinder-like swiping action on the card.



Monday, March 6, 2017

iOS Tinder-Like Swipe - Part 1- UIPanGestureRecognizer (Xcode 8, Swift 3)

Create Tinder-like swiping in your app. This was a fun tutorial series to make. Hope you enjoy it!







Also, a viewer pointed out something that can make the dragging of the card code a little simpler.

Instead of:
 
let point = sender.translation(in: view)
card.center = CGPoint(x: view.center.x + point.x, y: view.center.y + point.y)
 

You can just do:
 
card.center = sender.location(in: view)
 
Easy!

Thursday, March 2, 2017

Storyboard Tips - Easily Work With Layers Of Controls (iOS, Xcode 8)

Storyboard Tips. When working with layers of views and other controls, use this is a handy tip to get underneath other controls to make modifications and put everything back to the way it was with a click of a button!



Wednesday, March 1, 2017

Timer in Apps (Swfit 3, Xcode 8, iOS)

In this example I start a timer as soon as I enter the second view controller after clicking the "START MY RANDOM WORKOUT" button. Here is the code for that second view:

 
import UIKit

class ExerciseVc: UIViewController {

    @IBOutlet weak var timerLabel: UILabel!
    
    @IBOutlet weak var icon: UIImageView!
    var timer: Timer!
    var timeLeft = 60
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Call setTimeLeft every 1 second
        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: 
            #selector(self.setTimeLeft), userInfo: nil, repeats: true)
        icon.image = #imageLiteral(resourceName: "situp")
    }

    func setTimeLeft() {
        timeLeft -= 1 // Subtract one second
        
        if timeLeft == 0 {
            stop()
        }
        
        timerLabel.alpha = 1
        timerLabel.transform = CGAffineTransform(scaleX: 1.4, y: 1.4)
        
        UIView.animate(withDuration: 1, animations: {
            self.timerLabel.text = "\(self.timeLeft)"
            self.timerLabel.alpha = 0.3
            self.timerLabel.transform = .identity
        })
    }
    
    @IBAction func stop(_ sender: UIButton) {
        stop()
    }
    
    // Show a white status bar instead of the default black one
    override var preferredStatusBarStyle: UIStatusBarStyle {
        get {
            return UIStatusBarStyle.lightContent
        }
    }
    
    func stop() {
        timer.invalidate() // Stop the timer
        dismiss(animated: true, completion: nil)
    }
}
 

(Swift 3)

Saturday, February 25, 2017

Side Scrolling UIPIckerView


The scrolling temperature is a UIPickerView rotated on its side. Here is what is happening here:

  • Rotate the UIPickerView 90°
  • Rotate the view inside each row 90°
  • Reverse the data populated into the picker
  • Resize the rotated picker so it extends beyond the view. This makes the horizontal scroller fill the entire width
Here's the code:
 
class ViewController: UIViewController {

    @IBOutlet weak var picker: UIPickerView!
    
    var data: [String] = ["60°", "61°", "62°", "63°", "64°", "65°","66°", "67°", "65°", "63°", "59°", "57°"]
    var times: [String] = ["9:00", "10:00", "11:00", "12:00", "13:00", "14:00","15:00", "16:00", "17:00", "18:00", "19:00", "20:00"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        picker.transform = CGAffineTransform(rotationAngle: 90 * (.pi/180))
        picker.frame = CGRect(x: -100, y: view.frame.height - 120, width: view.frame.width + 200, height: 100)

        data.reverse()
        times.reverse()
        
        picker.dataSource = self
        picker.delegate = self
        
        picker.selectRow(data.count - 3, inComponent: 0, animated: false)
    }

    override func viewDidLayoutSubviews() {
        for subview in picker.subviews{
            if subview.frame.origin.y != 0{
                subview.isHidden = true
            }
        }
    }
}

extension ViewController: UIPickerViewDataSource {
    // Like number of columns
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return data.count
    }
}

extension ViewController: UIPickerViewDelegate {
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return data[row]
    }
    
    func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
        return 100
    }
    
    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        
        let label = UILabel(frame: CGRect(x: 5, y: 0, width: view.frame.width, height: view.frame.height))
        label.text = data[row]
        label.textAlignment = .center
        label.font = UIFont.systemFont(ofSize: 45, weight: UIFontWeightThin)
        view.addSubview(label)
        
        let time = UILabel(frame: CGRect(x: 0, y: 85, width: view.frame.width, height: 15))
        time.text = times[row]
        time.textAlignment = .center
        time.font = UIFont.systemFont(ofSize: 14, weight: UIFontWeightThin)
        view.addSubview(time)
        
        view.transform = CGAffineTransform(rotationAngle: -90 * (.pi/180))
        
        return view
    }
}
 


Sunday, February 12, 2017

Thursday, February 9, 2017

Wednesday, February 8, 2017

Basic UIPickerView Template

I am using extensions here just so you can see which functions belong to which protocols.
 
class ViewController: UIViewController {

    @IBOutlet weak var picker: UIPickerView!
    
    var data: [String] = ["Row 1", "Row 2", "Row 3"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        picker.dataSource = self
        picker.delegate = self
    }
}

extension ViewController: UIPickerViewDataSource {
    // Like number of columns
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return data.count
    }
}

extension ViewController: UIPickerViewDelegate {
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return data[row]
    }
}
 

(Swift 3)

Tuesday, February 7, 2017

Fun Animations with CGAffineTransform (Scale, Rotate, Reposition) Tutori...

In this video I will take you through and teach you how easy it is to do multiple animations using CGAffineTransform. I will even explain what "Affine" means. :D

Friday, February 3, 2017

How to Create Animation Chains - UIView.animate (iOS, Xcode 8, Swift 3)

Need to do multiple animations, one after another? This video will show you a pretty good way on how to accomplish this using UIView.animate with the completion block.

Sunday, January 29, 2017

How to make an Onboarding Screen (iOS, Xcode 8, Swift 3)

Show an onboarding (intro) screen the first time the user uses your app. Keep track if they saw it or not so you know if it should come first.

Monday, January 2, 2017

Gradients

Below is a simple gradient from black to dark gray. You can add many colors to the colors array.
 
let newLayer = CAGradientLayer()
newLayer.colors = [UIColor.black.cgColor, UIColor.darkGray.cgColor]
newLayer.frame = view.frame
view.layers.insertSublayer(newLayer, at: 0)
 

You can manually set the startPoint and endPoint properties for the CAGradientLayer to change the default gradient direction from top to bottom.

These are of a type CGPoint which is basically just and x and y value. BUT, the max value for x or y is only 1.

You have to think of the values as a percentages, like:

  •  0 = 0% 
  •  .25 = 25% 
  •  .5 = 50% 
  •  .75 = 75% 
  •  1 = 100% 
Here are the default values for top to bottom:
 
newLayer.startPoint = CGPoint(x: 0, y: 0) // Upper left corner
newLayer.endPoint = CGPoint(x: 0, y: 1) // Lower left corner
 

If you wanted to make it HORIZONTAL, then you could start from upper left to upper right.

It would look like this:
 
newLayer.startPoint = CGPoint(x: 0, y: 0) // Upper left corner
newLayer.endPoint = CGPoint(x: 1, y: 0) // Upper right corner
 

Now, can you guess what a 45 degree angle would look like?

It would look like this:
 
newLayer.startPoint = CGPoint(x: 0, y: 0) // Upper left corner
newLayer.endPoint = CGPoint(x: 1, y: 1) // Lower right corner
 

Here's a diagram which might clear up how these CGPoints work:
CGPoint X,Y Scale in iOS


(Swift 3)

SwiftUI Search & Filter with Combine - Part 3 (iOS, Xcode 13, SwiftUI, 2...

In part 3 of the Searchable video series, I show you how to use Combine in #SwiftUI for the search and filter logic connected to the searcha...