SceneDelegate

Introduced in iOS 13.

Understanding the iOS 13 SceneDelegate:

UIView

A view forms root of view hierarchy; object instance lifetime isn't quite 1:1 with widget (screen) lifetime.

Views form a hierarchy; every view has a parent view, rooted to a UIWindow (which is the root view to the OS).

Custom UIView subclass: draw(_:) method is invoked so that the view can draw itself.

Example: custom UIView class (MyHorizLine) that draws a horizontal line. File -> New -> File -> iOS -> Cocoa Touch Class (UIView).

```
class MyHorizLine : UIView {
    required init?(coder: NSCoder) {
      super.init(coder: coder)
      self.backgroundColor = .clear
    }

    override func draw(_ rect: CGRect) {
      let c = UIGraphicsGetCurrentContext()!
      c.move(to: CGPoint(x: 0, y: 0))
      c.addLine(to: CGPoint(x: self.bounds.size.width), y: 0))
      c.strokePath()
    }
}
```

UIViewController

A view controller isn't an interface object (view), but it manages one; this view is its "main view".

Use view controllers to manage your UIKit app’s interface. A view controller manages a single root view, which may itself contain any number of subviews. User interactions with that view hierarchy are handled by your view controller, which coordinates with other objects of your app as needed. Every app has at least one view controller whose content fills the main window. If your app has more content than can fit onscreen at once, use multiple view controllers to manage different parts of that content.

A container view controller embeds the content of other view controllers into its own root view. A container view controller may mix custom views with the contents of its child view controllers to facilitate navigation or to create unique interfaces. For example, a UINavigationController object manages a navigation bar and a stack of child view controllers (only one of which is visible at a time), and provides an API to add and remove child view controllers from the stack.

You change your app's interface by presenting and dismissing view controllers. Every window has a root view controller, which provides the initial content for your window. Presenting a new view controller changes that content by installing a new set of views in the window. When you no longer need the view controller, dismissing it removes its views from the window. You present view controllers in one of several ways:

Each technique gives you different amounts of control over the presentation and dismissal process.

Interface Builder: Document Outline

Hierarchical view of the objects in the nib.

Two fundamental IB file types, storyboards and nibs:

To manually instantiate a view controller from a nib/storyboard, take a UIStoryboard instance and call instantiateInitialViewController (to instantiate the one marked as the initial view controller) or instantiateViewController(withIdentifier:) (to instantiate one by ID)

Nib files

Resource-based widget construction. "Nib" comes from extension .nib: Nextstep Interface Builder. Also applies to .xib (XML-based Nib) and .storyboard files. A nib containing a view controller will almost certainly come from a storyboard.

When a view controller has a main view, but instantiates it lazily/on-demand. The view conroller can obtain it through one of several ways, including from a nib. If the view controller is instantiated in code, use the init(nibName:bundle:) to designate the .xib file to use to instantiate the view. (Or override it and provide it to the base class?)

Bundle::loadNibNamed(_:owner:options) or UINib::instantiate(withOwner:options:) (after instantiating a new UINib object). This returns an array of object instances created from the nib's top-level objects. (The owner will be the object to use for the destination of connections.)

To create a raw nib (.xib file): File | New | File -> iOS -> User Interface -> View.

Connections

Directional linking in the nib editor from one object (source) to another (destination). Two kinds:

Communication between objects

Organizational considerations to help arrange for coherent communication between objects. Almost all of them require First to have an active reference to second in some form.


Misc

Adding support for multiple windows to iPadOS app

(TODO: This is pretty complicated)

Dismissing the keyboard

From Dismissing the keyboard in SwiftUI

In UIKit, views that utilize the keyboard such as UITextField and UITextView can be dismissed by calling resignFirstResponder on the view itself, or endEditing on one of its parent views. Code in a simple view controller might look like this:

class ViewController: UIViewController {
    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
        self.view.addGestureRecognizer(tapGesture)
    }

    @IBAction func buttonPressed(_ sender: Any) {
        dismissKeyboardFrom(view: textField)
    }

    @objc func dismissKeyboardFrom(view: UIView) {
        view.resignFirstResponder()
        // or view.endEditing()
    }

    @objc func dismissKeyboard() {
        self.view.endEditing(true)
    }
}

Log all the responds(to:) requests on an object

For example, implement this on the AppDelegate class in a project to instrument with logging:

```
override func response(to aSelector: Selector) -> Bool {
  print(aSelector)
  return super.responds(to: aSelector)
}
```

Variable Width Strings

Wouldn’t it be useful if you could automatically change the text based on the available space? There’s a little-known feature of the localization system that does precisely that.

UIView styling with functions

Today I want to talk about UIView styling. The common approach when we want to customize the display of native UI controls (for instance UIButton or UILabel) is to create a subclass that overrides a bunch of properties. That works well most of the time, but some problems may arise.

Two Takes on Adaptive Cell Layout

On autolayout, adaptive table cells, and using UIStackView (or not!)

Popovers, UINavigationController, and preferredContentSize

In this post we'll look at a very specific but tricky interaction in UIKit, one which took me multiple days to work out how to implement.

Modality changes in iOS 13

One behavior that changed and might break your old app once you starting adopting new iOS 13 is the modal presentation.

The Auto Layout Comprehendium™

Intended as a compendium for you to look up certain topics and to fully understand the internal mechanics behind the technology. While following an intuitive approach, it will help you master Auto Layout at a deeper level and empower you to build adaptable layouts without conflicts or ambiguities.

The iOS 13 Design Guidelines: An Illustrated Guide

In this article, we’re going to cover basically everything you need to know to design an iPhone app following standard iOS 13 conventions and style.

SF Symbols Changes in iOS 14.2

There are now three different sets of symbols to consider...

Tweaking The iOS System Fonts

Before you switch to a custom font don’t overlook how much you can tweak the appearance of the system fonts. A quick review of some font APIs that work for both UIKit and SwiftUI.


Devices & Resolutions

Resolutions

iOS 14 resolutions

@stroughtonsmith

iPhone 4”: 320 x 568 pt
iPhone 4.7”: 375 x 667 pt
iPhone 5.5”: 414 x 736 pt

iPhone 5.4” & 5.8”: 375 x 812 pt
iPhone 6.1" (2020): 390 x 844 pt

iPhone 6.1” (2018–2019) & 6.5”: 414pt x 896 pt
iPhone 6.7”: 428 x 926 pt

@stroughtonsmith

If you want to be thorough, the 5.4" and 5.8" iPhone models also support a Display Zoom resolution of 320 x 693 pt,
which I'm sure almost nobody actually tests their apps at

iPhone 12


Nib/Storyboard/SwiftUI Alternatives

Layout: A declarative UI framework for iOS


Tags: platform   ios  

Last modified 18 May 2022