Skip to main content

Automatic Trait Tracking in iOS 18

Overview​

With iOS 18, UIKit introduces automatic trait tracking, eliminating the need for manual trait change notifications. This enhancement automatically invalidates views, calling methods like setNeedsLayout, setNeedsUpdateConstraints, or setNeedsDisplay based on trait changes, streamlining updates for traits accessed within supported methods.

Supported methods include:

  • UIView: layoutSubviews(), updateConstraints(), draw(CGRect)
  • UIViewController: viewWillLayoutSubviews(), updateViewConstraints(), updateConfiguration

Blog Post: πŸ”— Source​

Code Example​

Automatic Trait Tracking Example​

The following example demonstrates automatic trait tracking in a custom UIView:

final class SquareView: UIView {
override func draw(_ rect: CGRect) {
var scale = 0.3
if traitCollection.preferredContentSizeCategory.isAccessibilityCategory {
scale = 0.6
}

let width = bounds.width * scale
let height = bounds.height * scale
let startX = (bounds.width / 2) - (width / 2)
let startY = (bounds.height / 2) - (height / 2)

let path = UIBezierPath()
path.move(to: CGPoint(x: startX, y: startY))
path.addLine(to: CGPoint(x: startX, y: startY + height))
path.addLine(to: CGPoint(x: startX + width, y: startY + height))
path.addLine(to: CGPoint(x: startX + width, y: startY))
path.addLine(to: CGPoint(x: startX, y: startY))

UIColor.blue.setStroke()
UIColor.blue.setFill()
path.stroke()
path.fill()
}
}

UIKit automatically invalidates the view (setNeedsDisplay) when the preferredContentSizeCategory changes, without manual registrations or notifications.


Pre-iOS 18 Manual Trait Tracking​

Before iOS 18, developers needed to manually register for trait changes and trigger updates:

override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}

required init?(coder: NSCoder) {
super.init(coder: coder)
setupView()
}

private func setupView() {
registerForTraitChanges([UITraitPreferredContentSizeCategory.self], action: #selector(contentSizeChanged))
}

@objc private func contentSizeChanged() {
setNeedsDisplay()
}

Benefits of Automatic Trait Tracking​

  • Reduced Boilerplate Code: No need for manual registrations or callbacks.
  • Improved Reliability: Automatically updates based on trait changes, ensuring consistent UI behavior.
  • Streamlined Workflow: Focus on core functionality without handling notifications.

Learn More​