Search code examples
iosswiftsigabrtios13ios-darkmode

Xcode 11 Simulator - SIGABRT when checking for darkmode active


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

Solution

  • 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)
    }