Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/99.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS 13.0-支持暗模式和iOS 11&;的最佳方法;12_Ios_Swift_Uistoryboard_Uicolor_Ios13 - Fatal编程技术网

iOS 13.0-支持暗模式和iOS 11&;的最佳方法;12

iOS 13.0-支持暗模式和iOS 11&;的最佳方法;12,ios,swift,uistoryboard,uicolor,ios13,Ios,Swift,Uistoryboard,Uicolor,Ios13,所以我在苹果开发者论坛上发了帖子,但还没有得到回复 背景: iOS 13引入了暗模式和多种系统颜色,具有预定义的明暗变体:() 这些颜色可以作为命名颜色直接在情节提要中使用。它们还作为静态颜色添加到UIColor类:() 但是,添加到UIColor的静态颜色在iOS 11和iOS 12的代码中不可用。这使得使用它们变得很棘手,因为所有对新系统颜色的引用都必须包装在可用性检查中: 它还提出了一个问题:在iOS 11和iOS 12上,当直接在情节提要中使用时,系统颜色将解析为什么?在我们的测试中,

所以我在苹果开发者论坛上发了帖子,但还没有得到回复

背景: iOS 13引入了暗模式和多种系统颜色,具有预定义的明暗变体:()

这些颜色可以作为命名颜色直接在情节提要中使用。它们还作为静态颜色添加到UIColor类:()

但是,添加到UIColor的静态颜色在iOS 11和iOS 12的代码中不可用。这使得使用它们变得很棘手,因为所有对新系统颜色的引用都必须包装在可用性检查中:

它还提出了一个问题:在iOS 11和iOS 12上,当直接在情节提要中使用时,系统颜色将解析为什么?在我们的测试中,他们似乎解决了轻变型,虽然我们还没有测试所有的


当前方法: 这是我们倾向于的方法。我们将向colors.xcasets文件中添加所有颜色,以支持较旧的iOS版本,并通过CustomColors枚举执行单个版本检查和映射,以便根据iOS版本返回正确的UIColor系统颜色。一旦我们放弃对iOS 11和iOS 12的支持,我们将从colors.xcsets中删除相应的颜色,因为我们将只使用系统颜色。 我们还将重构所有故事板,以使用新的系统颜色

这种方法的缺点是:

  • 如果在我们放弃对iOS 11和12的支持(UIColor.label、UIColor.systemBackground等)之后,我们想在代码中直接使用系统颜色,那么要去掉所有枚举引用可能需要进行相当大的重构
  • 因为我们将在故事板中使用系统颜色,所以我们必须确保Colors.xcsets等价物使用相同的颜色代码
  • 此错误:()-如果未修复,则此方法不可用(编辑:此错误已在XCode 11 GM seed 2 11A420a中修复)
  • 与所有资产目录一样,使用魔术字符串访问目录中的项目使开发人员很容易犯错误并得到nil而不是资产(本例中的颜色)。如果我们不测试每个屏幕,这可能会导致很难发现bug,迫使我们编写crashIfAllColorsNotDefined()方法。使用枚举确实可以降低这种风险,因为魔术字符串只存储/使用在一个地方
其他办法:()


问题: 在仍然支持iOS 11和iOS 12的情况下,有哪些其他方法可以通过使用新的系统颜色来支持iOS 13的暗模式?
在旧iOS版本的故事板中使用新的系统颜色安全吗?

最终,Enum和UIColor扩展的组合是一种方法。 自定义颜色有两个“部分”——应用程序的特殊颜色和重复的苹果颜色

苹果发布的一些新颜色仅在iOS13或更高版本中可用(systemBackground、opaqueSeparator、secondaryLabel等)。如果您想立即使用这些颜色,那么必须将它们创建为自定义颜色。这是一个令人担忧的问题,因为它增加了未来的技术债务,因为一旦iOS13成为您支持的最低版本,这些颜色就必须进行重构。这在故事板中尤其难以重构

