Friday, November 18, 2016

UIPageViewController Minimum Setup Template

The minimum setup to get started using the UIPageViewController.
 
class ViewController: UIPageViewController, UIPageViewControllerDataSource {

    var pages: [UIViewController] = [UIViewController]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        dataSource = self
        
        pages.append(UIStoryboard(name: "Main", bundle: nil)
            .instantiateViewController(withIdentifier: "Page1"))
        pages.append(UIStoryboard(name: "Main", bundle: nil)
            .instantiateViewController(withIdentifier: "Page2"))
        pages.append(UIStoryboard(name: "Main", bundle: nil)
            .instantiateViewController(withIdentifier: "Page3"))
        
        setViewControllers([pages.first!], direction: .forward, animated: true, 
            completion: nil)
    }

    func pageViewController(_ pageViewController: UIPageViewController, 
        viewControllerBefore viewController: UIViewController) -> UIViewController? {
        
        let index = pages.index(of: viewController)!
        
        if index == 0 {
            return nil
        }
        
        return pages[index - 1]
    }
    
    func pageViewController(_ pageViewController: UIPageViewController, 
        viewControllerAfter viewController: UIViewController) -> UIViewController? {
        
        let index = pages.index(of: viewController)!
        
        if index == pages.count - 1 {
            return nil
        }
        
        return pages[index + 1]
    }
    
    func presentationCount(for pageViewController: UIPageViewController) -> Int {
        return pages.count
    }
    
    func presentationIndex(for pageViewController: UIPageViewController) -> Int {
        return 0
    }
}
 


(Xcode 8, Swift 3.0)

Sunday, November 13, 2016

Layout Anchors

Why describe what layout anchors are when you can show it!
These are the two UIViews I will be demonstrating.
Technically this example is not using a Layout Anchor but it is a good way to center objects.
 
myView.center = view.center
 
IMPORTANT! All examples below will need to include these 3 lines of code for them to work.
 
myView.translatesAutoresizingMaskIntoConstraints = false
myView.widthAnchor.constraint(equalToConstant: 125).isActive = true
myView.heightAnchor.constraint(equalToConstant: 125).isActive = true
 
Without setting translatesAutoresizingMaskIntoConstraints to false, the new constraints will do nothing.
Without a height and width I found a UIView will just collapse into no height or width.

Horizontal Examples

 
myView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
myView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
 

 
myView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
 

 
myView.rightAnchor.constraint(equalTo: view.leftAnchor, constant: 30).isActive = true
 

 
// Offset from center -50
myView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: -50).isActive = true
 

Vertical Examples

 
// Going to center myView for the Vertical examples.
myView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
myView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
 

 
myView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
 

(Xcode 8, Swift 3.0)

Monday, November 7, 2016

Getting Height or Width of Text

You use UIView.sizeThatFits to get the best size to fit a given size.

  • To get width, fix the height and maximize the width of your given size.
  • To get height, fix the width and maximize the height of your given size.

Code Example of Getting Width of Text

 
@IBOutlet weak var sampleTextLabel: UILabel!

@IBOutlet weak var widthTextField: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()
    
    // Fix the height to get the width.
    let suggestedSize = CGSize(width: CGFloat.greatestFiniteMagnitude, 
                               height: sampleTextLabel.frame.height)
    widthTextField.text = sampleTextLabel.sizeThatFits(suggestedSize).width.description
}
 
Note: CGFloat.greatestFiniteMagnitude gives you the maximum number for a float.

(Xcode 8, Swift 3.0)

Friday, November 4, 2016

Animation With Spring (Bounce)


Code Example

 
 
UIView.animate(withDuration: 0.2, 
    delay: 0, 
    usingSpringWithDamping: 0.5, 
    initialSpringVelocity: 0.5, 
    options: .curveEaseOut, 
    animations: {
    // Your animation
}, completion: nil)
 

