美文网首页iOS技术交流收藏
iOS 13下暗黑(深色)模式的配置

iOS 13下暗黑(深色)模式的配置

作者: goyohol | 来源:发表于2019-10-12 17:25 被阅读0次



    暗黑模式在macOS上推出后,又推广到移动端——在iOS 13上正式开放出来!

    其实简单而言就是以前常见App中的夜间模式罢了!只是集成到系统这个单例中去了而已!当然体验自我感觉不是很喜欢(不喜欢太暗色系的😂😂😂😂😂)


    OK,进入主题!开始看看怎么配置iOS 13的暗黑模式!
    在iOS 13(iPadOS 13同理)的设置中,叫"浅色"、"深色"!

    外观:"浅色"、"深色"

    对应的UIUserInterfaceStyle枚举:

    typedef NS_ENUM(NSInteger, UIUserInterfaceStyle) {
        UIUserInterfaceStyleUnspecified,
        UIUserInterfaceStyleLight,
        UIUserInterfaceStyleDark,
    } API_AVAILABLE(tvos(10.0)) API_AVAILABLE(ios(12.0)) API_UNAVAILABLE(watchos);
    


    不适配暗黑模式

    A.整个App都不使用,直接在项目的plist文件中设置——添加"User Interface Style"键,将值设为"UIUserInterfaceStyleLight":

    在"Source Code"中的形式:

    <key>UIUserInterfaceStyle</key> 
    <string>UIUserInterfaceStyleLight</string>
    

    B.各个UIViewController中不使用,设置 if (@available(iOS 13.0, *)){ self.overrideUserInterfaceStyle = UIUserInterfaceStyleLight; }

    设置当前的ViewController为"深色"模式后,此ViewController下的所有view都是"深色"模式!
    由此ViewController所present出来的ViewController是不会受到影响的,依然跟随系统的模式!



    获取当前模式(浅色、深色)
    if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { //当前 "深色"模式
        
    } else { //当前 "浅色"模式
        
    }
    



    颜色(UIColor)的处理:

    A.系统自带的视图设置相应的配色:

    从 iOS 13开始UIColor是一个动态颜色,在"浅色"和"深色"模式下可以分别展示出不同的颜色!以下是iOS 13系统所提供的动态颜色:

    @interface UIColor (UIColorSystemColors)
    
    #pragma mark System colors
    
    /* Some colors that are used by system elements and applications.
     * These return named colors whose values may vary between different contexts and releases.
     * Do not make assumptions about the color spaces or actual colors used.
     */
    @property (class, nonatomic, readonly) UIColor *systemRedColor          API_AVAILABLE(ios(7.0), tvos(9.0)) API_UNAVAILABLE(watchos);
    @property (class, nonatomic, readonly) UIColor *systemGreenColor        API_AVAILABLE(ios(7.0), tvos(9.0)) API_UNAVAILABLE(watchos);
    @property (class, nonatomic, readonly) UIColor *systemBlueColor         API_AVAILABLE(ios(7.0), tvos(9.0)) API_UNAVAILABLE(watchos);
    @property (class, nonatomic, readonly) UIColor *systemOrangeColor       API_AVAILABLE(ios(7.0), tvos(9.0)) API_UNAVAILABLE(watchos);
    @property (class, nonatomic, readonly) UIColor *systemYellowColor       API_AVAILABLE(ios(7.0), tvos(9.0)) API_UNAVAILABLE(watchos);
    @property (class, nonatomic, readonly) UIColor *systemPinkColor         API_AVAILABLE(ios(7.0), tvos(9.0)) API_UNAVAILABLE(watchos);
    @property (class, nonatomic, readonly) UIColor *systemPurpleColor       API_AVAILABLE(ios(9.0), tvos(9.0)) API_UNAVAILABLE(watchos);
    @property (class, nonatomic, readonly) UIColor *systemTealColor         API_AVAILABLE(ios(7.0), tvos(9.0)) API_UNAVAILABLE(watchos);
    @property (class, nonatomic, readonly) UIColor *systemIndigoColor       API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
    
    /* Shades of gray. systemGray is the base gray color.
     */
    @property (class, nonatomic, readonly) UIColor *systemGrayColor         API_AVAILABLE(ios(7.0), tvos(9.0)) API_UNAVAILABLE(watchos);
    
    /* The numbered variations, systemGray2 through systemGray6, are grays which increasingly
     * trend away from systemGray and in the direction of systemBackgroundColor.
     *
     * In UIUserInterfaceStyleLight: systemGray1 is slightly lighter than systemGray.
     *                               systemGray2 is lighter than that, and so on.
     * In UIUserInterfaceStyleDark:  systemGray1 is slightly darker than systemGray.
     *                               systemGray2 is darker than that, and so on.
     */
    @property (class, nonatomic, readonly) UIColor *systemGray2Color        API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
    @property (class, nonatomic, readonly) UIColor *systemGray3Color        API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
    @property (class, nonatomic, readonly) UIColor *systemGray4Color        API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
    @property (class, nonatomic, readonly) UIColor *systemGray5Color        API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
    @property (class, nonatomic, readonly) UIColor *systemGray6Color        API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
    
    #pragma mark Foreground colors
    
    /* Foreground colors for static text and related elements.
     */
    @property (class, nonatomic, readonly) UIColor *labelColor              API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
    @property (class, nonatomic, readonly) UIColor *secondaryLabelColor     API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
    @property (class, nonatomic, readonly) UIColor *tertiaryLabelColor      API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
    @property (class, nonatomic, readonly) UIColor *quaternaryLabelColor    API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
    
    /* Foreground color for standard system links.
     */
    @property (class, nonatomic, readonly) UIColor *linkColor               API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
    
    /* Foreground color for placeholder text in controls or text fields or text views.
     */
    @property (class, nonatomic, readonly) UIColor *placeholderTextColor    API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
    
    /* Foreground colors for separators (thin border or divider lines).
     * `separatorColor` may be partially transparent, so it can go on top of any content.
     * `opaqueSeparatorColor` is intended to look similar, but is guaranteed to be opaque, so it will
     * completely cover anything behind it. Depending on the situation, you may need one or the other.
     */
    @property (class, nonatomic, readonly) UIColor *separatorColor          API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
    @property (class, nonatomic, readonly) UIColor *opaqueSeparatorColor    API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
    
    #pragma mark Background colors
    
    /* We provide two design systems (also known as "stacks") for structuring an iOS app's backgrounds.
     *
     * Each stack has three "levels" of background colors. The first color is intended to be the
     * main background, farthest back. Secondary and tertiary colors are layered on top
     * of the main background, when appropriate.
     *
     * Inside of a discrete piece of UI, choose a stack, then use colors from that stack.
     * We do not recommend mixing and matching background colors between stacks.
     * The foreground colors above are designed to work in both stacks.
     *
     * 1. systemBackground
     *    Use this stack for views with standard table views, and designs which have a white
     *    primary background in light mode.
     */
    @property (class, nonatomic, readonly) UIColor *systemBackgroundColor                   API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
    @property (class, nonatomic, readonly) UIColor *secondarySystemBackgroundColor          API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
    @property (class, nonatomic, readonly) UIColor *tertiarySystemBackgroundColor           API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
    
    /* 2. systemGroupedBackground
     *    Use this stack for views with grouped content, such as grouped tables and
     *    platter-based designs. These are like grouped table views, but you may use these
     *    colors in places where a table view wouldn't make sense.
     */
    @property (class, nonatomic, readonly) UIColor *systemGroupedBackgroundColor            API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
    @property (class, nonatomic, readonly) UIColor *secondarySystemGroupedBackgroundColor   API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
    @property (class, nonatomic, readonly) UIColor *tertiarySystemGroupedBackgroundColor    API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
    
    #pragma mark Fill colors
    
    /* Fill colors for UI elements.
     * These are meant to be used over the background colors, since their alpha component is less than 1.
     *
     * systemFillColor is appropriate for filling thin and small shapes.
     * Example: The track of a slider.
     */
    @property (class, nonatomic, readonly) UIColor *systemFillColor                         API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
    
    /* secondarySystemFillColor is appropriate for filling medium-size shapes.
     * Example: The background of a switch.
     */
    @property (class, nonatomic, readonly) UIColor *secondarySystemFillColor                API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
    
    /* tertiarySystemFillColor is appropriate for filling large shapes.
     * Examples: Input fields, search bars, buttons.
     */
    @property (class, nonatomic, readonly) UIColor *tertiarySystemFillColor                 API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
    
    /* quaternarySystemFillColor is appropriate for filling large areas containing complex content.
     * Example: Expanded table cells.
     */
    @property (class, nonatomic, readonly) UIColor *quaternarySystemFillColor               API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
    
    #pragma mark Other colors
    
    /* lightTextColor is always light, and darkTextColor is always dark, regardless of the current UIUserInterfaceStyle.
     * When possible, we recommend using `labelColor` and its variants, instead.
     */
    @property(class, nonatomic, readonly) UIColor *lightTextColor API_UNAVAILABLE(tvos);    // for a dark background
    @property(class, nonatomic, readonly) UIColor *darkTextColor API_UNAVAILABLE(tvos);     // for a light background
    
    /* groupTableViewBackgroundColor is now the same as systemGroupedBackgroundColor.
     */
    @property(class, nonatomic, readonly) UIColor *groupTableViewBackgroundColor API_DEPRECATED_WITH_REPLACEMENT("systemGroupedBackgroundColor", ios(2.0, 13.0), tvos(13.0, 13.0));
    
    @property(class, nonatomic, readonly) UIColor *viewFlipsideBackgroundColor API_DEPRECATED("", ios(2.0, 7.0)) API_UNAVAILABLE(tvos);
    @property(class, nonatomic, readonly) UIColor *scrollViewTexturedBackgroundColor API_DEPRECATED("", ios(3.2, 7.0)) API_UNAVAILABLE(tvos);
    @property(class, nonatomic, readonly) UIColor *underPageBackgroundColor API_DEPRECATED("", ios(5.0, 7.0)) API_UNAVAILABLE(tvos);
    
    @end
    

    对于ViewController:

    [self.view setBackgroundColor:[UIColor systemBackgroundColor]];
    

    对于UITableviewCell:

    [self.titleLabel setTextColor:[UIColor labelColor]];
    [self.detailLabel setTextColor:[UIColor placeholderTextColor]];
    


    B.自定义的视图设置相应的配色:自定义动态颜色

    + (UIColor *)colorWithDynamicProvider:(UIColor * (^)(UITraitCollection *traitCollection))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
    - (UIColor *)initWithDynamicProvider:(UIColor * (^)(UITraitCollection *traitCollection))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
    
    使用方式如下:
    self.bgView.backgroundColor = [UIColor whiteColor];
    

    在需要处理暗黑模式的地方,再添加上如下代码:(设置相应配色)

    if (@available(iOS 13.0, *)) {
        UIColor * rightColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) {
            if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { //浅色模式
                return [UIColor whiteColor];
            } else { //深色模式
                return [UIColor blackColor];
            }
        }];
        self.bgView.backgroundColor = rightColor; //根据当前模式(光明\暗黑)-展示相应颜色
    }
    



    图片的处理

    在Xcode 11中,为".xcassets"文件带来了更新以自动读取加载"浅色"/"深色"模式的资源(其中的图片)!

    修改资源的Appearances属性,来设置是否要支持"浅色"/"深色"模式及相应的资源内容("浅色"图片/"深色"图片)!在调用“[UIImage imageNamed:@"图片名"]”方法时,会自动加载相应的"浅色"/"深色"资源("浅色"图片/"深色"图片)。

    图片资源的Appearances属性有三个选项:"None"、"Any,Dark""Any,Light,Dark"
    选第二项就够用了("默认"/"深色"模式)!要选第三项进行配置也行("默认"/"浅色"/"深色"模式)!

    选择第二项("默认"/"深色"模式) "浅色"/"深色"模式的效果: "浅色"/"深色"模式下的效果



    模式切换的监听

    在需要监听的viewController中,重写如下方法(得到切换前模式):

    -(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
        [super traitCollectionDidChange:previousTraitCollection];
        
        //previousTraitCollection:之前的模式("浅色"/"深色")
        if (@available(iOS 13.0, *)) {
            switch (previousTraitCollection.userInterfaceStyle) { //之前的模式("浅色"/"深色")
                case UIUserInterfaceStyleUnspecified:{ // 0
                    NSLog(@"previousTraitCollection: UIUserInterfaceStyleUnspecified");
                } break;
                case UIUserInterfaceStyleLight:{
                    NSLog(@"previousTraitCollection: UIUserInterfaceStyleLight");
                } break;
                case UIUserInterfaceStyleDark:{
                    NSLog(@"previousTraitCollection: UIUserInterfaceStyleDark");
                } break;
                default:
                    break;
            }
    
            if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { //当前 "深色"模式
              NSLog(@"now  changedTo TraitCollection: UIUserInterfaceStyleDark");
            } else { //当前 "浅色"模式
              NSLog(@"now  changedTo TraitCollection: UIUserInterfaceStyleLight");
            }
            
            
            //⭐️进行相应的  界面UI调整⭐️
            
        }
    }
    

    “判断两个UITraitCollection对象是否不同”的方法:

    - (BOOL)hasDifferentColorAppearanceComparedToTraitCollection:(UITraitCollection *)traitCollection;
    



    实时观察当前模式(其他方法)

    根据实时返回的trainCollection进行监听方法调用[weakSelf performSelector:@selector(traitCollectionChanged:) withObject:trainCollection];
    以“+ (UIColor *)colorWithDynamicProvider:(UIColor * (^)(UITraitCollection *traitCollection))dynamicProvider”方法为跳板!


     UIColor * rightColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) {
           [weakSelf performSelector:@selector(traitCollectionChanged:) withObject:trainCollection];
           if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) {
               return [UIColor whiteColor];
           } else {
               return [UIColor blackColor];
           }
       }];
    


    对“-(void)traitCollectionChanged:(UITraitCollection *)traitCollection”方法的调用:

    -(void)traitCollectionChanged:(UITraitCollection *)traitCollection{
        if (@available(iOS 13.0, *)) {
            switch (traitCollection.userInterfaceStyle) {
                case UIUserInterfaceStyleUnspecified:{
                    NSLog(@"Now traitCollection: UIUserInterfaceStyleUnspecified");
                } break;
                case UIUserInterfaceStyleLight:{
                    NSLog(@"Now traitCollection: UIUserInterfaceStyleLight");
                } break;
                case UIUserInterfaceStyleDark:{
                    NSLog(@"Now traitCollection: UIUserInterfaceStyleDark");
                } break;
                default:
                    break;
            }
            
            
            //⭐️进行相应的  界面UI调整⭐️
            
        }
    }
    







    已经记不到上次写文章是好久了😂😂😂😂😂
    难的闲下来一次。。。





    goyohol's essay

    相关文章

      网友评论

        本文标题:iOS 13下暗黑(深色)模式的配置

        本文链接:https://www.haomeiwen.com/subject/qxbqmctx.html