通过设置此解决方案,可以轻松修改UIColors扩展,以便在稍后阶段返回苹果的官方颜色。您应该只以编程方式设置重复的apple颜色-不要直接在故事板中使用它们

在代码中:

self.backgroundColor = .red1
self.layer.borderColor = UIColor.successGreen1.cgColor
颜色枚举:

// Enum for all custom colors
private enum CustomColors : String, CaseIterable {
    case red1 = "red1"
    case red2 = "red2"
    case blue1 = "blue1"
    case blue2 = "blue2"
    case successGreen1 = "successGreen1"
    case warningOrange1 = "warningOrange1"

    //----------------------------------------------------------------------
    // MARK: - Apple colors
    //----------------------------------------------------------------------

    // Duplicates for new apple colors only available in iOS 13
    case opaqueSeparator = "customOpaqueSeparator"
    case systemBackground = "customSystemBackground"
    case systemGroupedBackground = "customSystemGroupedBackground"
    case secondarySystemGroupedBackground = "customSecondarySystemGroupedBackground"
    case secondaryLabel = "customSecondaryLabel"
    case systemGray2 = "customSystemGray2"
}
UIColor扩展:

// Extension on UIColor for all custom (and unsupported) colors available
extension UIColor {

    //----------------------------------------------------------------------
    // MARK: - Apple colors with #available(iOS 13.0, *) check
    //----------------------------------------------------------------------

    // These can all be removed when iOS13 becomes your minimum supported platform.
    // Or just return the correct apple-defined color instead.

    /// Opaque Seperator color
    static var customOpaqueSeparator: UIColor {
        if #available(iOS 13.0, *) {
            return UIColor.opaqueSeparator
        } else {
            return UIColor(named: CustomColors.opaqueSeparator.rawValue)!
        }
    }

    /// System Background color
    static var customSystemBackground: UIColor {
        if #available(iOS 13.0, *) {
            return UIColor.systemBackground
        } else {
            return UIColor(named: CustomColors.systemBackground.rawValue)!
        }
    }

    /// System Grouped Background color
    static var customSystemGroupedBackground: UIColor {
        if #available(iOS 13.0, *) {
            return UIColor.systemGroupedBackground
        } else {
            return UIColor(named: CustomColors.systemGroupedBackground.rawValue)!
        }
    }

    // more

    //----------------------------------------------------------------------
    // MARK: - My App Custom Colors
    //----------------------------------------------------------------------

    /// Red 1 color
    static var red1: UIColor {
        return UIColor(named: CustomColors.red1.rawValue)!
    }

    /// Red 2 color
    static var red2: UIColor {
        return UIColor(named: CustomColors.red2.rawValue)!
    }

    /// Success Green 1 color
    static var successGreen1: UIColor {
        return UIColor(named: CustomColors.successGreen1.rawValue)!
    }

    // more

    //----------------------------------------------------------------------
    // MARK: - Crash If Not Defined check
    //----------------------------------------------------------------------

    // Call UIColor.crashIfCustomColorsNotDefined() in AppDelegate.didFinishLaunchingWithOptions. If your application 
    // has unit tests, perhaps ensure that all colors exist via unit tests instead.

    /// Iterates through CustomColors enum and check that each color exists as a named color.
    /// Crashes if any don't exist.
    /// This is done because UIColor(named:) returns an optionl. This is bad - 
    /// it means that our code could crash on a particular screen, but only at runtime. If we don't coincidently test that screen
    /// during testing phase, then customers could suffer unexpected behavior.
    static func crashIfCustomColorsNotDefined() {
        CustomColors.allCases.forEach {
           guard UIColor(named: $0.rawValue) != nil else {
            Logger.log("Custom Colors - Color not defined: " + $0.rawValue)
            fatalError()
           }
       }
    }
}
在故事板中:

self.backgroundColor = .red1
self.layer.borderColor = UIColor.successGreen1.cgColor
直接选择自定义颜色,但重复的apple颜色除外

Colors.xcsets:

另请参见故事板和新颜色。谢谢!看起来在故事板中使用新颜色是可靠和安全的