Parameters

  • withDuration - How long the animation should last
  • delay - How long to wait until starting the animation
  • usingSpringWithDamping - Applies damping to the spring (bounce). Using 1 will completely damp out the spring so the animation just slides into place and stops. Lower the damping for more bounce (example: 0.1 - 0.9).
  • initialSpringVelocity - How fast you want the initial animation to happen. Using 1 will start it fast, 0 is normal. Apple says, "You'll typically want to pass 0 for the velocity."
  • options:
    • curveEaseInOut - Start slow, speed up, then slow down
    • curveEaseIn - ("In" specifies the start of the animation) Start slow, speed up, then suddenly stop
    • curveEaseOut - ("Out" specifies the end of the animation) start fast, then slow down until stop
    • curveLinear - Constant speed throughout animation

(Xcode 8, Swift 3.0)

Tuesday, November 1, 2016

Menus in Your Apps

In these videos I show you two options for creating menus that slide out from the side. The main thing I'm doing is using a UIView and animating the movement to show a menu.




Sunday, October 30, 2016

Drop Shadow on a UIView

Minimum Code

Views already have a black, three point drop shadow by default but you cannot see it because the opacity is set to zero.
 
myView.layer.shadowOpacity = 1
 
That all you need to get started to show the drop shadow.

Options

Reposition the Drop Shadow

 
// Reposition the drop shadow (center it with with CGSize.zero)
myView.layer.shadowOffset = CGSize.zero // Default is (0, -3)
 
 
myView.layer.shadowOffset = CGSize(width: 0, height: -5) // Top
myView.layer.shadowOffset = CGSize(width: 5, height: 0) // Right
myView.layer.shadowOffset = CGSize(width: 0, height: 5) // Bottom
myView.layer.shadowOffset = CGSize(width: -5, height: 0) // Left
myView.layer.shadowOffset = CGSize(width: 5, height: -5) // Top, Right
myView.layer.shadowOffset = CGSize(width: -5, height: -5) // Top, Left
myView.layer.shadowOffset = CGSize(width: 5, height: 5) // Bottom, Right
myView.layer.shadowOffset = CGSize(width: -5, height: 5) // Bottom, Left
 

Change Drop Shadow Size

 
// Increase the size of the drop shadow
myView.layer.shadowRadius = 6 // Default is 3
 

Change Drop Shadow Color

 
myView.layer.shadowColor = UIColor.blue.cgColor
 

Improve Performance

 
// Apple says: "...this property will usually 
//             improve rendering performance..."
myView.layer.shadowPath = UIBezierPath(rect: myView.bounds).cgPath

// Another way is to convert the drop shadow into a bitmap.
// Apple says: "...may attempt to cache and reuse..."
myView.layer.shouldRasterize = true
 

(Xcode 8, Swift 3.0)

Friday, October 28, 2016

Adding Done Button to Keyboard

In this example I use a UIToolBar to contain the done button but you can use any UIView to assign to inputAccessoryView.
 
class ViewController: UIViewController {

    @IBOutlet weak var nameTextField: UITextField!
    @IBOutlet weak var phoneNumberTextField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let keyboardToolBar = UIToolbar()
        keyboardToolBar.sizeToFit()
        
        let flexibleSpace = UIBarButtonItem(barButtonSystemItem: 
            UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
        let doneButton = UIBarButtonItem(barButtonSystemItem: 
            UIBarButtonSystemItem.done, target: self, action: #selector(self.doneClicked) )
        
        keyboardToolBar.setItems([flexibleSpace, doneButton], animated: true)
        
        nameTextField.inputAccessoryView = keyboardToolBar
        phoneNumberTextField.inputAccessoryView = keyboardToolBar
    }

    func doneClicked() {
        view.endEditing(true)
    }
}
 

Here is an example of using a Navigation Bar:
 
let navItem = UINavigationItem()
let doneBtn = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.done, 
    target: self, action: #selector(self.doneClicked))
navItem.rightBarButtonItem = doneBtn

let navBar = UINavigationBar(frame: CGRect(x: 0, y: 0, width: view.frame.width, 
    height: 44))
navBar.pushItem(navItem, animated: true)

nameTextField.inputAccessoryView = navBar
phoneNumberTextField.inputAccessoryView = navBar
 

(Xcode 8, Swift 3.0)

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...