• iOS-夜间模式(换肤设置)


    概述

    iOS 开发中有时候会有夜间模式(换肤设置)的需求, 主要是更改相关颜色操作每次切换夜间/白天模式时,都会发出通知给所有ViewController,让它们切换到相应的主题.

    详细


    一、实现功能及主要思路

    实现功能:

    iOS 开发中有时候会有夜间模式(换肤设置)的需求, 其实主要是更改相关颜色操作.每次切换夜间/白天模式时,都会发出通知给所有ViewController,让它们切换到相应的主题.

    主要思路:

    1. 创建一个管理模式主题的单例管理类ThemeManage

    2. 封装好需要做夜间模式变色处理的控件扩展:UIView (ThemeChange), UINavigationBar (ThemeChange), UITabBar (ThemeChange), UILabel (ThemeChange), UIButton (ThemeChange)

    3. 在 AppDelegate里先获取夜间模式状态, 根控制器里先设置tabBar 及 子控制器里navigationBar的夜间模式状态

    4. 添加控制白天/黑夜模式item,发通知切换相对应i模式及image

    5. 添加相关控件是否黑夜模式下已更换字色和背景色

    二、程序实现

    Step1. 创建一个管理模式主题的单例管理类

    ThemeManage.h 文件里添加模式管理单例:

    // 是否是夜间 YES表示夜间, NO为正常
    @property(nonatomic, assign) BOOL isNight;
    /**
     * 模式管理单例
     */
    + (ThemeManage *)shareThemeManage;

    ThemeManage. m 文件:

    单例的初始化:

    + (ThemeManage *)shareThemeManage {
        
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            themeManage = [[ThemeManage alloc] init];
        });
        return themeManage;
    }

    重写isNight的set方法 (是否是夜间 YES表示夜间, NO为正常)

    - (void)setIsNight:(BOOL)isNight {
        
        _isNight = isNight;
        
        if (self.isNight) { // 夜间模式改变相关颜色
            
            self.bgColor = [UIColor colorWithRed:0.06 green:0.08 blue:0.1 alpha:1];
            self.textColor = [UIColor whiteColor];
            self.color1 = [UIColor colorWithRed:0.08 green:0.11 blue:0.13 alpha:1];
            self.navBarColor = [UIColor whiteColor];
            self.color2 = [UIColor colorWithRed:0.2 green:0.31 blue:0.43 alpha:1];
            self.textColorGray = [UIColor whiteColor];
        } else{
            
            self.bgColor = [UIColor whiteColor];
            self.textColor = [UIColor blackColor];
            self.color1 = [UIColor colorWithRed:0.06 green:0.25 blue:0.48 alpha:1];
            self.navBarColor = [UIColor colorWithRed:0.31 green:0.73 blue:0.58 alpha:1];
            self.color2 = [UIColor colorWithRed:0.57 green:0.66 blue:0.77 alpha:1];
            self.textColorGray = [UIColor grayColor];
        }
        
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            self.colorClear = [UIColor clearColor];
        });
    }

    Step2. 封装好需要做夜间模式变色处理的控件扩展

    一般需要UIView (ThemeChange), UINavigationBar (ThemeChange), UITabBar (ThemeChange), UILabel (ThemeChange), UIButton (ThemeChange);

    详情见 Demo, 这里拿 UIView 做例子:

    添加颜色状态枚举值 颜色的定义(一个代表一套):

    typedef NS_ENUM(NSInteger, UIViewColorType) {
        UIViewColorTypeNormal, // 白天白色, 夜间黑色
        UIViewColorType1, // 白天蓝色, 夜间深灰
        UIViewColorType2, // 白天浅蓝, 夜间浅蓝
        UIViewColorTypeClear // 透明状态
    };

    添加type的set,get方法:

    - (void)setType:(id)type {
        
        objc_setAssociatedObject(self, @selector(type), type, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    - (id)type {
        return objc_getAssociatedObject(self, @selector(type));
    }

    开始监听:

    - (void)startMonitor {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeColor) name:@"changeColor" object:nil];
    }

    改变颜色:

    - (void)changeColor {
        // type为NSNumber型, 变为NSInteger
        switch ([self.type integerValue]) {
            case UIViewColorTypeNormal:
                self.backgroundColor = [ThemeManage shareThemeManage].bgColor;
                break;
            case UIViewColorType1:
                self.backgroundColor = [ThemeManage shareThemeManage].color1;
                break;
            case UIViewColorType2:
                self.backgroundColor = [ThemeManage shareThemeManage].color2;
                break;
            case UIViewColorTypeClear:
                self.backgroundColor = [ThemeManage shareThemeManage].colorClear;
                break;
                
            default:
                break;
        }
        
    }

    设置颜色类型和对应颜色:

    - (void)NightWithType:(UIViewColorType)type {
        
        self.type = [NSNumber numberWithInteger:type];
        [self changeColor];
        [self startMonitor];
        
        // 调用设置字体颜色的方法
        [self initTextColor];
    }

    改变字体颜色的方法, 空方法, 可以在子类中重写这个方法来改变颜色(例如:Label):

    - (void)initTextColor {
        
    }

    Step3. 在 AppDelegate里先获取夜间模式状态, 根控制器里先设置tabBar 及 子控制器里navigationBar的夜间模式状态

    #import "ThemeManage.h"
    #import "UIView+ThemeChange.h"

    获取夜间模式状态:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        
        // 获取夜间模式状态
        [ThemeManage shareThemeManage].isNight = [[NSUserDefaults standardUserDefaults] boolForKey:@"night"];
        
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        self.window.backgroundColor = [UIColor whiteColor];
        [self.window makeKeyAndVisible];
        
        RootViewController *rootVc = [[RootViewController alloc] init];
        self.window.rootViewController = rootVc;
        
        return YES;
    }

    RootViewController.m 文件里设置navigationBar的夜间模式状态:

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        [self.view NightWithType:UIViewColorTypeNormal];
        
        HomeViewController *vc = [[HomeViewController alloc] init];
        UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
        // 设置navigationBar的夜间模式状态
        [nav.navigationBar NightWithType:UIViewColorTypeNormal];
        vc.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"首页" image:[UIImage imageNamed:@"home"] tag:10];
        
        SchemaViewController *secondVC = [[SchemaViewController alloc] init];
        UINavigationController *nav1 = [[UINavigationController alloc] initWithRootViewController:secondVC];
        // 设置navigationBar的夜间模式状态
        [nav1.navigationBar NightWithType:UIViewColorTypeNormal];
        secondVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"菜单" image:[UIImage imageNamed:@"schema"] tag:11];
        
        [self.tabBar NightWithType:UIViewColorTypeNormal];
        self.viewControllers = @[nav, nav1];
        self.tabBar.translucent = NO;
        [[UINavigationBar appearance] setTranslucent:NO];
    }

    Step4. 添加控制白天/黑夜模式item,发通知切换相对应i模式及image

        [self.view NightWithType:UIViewColorTypeNormal];
        
        UIImage *barButtonImage = [ThemeManage shareThemeManage].isNight ? [UIImage imageNamed:@"night"] : [UIImage imageNamed:@"day"];
        self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:barButtonImage style:UIBarButtonItemStylePlain target:self action:@selector(rightBarBtnAction:)];

    Action点击动作事件(切换夜间模式):

    - (void)rightBarBtnAction:(UIBarButtonItem *)barButton {
        
        [ThemeManage shareThemeManage].isNight = ![ThemeManage shareThemeManage].isNight;
        [[NSNotificationCenter defaultCenter] postNotificationName:@"changeColor" object:nil];
        [[NSUserDefaults standardUserDefaults] setBool:[ThemeManage shareThemeManage].isNight forKey:@"night"];
        UIImage *barBtnImage = [ThemeManage shareThemeManage].isNight ? [UIImage imageNamed:@"night"] : [UIImage imageNamed:@"day"];
        [barButton setImage:barBtnImage];
    }

    发了通知不要忘记移除监听:

    - (void)dealloc {
        // 移除监听
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }

    Step5. 添加相关控件是否黑夜模式下已更换字色和背景色

    #import "UILabel+ThemeChange.h"
      UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 200, 40)];
        label.text = @"测试看看字色及背景色";
        [label NightWithType:UIViewColorTypeNormal];
        [label NightTextType:LabelColorGray];
        [self.view addSubview:label];

    三、项目截图及运行效果

    项目截图:

    D4E7C60D-D933-4F01-B306-C17B19A81617.png

    E400F0A1-F882-4AE4-B032-F46A53A3F32E.png

    这时候测试下, 看下运行效果:

    夜间模式.gif

    夜间模式对比截图:

    EA21E87F-09B2-4996-BAEB-FD2C819827B5.png

    四、其他补充

    界面性问题可以根据自己项目需求调整即可, 具体可参考代码, 项目能够直接运行!

    注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

  • 相关阅读:
    做事的底线和逻辑
    我在华为的十年----徐家俊
    华为的冬天
    如何当好一个师长--林彪
    Base64 的那些事儿
    流媒体协议介绍(rtp/rtcp/rtsp/rtmp/mms/hls)
    软件目的需求开发与管理
    车载行业认证资质
    tcpdump抓包分析 https://www.01hai.com/note/av263669
    packages.conifg
  • 原文地址:https://www.cnblogs.com/demodashi/p/8481652.html
Copyright © 2020-2023  润新知