I am trying to work with this function but it does not work with iOS 17. I want to make a change every time I switch between dark and light mode.
This is my function:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
// Check if the user interface style has changed
if self.traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
// User interface style has changed (light to dark or vice versa)
if self.traitCollection.userInterfaceStyle == .light {
// Code to execute in light mode
print("App switched to light mode")
} else {
// Code to execute in dark mode
print("App switched to dark mode")
}
}
}
This is the issue:
‘traitCollectionDidChange’ was deprecated in iOS 17.0: Use the trait change registration APIs declared in the UITraitChangeObservable protocol
Should I use registerForTraitChanges(_:handler:)
or registerForTraitChanges(_:target:action:)
instead? I don't know how to use it.
traitCollectionDidChange
is deprecated as of iOS 17.0. The solution depends on your app's deployment target. If your app's deployment target is older than iOS 17.0 (Xcode 15 supports back to iOS 12) then it's perfectly fine to continue usingtraitCollectionDidChange
. It will continue to be called even on a device with iOS 17. You won't even get a deprecation warning if you have an older deployment target.If your app's deployment target is iOS 17.0 or later then you should not override
traitCollectionDidChange
since it is now deprecated. As the documentation fortraitCollectionDidChange
shows, you instead make use of eitherregisterForTraitChanges(_:handler:)
orregisterForTraitChanges(_:target:action:)
.The documentation for both of the new methods provide examples of how to use them. The key is to find the trait(s) your code wishes to work with.
In your case you wish to handle a change to
UITraitUserInterfaceStyle
. You can find the list of traits that you can register for on the page forUIMutableTraits
.Update your code by removing the use of
traitCollectionDidChange
and adding the following toviewDidLoad
:Note that the documentation clearly states that you can safely ignore the return value and you do not need to unregister. You would want to make use of the return value and unregister if you had a case where your registration has a more limited lifetime.
Your update doesn't need to call
hasDifferentColorAppearance(comparedTo:)
since the handler code is only going to be called when the user interface style changes in this case.Note - if your deployment target is older than iOS 17, do not use both the old and new code since both sets of code will actually be called when run on devices with iOS 17. You would end up having two similar sets of code each wrapped with appropriate
if #available
checks.