I'm currently adapting my app to be compatible with the new ios 13 features. I have some color values stored in Firebase Remote Config, for light and for dark mode, and I would like to use them depending on the user's setting, however when I access the traitCollection's attribute the simulator crashes when darkmode is disabled. Once I enable darkmode everything is fine.
How can I solve this?
From what I understand reading Apple's documentation the default mode is light so I thought I could just create a simple if statement to ask for darkmode enabled. Below you can see the method in code. It get's called inside viewDidLoad of my ViewController:
func renderCustomUI() {
var primaryColor = UIColor()
var secondaryColor = UIColor()
if #available(iOS 13.0, *) {
// crash !
if traitCollection.userInterfaceStyle == .dark {
primaryColor = UIFunctions.shared.getPrimaryColor(darkMode: true)
secondaryColor = UIFunctions.shared.getSecondaryColor(darkMode: true)
}
} else {
primaryColor = UIFunctions.shared.getPrimaryColor(darkMode: false)
secondaryColor = UIFunctions.shared.getSecondaryColor(darkMode: false)
}
let navBar = navigationController?.navigationBar
navBar?.barTintColor = primaryColor
navBar?.tintColor = secondaryColor
self.refreshControl.tintColor = primaryColor
let homeButton = self.navigationItem.leftBarButtonItem!
homeButton.setIcon(icon: .ionicons(.iosInformationOutline), iconSize: CGFloat(IconSizes.navBarIcon.rawValue)+3, color: secondaryColor)
pastEventsSegment.tintColor = primaryColor
// set border bottom of nav bar to color
self.navigationController?.setNavigationBarBorderColor(primaryColor)
setupFont(color: secondaryColor)
}
public func getPrimaryColor(darkMode: Bool) -> UIColor {
var color = UIColor()
var primaryColorHex = ""
if darkMode {
primaryColorHex = RemoteConfig.remoteConfig()
.configValue(forKey: "primaryColorDark")
.stringValue ?? ""
} else {
// light mode and previous iOS versions
primaryColorHex = RemoteConfig.remoteConfig()
.configValue(forKey: "primaryColorDefault")
.stringValue ?? ""
}
color = self.hexStringToUIColor(hex: primaryColorHex)
return color
}
I expected I can react to darkmode this way, any other case would go with the default coloring for my app, which would be equivalent to light mode. Devices below iOS 13 also would get the default coloring.
2019-09-23 12:51:20.449882+0200 Kaerwaradar[6231:311159] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -isEqual: not defined for the UIColor <UIPlaceholderColor: 0x60000272f5a0>; need to first convert colorspace.'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff23b98bde __exceptionPreprocess + 350
1 libobjc.A.dylib 0x00007fff503b5b20 objc_exception_throw + 48
2 CoreFoundation 0x00007fff23b98a1c +[NSException raise:format:] + 188
3 UIKitCore 0x00007fff46d5a397 raiseWithColorSpaceError + 96
4 UIKitCore 0x00007fff46d5a3f9 -[UIColor isEqual:] + 9
5 UIKitCore 0x00007fff467e09fc -[UINavigationBar setBarTintColor:] + 59
6 Kaerwaradar 0x0000000107e57a92 $s11Kaerwaradar18HomeViewControllerC14renderCustomUIyyF + 1266
7 Kaerwaradar 0x0000000107e52649 $s11Kaerwaradar18HomeViewControllerC11viewDidLoadyyF + 1033
8 Kaerwaradar 0x0000000107e5321b $s11Kaerwaradar18HomeViewControllerC11viewDidLoadyyFTo + 43
9 UIKitCore 0x00007fff46af87c2 -[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled] + 83
10 UIKitCore 0x00007fff46afd6d3 -[UIViewController loadViewIfRequired] + 1084
11 UIKitCore 0x00007fff46a6208c -[UINavigationController _updateScrollViewFromViewController:toViewController:] + 160
12 UIKitCore 0x00007fff46a6238c -[UINavigationController _startTransition:fromViewController:toViewController:] + 140
13 UIKitCore 0x00007fff46a63256 -[UINavigationController _startDeferredTransitionIfNeeded:] + 868
14 UIKitCore 0x00007fff46a645c1 -[UINavigationController __viewWillLayoutSubviews] + 150
15 UIKitCore 0x00007fff46a45ffb -[UILayoutContainerView layoutSubviews] + 217
16 UIKitCore 0x00007fff47636722 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2478
17 QuartzCore 0x00007fff2b030ef9 -[CALayer layoutSublayers] + 255
18 QuartzCore 0x00007fff2b0358ff _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 517
19 QuartzCore 0x00007fff2b041fe4 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 80
20 QuartzCore 0x00007fff2af8a4a8 _ZN2CA7Context18commit_transactionEPNS_11TransactionEd + 324
21 QuartzCore 0x00007fff2afbfab3 _ZN2CA11Transaction6commitEv + 643
22 UIKitCore 0x00007fff4717a1e1 __34-[UIApplication _firstCommitBlock]_block_invoke_2 + 81
23 CoreFoundation 0x00007fff23afb8ec __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
24 CoreFoundation 0x00007fff23afb058 __CFRunLoopDoBlocks + 312
25 CoreFoundation 0x00007fff23af5ee4 __CFRunLoopRun + 1284
26 CoreFoundation 0x00007fff23af56b6 CFRunLoopRunSpecific + 438
27 GraphicsServices 0x00007fff3815cbb0 GSEventRunModal + 65
28 UIKitCore 0x00007fff47162a67 UIApplicationMain + 1621
29 Kaerwaradar 0x0000000107e14d1b main + 75
30 libdyld.dylib 0x00007fff5123bcf5 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
The colors are not set properly in iOS 13 light mode.
if #available(iOS 13.0, *) {
let isDark = traitCollection.userInterfaceStyle == .dark
primaryColor = UIFunctions.shared.getPrimaryColor(darkMode: isDark)
secondaryColor = UIFunctions.shared.getSecondaryColor(darkMode: isDark)
} else {
primaryColor = UIFunctions.shared.getPrimaryColor(darkMode: false)
secondaryColor = UIFunctions.shared.getSecondaryColor(darkMode: false)
}