UITrait and UITraitDefinition
- iOS17 adds a new protocol
UITraitDefinition
to represent the type of features in a feature collection. Custom features can be implemented by adhering to this protocol. - UITrait is
UITraitDefinition.Type
an alias for .
@available(iOS 17.0, tvOS 17.0, *)
public protocol UITraitDefinition {
associatedtype Value
static var defaultValue: Self.Value { get }
static var identifier: String { get }
static var name: String { get }
static var affectsColorAppearance: Bool { get }
}
@available(iOS 17.0, tvOS 17.0, *)
public typealias UITrait = UITraitDefinition.Type
UITraitCollection
- All traits contained in UITraitCollection adhere to
UITraitDefinition
the protocol. - New constructor methods added.
- Added modification method.
//
let customTraits = UITraitCollection { mutableTraits in
mutableTraits.horizontalSizeClass = .compact
mutableTraits.verticalSizeClass = .regular
mutableTraits.userInterfaceStyle = .light
}
//
let modifyTraits = customTraits.modifyingTraits { mutableTraits in
mutableTraits.horizontalSizeClass = .regular
mutableTraits.verticalSizeClass = .compact
mutableTraits.userInterfaceStyle = .dark
}
traitCollectionDidChange()
The methods in the UITraitEnvironment protocol traitCollectionDidChange()
are obsolete. To listen for feature changes, you need to use UITraitChangeObservable
the corresponding feature change registration method in the protocol.
import UIKit
extension UIColor {
static var viewBackgroundColor: UIColor {
.init { (trait: UITraitCollection) -> UIColor in
if trait.userInterfaceStyle == .dark {
return .white
}
return .black
}
}
static var viewControllerBackgroundColor: UIColor {
.init { (trait: UITraitCollection) -> UIColor in
if trait.userInterfaceStyle == .dark {
return .red
}
return .green
}
}
}
class CustomView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
//
registerForTraitChanges([UITraitUserInterfaceStyle.self], action: #selector(configureView))
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {}
@objc private func configureView() {
backgroundColor = .viewBackgroundColor
}
}
class ViewController: UIViewController {
lazy var customView: CustomView = {
let customView = CustomView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
customView.center = view.center
customView.backgroundColor = .viewBackgroundColor
return customView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .viewControllerBackgroundColor
view.addSubview(customView)
//
registerForTraitChanges([UITraitUserInterfaceStyle.self]) { (self: Self, previousTraitCollection: UITraitCollection) in
self.view.backgroundColor = .viewControllerBackgroundColor
}
}
//
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {}
}