Build with iOS pickers, menus and actions

Written by Ammar AlTahhan

Description: Build iPhone and iPad apps with fluid interfaces and easily-accessible contextual information. We’ll show you how to integrate the latest UIKit controls into your app to best take advantage of menus, date pickers, page controls, and segmented controllers. Learn how to adopt Menus throughly your user interface, and explore how UIAction can help unify your event handling. Once you’ve learned about these new controls, watch “Design with iOS pickers, menus and actions” to discover how to design great interfaces with these tools and APIs.

UIControls New Design and Appearance

UIPageControl

  • UIPageControl can now be scrubbed and scrolled when the number of pages doesn’t fit the available space.
  • UIPageControl components such as indicators can now be customized via the following API:
let pageControl = UIPageControl()
pageControl.numberOfPages = 5

pageControl.backgroundStyle = .prominent

pageControl.preferredIndicatorImage =
    UIImage(systemName: "bookmark.fill")

pageControl.setIndicatorImage(
    UIImage(systemName: "heart.fill"), forPage: 0)

UIColorPickerViewController

  • New UIColorPickerViewController, presented as a sheet and featuring eyedropper, favorites, and hexadecimal specification
var color = UIColor.blue
var colorPicker = UIColorPickerViewController()

func pickColor() {
    colorPicker.supportsAlpha = true
    colorPicker.selectedColor = color
    self.present(
        colorPicker,
        animated: true,
        completion: nil
    )
}

func colorPickerViewControllerDidSelectColor(
    _ viewController: UIColorPickerViewController
) {
    color = viewController.selectedColor
}

func colorPickerViewControllerDidFinish(
    _ viewController: UIColorPickerViewController
) {
    // Do nothing
}

UIDatePicker

  • UIDatePicker now offers a compact style, and we can optionally limit selection to just a date or time.
let datePicker = UIDatePicker()
datePicker.date = Date(
    timeIntervalSinceReferenceDate: timeInterval
)

datePicker.preferredDatePickerStyle = .compact

datePicker.calendar = Calendar(identifier: .japanese)
datePicker.datePickerMode = .date

datePicker.addTarget(
    self,
    action: #selector(dateSet),
    for: .valueChanged
)
iOS / iPadOSmacOS

UIMenu

  • In iOS, we can now add UIMenus to UIButtons and UIBarButtonItems displayed to the user on a long press:
button.menu = UIMenu(...)

barButtonItem.menu = UIMenu(...)
  • We can also adjust the behavior of menus to show immediately on touch down instead of waiting for a long press by:
    • button.showsMenuAsPrimaryAction = true for UIButton
    • Not providing a primary action for UIBarButtonItem
  • UINavigationBar back button now gets a default menu as well (to let the user jumps back to a previous controller quickly). Menu titles are automatically chosen, if we’re currently using a custom title view in our controller, consider setting:
    • .backBarButtonItem.title
    • .backButtonTitle
    • .title
  • We can access UIControl interactions and their properties, and we can subclass UIControl and provide a custom implementation for our custom menu based UIs
    • We can use UIDeferredMenuElement to add the ability to load menu items asynchronously while showing a standard loading UI.

    UIAction

    • UIAction can now be directly passed to UIButton, UIBarButtonItem, and UISegmentedControl initializers.
    • UIButton initializer init(type:primaryAction:) defaults the UIButton type to .system, which sets the button’s title and image to that of the primary action (primaryAction.title and primaryAction.image)
    • We can now create UISegmentedControl as easy as:
    let control = UISegmentedControl(frame: .zero, actions: Colors.allCases.map { color in 
    	UIAction(title: color.description) { [unowned imageView] _ in 
    		imageView.tintColor = color.color()
    	}
    })
    

    Missing anything? Corrections? Contributions are welcome 😃

    Related

    Written by

    Ammar AlTahhan

    Ammar AlTahhan

    Software Engineer