精华内容
下载资源
问答
  • 自定义一个适配暗黑模式的QMUITextField - (instancetype)init { self = [super init]; if (self) {////既然nil解析成NO,所以没有必要在条件语句比较。不要拿某样东西直接与YES比较,因为YES被...

    前言

    • 原文

    https://blog.csdn.net/z929118967/article/details/104293041

    Dark Mode

    2018 年苹果在 macOS 10.14 上加入了深色模式
    深色模式可以显著降低屏幕的整体视觉亮度,减少眼睛的视觉压力。
    在深色模式下,所有的界面元素都退居幕后,使得我们真正与之交互和操作的内容可以被凸显出来。同时随着 OLED屏幕的普及,支持深色模式更有了一定的现实意义:省电
    由于 OLED 屏幕中每个像素都是自主发光而非 LCD 由整个一块背光面板发光,所以在显示深色元素时像素所消耗的电流更低,在纯黑色下像素点可以完全关闭达到省电的效果。

    • 适配暗黑模式的方式1:设置app不支持Dark Mode

    如果使用Apple默认[UIColor WhiteColor]等设置颜色需要注意,如果不设置不支持dark mode则在对应模式下,会改变相关颜色。
    1、设置UITabBarItem上title选择和缺省状态的颜色,使用新的API【self.tabBar.unselectedItemTintColor】
    2、设置状态栏背景颜色的解决方案:使用新的API 【statusBarManager】
    3、状态栏样式适配iOS13的深色模式
    4、自定义视图: 进行统一颜色设置
    在iOS13 的登录界面的输入手机号码和密码的占位符颜色和文本颜色进行统一设置,避免看不见文本颜色。

    • 适配暗黑模式的方式2: 制定深色模式开发规范

    I、设置app不支持Dark Mode

    配置方式有两种,单页面配置 和 全局配置。

    1、 单页配置
    将需要配置的 UIViewControler 对象的 overrideUserInterfaceStyle 属性设置成 UIUserInterfaceStyleLight 或者 UIUserInterfaceStyleDark 以强制是某个页面显示为 浅/深色模式

    2、 全局配置
    在工程的Info.plist的中,增加/修改 UIUserInterfaceStyle为UIUserInterfaceStyleLight或UIUserInterfaceStyleDark

    // info.plist中添加
    User Interface Style [string] Light
    
    

    1.1 设置app不支持Dark Mode

    • 关闭暗黑模式
    	<key>UIUserInterfaceStyle</key>
    	<string>Light</string>
    
    

    1.2 状态栏样式适配iOS13的深色模式

    1.2.1 解决方案

    • 解决方案: 如果iOS系统>13将UIStatusBarStyleDefault修改为UIStatusBarStyleDarkContent
        if (@available(iOS 13.0, *)) {
            [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDarkContent;
        } else {
            [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;
    
            // Fallback on earlier versions
        }
    
    

    在这里插入图片描述

    • 统一封装状态栏样式,并适配iOS13
    /**
     
     1.2 状态栏样式适配iOS13的深色模式
    
     */
    + (void)setupUIStatusBarStyleDefault4ios13{
        
        if (@available(iOS 13.0, *)) {
            [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDarkContent;
        } else {
            [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;
    
            // Fallback on earlier versions
        }
    
    }
    
    + (UIStatusBarStyle)getUIStatusBarStyleDefault4ios13{
        
    
    if (@available(iOS 13.0, *)) {
         return  UIStatusBarStyleDarkContent;
        
    } else {
        
        // Fallback on earlier versions
        return UIStatusBarStyleDefault;
        
    
    }
        
    }
    
    
    

    1.2.2 问题分析过程

    typedef NS_ENUM(NSInteger, UIStatusBarStyle) {
        UIStatusBarStyleDefault                                  = 0, // Automatically chooses light or dark content based on the user interface style
        UIStatusBarStyleLightContent     API_AVAILABLE(ios(7.0)) = 1, // Light content, for use on dark backgrounds
        UIStatusBarStyleDarkContent     API_AVAILABLE(ios(13.0)) = 3, // Dark content, for use on light backgrounds
        
        UIStatusBarStyleBlackTranslucent NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 1,
        UIStatusBarStyleBlackOpaque      NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 2,
    } API_UNAVAILABLE(tvos);
    
    

    如果旧的代码是设置UIStatusBarStyleDefault时,

    当关闭暗黑模式时,状态栏的文字颜色是白色
    当没有关闭暗黑模式时,状态栏的文字颜色是黑色

    因此为了解决这个问题,需要明确指定状态栏的样式为UIStatusBarStyleLightContent或者UIStatusBarStyleDarkContent

    1.3 iOS13适配暗黑模式方案之【状态栏背景颜色】

    1.4 设置UITabBarItem上title颜色

    1.5 自定义一个适配暗黑模式的UITextField

    
    - (instancetype)init {
        self = [super init];
        if (self) {既然nil解析成NO,所以没有必要在条件语句比较。不要拿某样东西直接与YES比较,因为YES被定义为1
            // ...setupUITextField4attributedPlaceholder
            
                    [QCTiOS13Tool setupUITextField4attributedPlaceholder:self];
                    self.textColor =kTextFileColor;
    
    
            
        }
        return self;
    }
    
    
    • 设置占位符颜色
    + (void)setupUITextField4attributedPlaceholder:(UITextField*)textField{
        
                if (@available(iOS 13.0, *)) {
                    
                    
                }else{
                    
                    return;
                }
        
        
        
        textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"placeholder" attributes:@{NSForegroundColorAttributeName:kTextPlaceholderColor, NSFontAttributeName:kTextFont(13) }];
    
        
    //    textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"placeholder" attributes:@{NSForegroundColorAttributeName: [UIColor darkGrayColor], NSFontAttributeName: [UIFont systemFontOfSize:13]}];
    
    }
    
    

    II、 制定深色模式开发规范

    • 页面

    • 文本

    • 图片及icon

    • 导航栏

    • 页面卡

    • 状态栏

    • 当做主题来开发

    1. 首先定制一批颜色:每个颜色都分为亮色模式暗色模式两种
    2. 定义一批图片,亮色和暗色区别
    3. 网络请求图片的处理:如果后台没有这两种,在暗色模式下图片加白边
    4. 导航栏、页面、状态栏、页面卡背景色处理

    2.1 Backwards compatibility for iOS 13 system colors

    2.1.1 巧用系统颜色

    • labelColor :文本颜色
    • secondaryLabelColor : 辅助内容的文本标签颜色
    • tertiaryLabelColor :三级
    • linkColor: 超链接标签颜色
    • separatorColor/opaqueseparatorColor:分隔符(细边框或者分割线)
    • systembackgroundColor :界面背景色

    2.1.2 Table of system colors

    • Dark Mode
    Name Color Hex String RGBA
    label #ffffffff rgba(255.0, 255.0, 255.0, 1.0)
    secondaryLabel #ebebf599 rgba(235.0, 235.0, 245.0, 0.6)
    tertiaryLabel #ebebf54c rgba(235.0, 235.0, 245.0, 0.3)
    quaternaryLabel #ebebf52d rgba(235.0, 235.0, 245.0, 0.18)
    systemFill #7878805b rgba(120.0, 120.0, 128.0, 0.36)
    secondarySystemFill #78788051 rgba(120.0, 120.0, 128.0, 0.32)
    tertiarySystemFill #7676803d rgba(118.0, 118.0, 128.0, 0.24)
    quaternarySystemFill #7676802d rgba(118.0, 118.0, 128.0, 0.18)
    placeholderText #ebebf54c rgba(235.0, 235.0, 245.0, 0.3)
    systemBackground #000000ff rgba(0.0, 0.0, 0.0, 1.0)
    secondarySystemBackground #1c1c1eff rgba(28.0, 28.0, 30.0, 1.0)
    tertiarySystemBackground #2c2c2eff rgba(44.0, 44.0, 46.0, 1.0)
    systemGroupedBackground #000000ff rgba(0.0, 0.0, 0.0, 1.0)
    secondarySystemGroupedBackground #1c1c1eff rgba(28.0, 28.0, 30.0, 1.0)
    tertiarySystemGroupedBackground #2c2c2eff rgba(44.0, 44.0, 46.0, 1.0)
    separator #54545899 rgba(84.0, 84.0, 88.0, 0.6)
    opaqueSeparator #38383aff rgba(56.0, 56.0, 58.0, 1.0)
    link #0984ffff rgba(9.0, 132.0, 255.0, 1.0)
    darkText #000000ff rgba(0.0, 0.0, 0.0, 1.0)
    lightText #ffffff99 rgba(255.0, 255.0, 255.0, 0.6)
    systemBlue #0a84ffff rgba(10.0, 132.0, 255.0, 1.0)
    systemGreen #30d158ff rgba(48.0, 209.0, 88.0, 1.0)
    systemIndigo #5e5ce6ff rgba(94.0, 92.0, 230.0, 1.0)
    systemOrange #ff9f0aff rgba(255.0, 159.0, 10.0, 1.0)
    systemPink #ff375fff rgba(255.0, 55.0, 95.0, 1.0)
    systemPurple #bf5af2ff rgba(191.0, 90.0, 242.0, 1.0)
    systemRed #ff453aff rgba(255.0, 69.0, 58.0, 1.0)
    systemTeal #64d2ffff rgba(100.0, 210.0, 255.0, 1.0)
    systemYellow #ffd60aff rgba(255.0, 214.0, 10.0, 1.0)
    systemGray #8e8e93ff rgba(142.0, 142.0, 147.0, 1.0)
    systemGray2 #636366ff rgba(99.0, 99.0, 102.0, 1.0)
    systemGray3 #48484aff rgba(72.0, 72.0, 74.0, 1.0)
    systemGray4 #3a3a3cff rgba(58.0, 58.0, 60.0, 1.0)
    systemGray5 #2c2c2eff rgba(44.0, 44.0, 46.0, 1.0)
    systemGray6 #1c1c1eff rgba(28.0, 28.0, 30.0, 1.0)
    • Light Mode
    Name Color Hex String RGBA
    label #000000ff rgba(0.0, 0.0, 0.0, 1.0)
    secondaryLabel #3c3c4399 rgba(60.0, 60.0, 67.0, 0.6)
    tertiaryLabel #3c3c434c rgba(60.0, 60.0, 67.0, 0.3)
    quaternaryLabel #3c3c432d rgba(60.0, 60.0, 67.0, 0.18)
    systemFill #78788033 rgba(120.0, 120.0, 128.0, 0.2)
    secondarySystemFill #78788028 rgba(120.0, 120.0, 128.0, 0.16)
    tertiarySystemFill #7676801e rgba(118.0, 118.0, 128.0, 0.12)
    quaternarySystemFill #74748014 rgba(116.0, 116.0, 128.0, 0.08)
    placeholderText #3c3c434c rgba(60.0, 60.0, 67.0, 0.3)
    systemBackground #ffffffff rgba(255.0, 255.0, 255.0, 1.0)
    secondarySystemBackground #f2f2f7ff rgba(242.0, 242.0, 247.0, 1.0)
    tertiarySystemBackground #ffffffff rgba(255.0, 255.0, 255.0, 1.0)
    systemGroupedBackground #f2f2f7ff rgba(242.0, 242.0, 247.0, 1.0)
    secondarySystemGroupedBackground #ffffffff rgba(255.0, 255.0, 255.0, 1.0)
    tertiarySystemGroupedBackground #f2f2f7ff rgba(242.0, 242.0, 247.0, 1.0)
    separator #3c3c4349 rgba(60.0, 60.0, 67.0, 0.29)
    opaqueSeparator #c6c6c8ff rgba(198.0, 198.0, 200.0, 1.0)
    link #007affff rgba(0.0, 122.0, 255.0, 1.0)
    darkText #000000ff rgba(0.0, 0.0, 0.0, 1.0)
    lightText #ffffff99 rgba(255.0, 255.0, 255.0, 0.6)
    systemBlue #007affff rgba(0.0, 122.0, 255.0, 1.0)
    systemGreen #34c759ff rgba(52.0, 199.0, 89.0, 1.0)
    systemIndigo #5856d6ff rgba(88.0, 86.0, 214.0, 1.0)
    systemOrange #ff9500ff rgba(255.0, 149.0, 0.0, 1.0)
    systemPink #ff2d55ff rgba(255.0, 45.0, 85.0, 1.0)
    systemPurple #af52deff rgba(175.0, 82.0, 222.0, 1.0)
    systemRed #ff3b30ff rgba(255.0, 59.0, 48.0, 1.0)
    systemTeal #5ac8faff rgba(90.0, 200.0, 250.0, 1.0)
    systemYellow #ffcc00ff rgba(255.0, 204.0, 0.0, 1.0)
    systemGray #8e8e93ff rgba(142.0, 142.0, 147.0, 1.0)
    systemGray2 #aeaeb2ff rgba(174.0, 174.0, 178.0, 1.0)
    systemGray3 #c7c7ccff rgba(199.0, 199.0, 204.0, 1.0)
    systemGray4 #d1d1d6ff rgba(209.0, 209.0, 214.0, 1.0)
    systemGray5 #e5e5eaff rgba(229.0, 229.0, 234.0, 1.0)
    systemGray6 #f2f2f7ff rgba(242.0, 242.0, 247.0, 1.0)

    2.2 监听当前View或者VC的模式改变

    - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection方法
    监听当前层级模式的变化,并修改相关控件的显示样式。

    see also

    QMUITextField

    展开全文
  • iOS 13 苹果推出了暗黑模式暗黑模式在夜间可以更好保护视力,也可以节省 App 电量消耗。但是 Apple 提供的暗黑模式只支持 iOS 13,为了给用户带来更好体验,我们希望 iOS 13 以下系统也可以支持暗黑模式。...

    Alt
    以下文章来源于京东零售技术,作者平台研发姚琦

    什么是暗黑模式?

    iOS 13 苹果推出了暗黑模式,暗黑模式在夜间可以更好的保护视力,也可以节省 App 电量消耗。但是 Apple 提供的暗黑模式只支持 iOS 13,为了给用户带来更好的体验,我们希望 iOS 13 以下的系统也可以支持暗黑模式。另外我们还给用户提供了自主选择的权利,可以在 App 内手动关闭暗黑模式,不跟随系统主题变化。

    京东 App 涉及业务模块众多,整个适配工作量巨大,为了解决上述问题,并让各模块通过统一的接口快速接入,我们开发了暗黑基础组件,提供以下能力:

    • 支持 iOS 9 及以上系统,同时兼容 iOS 13 系统暗黑模式
    • 支持整体切量、降级
    • 支持跟随系统模式,也可以选择不跟随,使用 App 内部的模式
    • 内置调试工具,帮助开发者快速调试,提升效率
    • 支持颜色模式扩展

    基础组件设计方案如下:
    Alt
    业务接入

    业务接入时需要调用基础组件提供的jdbappearance_bindUpdater方法,传入一个Block并在其中处理UI更新的逻辑,基础组件会绑定Block和UIView,然后将UIView存储在HashTable中,在合适的时机通过遍历HashTable和执行绑定的Block来更新UI。业务组件的接入方案如下:

    Alt

    需要注意的是,遍历HashTable的时候并不是所有的Block都会执行,这里会判断UIView的window是否存在,如果window有值,就执行UIView绑定的Block,否则会先把这个Block标记为稍后执行,当UIView下次出现在window中时(didMoveToWindow 被调用的时候)就会执行这个Block。

    另外不用担心Block会在每次 didMoveToWindow 时被调用,因为只有颜色模式变化的时候,Block才会被标记为稍后执行。

    如果涉及接口调用等异步场景,是否会增加接入成本呢?我们通过下面的代码示例看一下业务是如何进行适配的:

     // 接入前
     cell.viewA.backgroundColor = [UIColor redColor];
     cell.viewB.image = [UIImage imageNamed:@"xxx"];
     
     
     // 接入后
     @weakify(cell)
     [cell jdbappearance_bindUpdater:^(JDBAppearance *apperance, UIView *bindView) {
         @strongify(cell)
        cell.viewA.backgroundColor = [UIColor jdbappearance_colorBR];
        cell.viewB.image = [UIImage jdbappearance_imageNamed:@[@"light_xx", @"dark_xx"]];
    }];
    

    因为每次调用jdbappearance_bindUpdater 时,会立刻执行一次Block,所以不论是否涉及异步场景,接入方式都是统一的,并不会带来额外的接入成本。

    自定义Updater:

    Block机制基本可以满足所有的适配场景,但是实际开发中,我们可能希望有一些便捷的方法,比如直接调用一个方法jd_setBackgroundColor设置UIView的背景色。

    这样的需求也是可以满足的,我们来看一下如何封装这样的API:

     @implementation UIView (CustomUpdater)
     
     
     - (void)jdb_setBackgroundColor:(NSArray *)colors
     {
         [self jdbappearance_bindUpdater:^(JDBAppearance * _Nonnull appearance, UIView * _Nonnull bindView) {
             bindView.backgroundColor = [UIColor jdbappearance_colorWithHex:colors];
         } updaterKey:@"jdb_setBackgroundColor"];
     }
    
    
    @end
    

    注意绑定Block的时候需要指定一个updaterKey,updaterKey允许一个UIView绑定多个Block。使用方式也很简单,并且不需要考虑循环引用的问题:

    [cell jdb_setBackgroundColor:@[@"#FFFFFF", @"#1D1B1B"]];
    

    App内切换暗黑模式

    这个功能允许用户在 App 内手动开启或者关闭暗黑模式,但是存在一个问题:

    如果系统开启了暗黑,但是 App 内关闭了,此时一些系统控件的颜色仍然是深色的(例如通过UIImagePickerController调起的系统相册),从而导致系统控件颜色和 App 颜色不一致。

    在阐述解决方案之前,先来介绍一下UITraitCollection:

    UITraitCollection是 iOS 8 开始新增的一个类,管理着 App 中的用户界面相关的一些系统特征,每个视图都拥有自己的UITraitCollection。

    iOS 13 颜色模式相关的信息,就存储在userInterfaceStyle属性中。如果我们想给视图单独指定userInterfaceStyle,需要使用 iOS 13 新增的 API overrideUserInterfaceStyle,另外设置overrideUserInterfaceStyle是对子视图生效的。

    可是这么多视图,我们应该修改谁的属性呢?下面这张图描述了视图之间的层级关系以及UITraitCollection的传递路线:

    Alt
    UITraitCollection是自上而下传递的,但是 UIScreen 和 UIWindowScene 并未提供 overrideUserInterfaceStyle 这个API,我们只能修改UIWindow的属性,使UIWindow及其所有子视图展示我们设置的颜色:

    • 如果开启了暗黑,将所有window的overrideUserInterfaceStyle设置为
      UIUserInterfaceStyleDark。
    • 如果关闭了暗黑,将所有window的overrideUserInterfaceStyle设置为
      UIUserInterfaceStyleLight。

    如果在 overrideUserInterfaceStyle 修改后,又有新的 window 出现,这种情况要怎么处理呢?我们注册了UIWindowDidBecomeVisibleNotification通知,这个通知会在一个 UIWindow 对象变为可见的时候发出,在接收到通知后,设置这个window的overrideUserInterfaceStyle属性。

    总结:通过修改window的overrideUserInterfaceStyle属性,大多数系统控件的颜色都能和App的颜色保持一致。

    监听系统模式切换

    为什么要提这个呢?用traitCollectionDidChange监听不就可以了吗?

    因为我们发现,在修改overrideUserInterfaceStyle后,当切换系统颜色模式时,window及其子视图的traitCollectionDidChange并没有被调用。

    虽然官方文档中并没有找到明确的说明,但是经过验证,只要我们将window的 overrideUserInterfaceStyle设置为UIUserInterfaceStyleDark 或 UIUserInterfaceStyleLight,window 及其子视图我们都没法监听。只有默认的UIUserInterfaceStyleUnspecified才会生效。

    那怎么办呢?我们刚刚把所有window的 overrideUserInterfaceStyle都改了😂😂😂

    办法总比困难多!仔细来分析一下,我们修改window的overrideUserInterfaceStyle是为了同步修改系统控件的颜色。那我们是不是可以创建一个独立的ObserveWindow,在切换模式的时候,如果是ObserveWindow就跳过,只修改其他window的overrideUserInterfaceStyle。这样就可以在ObserveWindow中实现traitCollectionDidChange方法,处理监听系统模式切换以及更新 App UI 的逻辑:

     @implementatiton ObserveWindow
     
     
     - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
     {
         if (@available(iOS 13.0, *)) {
             if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
                 // 1. 修改 App 内部样式
                 // 2. 修改其他 window 的 overrideUserInterfaceStyle
                // 3. 通知业务更新 UI
            }
        }
    }
    
    
    @end
    

    多任务界面快照

    在适配过程中,我们发现一个问题:在多任务界面,会出现 App 展示的颜色和系统颜色模式刚好相反。

    进一步分析后,发现 App 在进入后台时,traitCollectionDidChange 执行了2次,这两次执行过程中系统的 userInterfaceStyle 分别是 UIUserInterfaceStyleDark 和 UIUserInterfaceStyleLight。

    这是为什么呢?我们查看了下traitCollectionDidChange被调用时的堆栈:

    Alt
    看了堆栈就明白了,系统在进入后台时会创建快照,这个快照其实就是系统多任务界面展示的快照,调用2次是为了分别对深色和浅色进行快照,当进入多任务界面时,系统会根据当前的颜色模式展示正确的快照。

    Alt
    为什么我们会遇到颜色模式相反的问题呢,这里要先介绍一下“跟随系统”的功能:

    App 中有一个开关,用来控制是否跟随系统颜色模式。当用户首次选择切换到暗黑模式,会默认开启跟随系统,此时 App 模式会和系统模式保持一致。如果关闭“跟随系统”的开关,则不再监听系统模式的切换,以 App 内用户选择的模式为准。

    当关闭“跟随系统”的开关后,App 内的颜色模式有可能和系统的不一致,当出现不一致的时候,快照就会出错,比如Dark模式截取了Light模式的图。为了避免这种错误,我们加了一个判断条件,只有“跟随系统”开启的情况下才会开启快照功能。

    修改后的traitCollectionDidChange实现如下:

     -(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
     {
         if (@available(iOS 13.0, *)) {
       UIApplicationState state = [UIApplication sharedApplication].applicationState;
             if (state == UIApplicationStateBackground) {
                 // 系统切换到后台时,会对颜色模式取反截2张图
                 JDBAppearanceManager *manager = [JDBAppearanceManager sharedInstance];
                 if (manager.followSystemMode) {
                     // 如果跟随系统,就更新UI,系统会在UI更新完成后进行快照
                }
            } else {
                // 触发场景:系统控制中心切换模式、后台进入前台、Xcode调试菜单切换模式
    if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
                    // 1. 修改 App 内部样式
                    // 2. 修改其他 window 的 overrideUserInterfaceStyle
                    // 3. 通知业务更新 UI
                }
            }
        }
    }
    

    个性化定制

    基础组件的定位,除了为京东 App 的暗黑模式适配提供支持,我们还希望可以给更多的 App 使用。暗黑基础组件在支持现有功能的基础上,也支持个性化定制功能或者API,接入方可以根据自己的需求灵活选择:

    • App 内部切换开关
    • 多任务快照
    • 自定义 Updater
    • 自定义颜色模式

    希望大家不要重复采坑

    本文详细介绍了京东 App iOS 暗黑模式适配过程中踩过的坑,以及整个方案的实现原理,希望对大家有所帮助。

    欢迎点击“京东智联云”了解更多精彩内容!

    Alt

    Alt

    展开全文
  • 因为iosapp 要求适配暗黑模式APP内嵌H5页面也需要相应暗黑适配,做到根据进入页面时app参数,或者页面内一键切换主题风格 解决方案 已首次进入H5时接收APP传参判断,主题风格 (暗黑模式,正常模式,)为例 在...

    需求:
    因为iosapp 要求适配暗黑模式,APP内嵌H5页面也需要相应的暗黑适配,做到根据进入页面时app参数,或者页面内一键切换主题风格

    解决方案
    已首次进入H5时接收APP传参判断,主题风格 (暗黑模式,正常模式,)为例


    一、通过app传参 dark 字段判断是否为 暗黑模式(主题风格)

    在app.vue onLaunch 中加入判断

    if (this.user && this.user.dark === '1') {
          Vue.prototype.datatheme = 'dark'
          window.document.documentElement.setAttribute('data-theme', 'dark')
        } else {
          Vue.prototype.datatheme = 'light'
          window.document.documentElement.setAttribute('data-theme', 'light')
        }
    

    在app.vue 底部引入base.scss

    <style lang="scss">
      @import "styles/base.scss";
    </style>
    

    二、创建_themes.scss文件

    $themes: (
      light: (
        white: #fff,
        black: #27292d,
        // 主色调1
        main-one: #00A54F,
        // 主色调2
        main-two: #1B88EE
      ),
      dark: (
       white: #27292d,
       black: #fff,
       // 主色调1
       main-one: #00A54F,
       // 主色调2
       main-two: #1B88EE
      )
    )
    

    三、创建base.scss文件

    @import "./_themes.scss"; // 引入_themes.scss
    
    //遍历主题map
    @mixin themeify {
    
      @each $theme-name,
      $theme-map in $themes {
        //!global 把局部变量强升为全局变量
        $theme-map: $theme-map !global;
    
        //这步是判断html的data-theme的属性值  #{}是sass的插值表达式
        //& sass嵌套里的父容器标识   @content是混合器插槽,像vue的slot
        [data-theme="#{$theme-name}"] & {
          @content;
        }
      }
    }
    
    //声明一个根据Key获取颜色的function
    @function themed($key) {
      @return map-get($theme-map, $key);
    }
    
    //获取背景透明度
    @mixin background($color) {
      @include themeify {
        background: themed($color)
      }
    }
    
    @mixin background_imp($color) {
      @include themeify {
        background: themed($color) !important
      }
    }
    
    //获取背景颜色
    @mixin background_color($color) {
      @include themeify {
        background-color: themed($color)
      }
    }
    
    @mixin background_color_imp($color) {
      @include themeify {
        background-color: themed($color) !important
      }
    }
    
    //获取字体颜色
    @mixin font_color($color) {
      @include themeify {
        color: themed($color);
      }
    }
    
    @mixin font_color_imp($color) {
      @include themeify {
        color: themed($color) !important
      }
    }
    
    //获取边框颜色
    @mixin border_color($color) {
      @include themeify {
        border-color: themed($color)
      }
    }
    
    @mixin border_color_imp($color) {
      @include themeify {
        border-color: themed($color) !important
      }
    }
    
    

    注; 方式创建了两种, 考虑到 !important,自己按需使用

    四、scss中使用

    // 字体颜色
    .color-white {
      @include font_color_imp("white")
    }
    
    .color-black {
      @include font_color_imp("black")
    }
    
    
    // 边框颜色
    
    .line-color {
      @include border_color("divider")
    }
    
    
    // 背景颜色
    .bg-black {
      @include background_color_imp("black")
    }
    
    .bg-white {
      @include background_color_imp("white")
    }
    

    以上即为vue切换主题风格的实现原理

    五、页面中判断是否暗黑模式

    在app.vue中已经全局定义了变量 datatheme (Vue.prototype.datatheme = ‘dark’)

    页面中只需 使用 this.datatheme 即可取到风格参数

    :background="datatheme === 'light' ? '#fff' : '#27292d'" 
    

    六,头部导航栏适配主题风格

    定义全局方法,进入页面后设置头部导航栏字体颜色及背景颜色

    function setNavigation () {
      if (store.getters.user.dark === '0') {
        uni.setNavigationBarColor({
          frontColor: '#000000',
          backgroundColor: '#ffffff'
        })
      } else {
        uni.setNavigationBarColor({
          frontColor: '#ffffff',
          backgroundColor: '#27292d'
        })
      }
    }
    

    OK。完成

    学习中遇到问题写博客记录下过程,新手有不对的地方欢迎指教,QQ:1075606525 ,欢迎大家私聊,一起学习一起进步!!!

    展开全文
  • 为了让APP无论是在浅色还是深色模式下,App的UI保持不变 1、全局 在info.plist里面加一个key:UIUserInterfaceStyle,把它值设为Light 2、单个页面不支持 if #available(iOS 13.0, *) { self....

    为了让APP无论是在浅色还是深色模式下,App的UI保持不变

    1、全局

    在info.plist里面加一个key:UIUserInterfaceStyle,把它的值设为Light

    2、单个页面不支持

     if #available(iOS 13.0, *) {
          self.overrideUserInterfaceStyle = .light
      } else {
          // Fallback on earlier versions
      }

    3、根据用户的选择进行暗黑模式适配

    extension UIColor {
        convenience init(light: UIColor, dark: UIColor) {
            self.init(dynamicProvider: { (traits) in
                if traits.userInterfaceStyle == .dark {
                    return dark
                }
                return light
            })
        }
    }

     

    展开全文
  • 背景:iOS13系统提供了暗黑模式,公司各业务线App打算尝试适配iOS13系统暗黑模式。 一、关于图片的适配: 1、本地图片适配:Assets中设置(Any,Dark)类型,可设置两种模式下分别需要显示图片(可兼容iOS低版本...
  • Android App Dark Theme(暗黑模式适配指南

    千次阅读 多人点赞 2020-03-04 10:02:13
    在 2019 年 Google I/O 和 Apple WWDC 上,新露面 Android 10 和 iOS 13 都宣布将支持 Dark Theme 也就是...Android 开发者该如何适配暗黑模式呢?今天这篇文章就告诉你。 Why we need Dark Theme? 暗色主题...
  • IOS 暗黑模式适配前言适配DarkMode一 .图片适配二.颜色适配1.系统动态色值2.定义颜色三. UITextField 适配模式配置一....不过现在很多App开始适配暗黑模式,适配也应该做起来了。顺便整理了一份适配方案,
  • HBuilderX2.6.3+版本开始支持对暗黑模式的适配处理。 全局开启暗黑模式 为了保证应用的兼容性,HBuilderX打包生成的App默认已关闭兼容暗黑模式,需按以下方法配置开启暗黑模式。如果不开启黑暗模式,将无法获取...
  • 原创:liushaohua 百度APP技术团队 一 背景 在2019WWDC开场演讲中,苹果公布了即将推出iOS13 DarkMode新特性。此新特性不仅可以在夜晚保护视力,而且对于使用OLED最新一代设备而言,也可以帮助用户节省电量...
  • 先看一张效果图 实现大致思路: 1、使用一个状态管理器,...3、在打开APP的时候,根据本地存储的标志位,来选择具体的AppTheme。 **首先写一个 全局的状态管理类WSState.dart。 import 'package:ws/redux/theme_redux
  • Android 适配Dark Theme(暗黑模式

    千次阅读 2020-06-10 00:24:32
    Android开发者应该如何让自己的app适配暗黑模式?接下来的文章将一一为你解答。 为什么我们需要暗黑模式 在Android 官方文档中,列举了暗黑模式的三个好处: 可以大大降低功耗(取决于设备的屏幕技术)。 提高了...
  • iOS 详解暗黑模式的关闭与适配

    千次阅读 2020-03-20 11:40:31
    暗黑模式一开启,APP没有适配,然后你发现,你输入白底黑字,变成了白底白字,呈现在面前,就是一片空白,是,你没看错,就是一片空白。 来来来,有图有真相,我们以一叶来洞察整个森林,下面是一毛一样...
  • 根据苹果设计思路,适配暗黑模式是通过UIKit提供基础对象进行颜色和图片控制 一些系统提供控件已经适配了暗黑模式,剩下就是适配我们自己写一些控件特性了。 ###开始适配 一、暂时还未适配 如果你 ...
  • 文章目录引言I 、状态栏背景颜色的适配方案1.1 使用新API 【statusBarManager】1.2 适配特色场景:状态是有透明或者半透明效果场景 引言 设置状态栏背景颜色解决方案:使用新API 【statusBarManager】 I ...
  • Zhujiang |作者承香墨影 |校对https://juejin.im/post/5e95633951882573c2192501 |原文一、前言第一次听到暗黑模式的时候,感觉好酷啊...
  • ####前言 iOS 13 和 Android 10 的发布,暗黑模式让人眼前一亮,...暗黑模式的主色背景是深色,深色背景的优势是 突出与我们主要交互操作的内容 弱化其他辅助元素并降低屏幕整体的亮度减少视觉压力。 很多程序猿也偏
  • 通过上面两篇文章,我们知道了暗黑模式怎么去适配,那么如何结合到真实项目场景中去呢? ###适配目标 在项目适配之前,先来梳理一下需要适配的东西,以及可能预见问题。 一、下图是我们单个App的控件适配目标,...
  • 简介: 《 优酷 APP 全量支持“暗黑...各大APP都将暗黑模式的适配列入了开发日程,舆情上用户们对暗黑模式支持的呼声也非常的高。优酷主客也顺应时势,启动了相应的技术预研。 从2019年11月开始,优酷主客Andro...
  • 现在很多app都开始适配暗黑模式,如何获取状态呢? 暗黑模式其实就是很早之前的阅读类app的黑夜模式,也就是换肤。不过苹果将它集成优化了一下而已。一般长时间浏览的App适合做暗黑模式。像某些APP一般就是查查东西...
  • iOS制作暗黑模式教程

    2020-05-20 14:31:17
    随着iOS13的普及,大多数的APP都已经适配了暗黑模式,网络上关于暗黑模式适配的文章也很多,基本看几篇就能解决掉iOS13暗黑模式的适配。我看了大部分的文章,基本都是对暗黑模式通用的介绍和适配,一些实际项目中的...
  • iOS13 暗黑模式(Dark Mode)适配之OC版

    千次阅读 2019-06-16 19:52:55
    招ios app马甲包套壳上架技术(个人、团队)H5接口、极光推送、关键词、介绍图、标题。能做私聊Q;51286559 iOS马甲包开发审核交流Q群:370868450 首先看看我们效果图: 适配效果图 一、适配Dark Mode ...
  • 各大APP都将“暗黑模式的适配列入了开发日程,舆情上用户们对“暗黑模式”支持呼声也非常高。 为什么要支持“暗黑模式”? “暗黑模式概念主要来源于MacOS,该系统为用户提供两个外观,即"浅色"和"深色"。...
  • 关于暗黑模式

    2020-07-24 09:44:04
    Android客户端AndroidQ开始已经支持暗黑模式了,体验也挺好的,所以一些很多大型的APP也都会对此进行适配适配的方法大致分为两种: 1自定义的方式:新增一套night的文件,根据UI设计对drawable和colors ,style 等...
  • iOS 13 、 Android Q(安卓 10)和部分安卓 9 手机都支持深色外观,苦逼开发者又多了一...如果使用 React Native,可以引用第三方库react-native-dark-mode检测并适配暗黑模式。 useDarkMode 使用useDarkMod...
  • iOS13 不使用暗黑模式

    2020-07-24 14:59:17
    网上google搜到, 关于"不适配深色模式"解决办法都是: 这是写法确实是效,但是上传appstore提交审核,会报错App Store Connect Operation Error ERROR ITMS-90785: App Store Connect Operation Error ERROR...
  • App Store审核规则简要汇总

    千次阅读 2020-08-01 02:50:53
    App Store审核规则简要汇总 提交之前 会发生崩溃、存在错误的 app 会被拒绝。 app 信息及元数据不完整、不正确的 app 会被拒绝。 及时更新有效联系信息。...未适配暗黑模式的 app 会被拒绝。 1、安全 App
  • 如果控件设置颜色为系统提供控件颜色或者背景,那么在暗黑模式下就有可能发生颜色变化,如果没有适配,就会产生适配问题。 禁用 全局禁用 在plist文件中添加NSRequiresAquaSystemAppearance键(值...

空空如也

空空如也

1 2
收藏数 37
精华内容 14
关键字:

适配暗黑模式的app