一步一步实现iOS主题皮肤切换效果

本文实例为大家分享了iOS主题皮肤切换代码,供大家参考,具体内容如下

1. 主题皮肤功能切换介绍
主题切换就是根据用户设置不同的主题,来动态改变用户的界面,通常会改变navigationBar背景图片、tabBar背景图片、tabBar中的按钮的图片和选中的背景图片、navigationItem.title 标题的字体颜色、UI中其他元素控件

下载源代码地址: http://xiazai.jb51.net/201609/yuanma/ThemeSkinSetup(jb51.net).rar

2.项目目录结构及实现效果截图



3. 具体实现步骤

1.将image文件夹(group)和 Skins拖入到项目工程中的资源文件夹中
2.创建BaseViewController
3.配置theme.plist
4.事项项目所需的基本框架供能,并实现主题的tableView功能
5.创建主题管理器:ThemeManager
6.自定义ThemeTabBarItem 控件
7.创建UI工厂: UIFactory
8. 实现tableView中的didSelected事件完成主题切换
9.记录用户选择的主题,以便用户下次启动时是上次设置的主题

1.创建BaseViewController

#import <UIKit/UIKit.h>
@interface BaseViewController : UIViewController 

- (void) reloadThemeImage;
@end
#import "BaseViewController.h" 

#import "ThemeManager.h"
#import "NotificationMacro.h" 

@interface BaseViewController () 

@end 

@implementation BaseViewController
- (id) init {
 if (self == [super init]) {
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(themeChangedNotfication:) name:kThemeChangedNotification object:nil];
 } 

 [self reloadThemeImage];
 return self;
} 

- (void)viewDidLoad {
 [super viewDidLoad];
 [self reloadThemeImage];
} 

- (void)didReceiveMemoryWarning {
 [super didReceiveMemoryWarning];
 // Dispose of any resources that can be recreated.
} 

- (void) themeChangedNotfication:(NSNotification *)notification {
 [self reloadThemeImage];
} 

- (void) reloadThemeImage {
 ThemeManager * themeManager = [ThemeManager sharedThemeManager]; 

 UIImage * navigationBackgroundImage = [themeManager themeImageWithName:@"navigationbar_background.png"];
 [self.navigationController.navigationBar setBackgroundImage:navigationBackgroundImage forBarMetrics:UIBarMetricsDefault]; 

 UIImage * tabBarBackgroundImage = [themeManager themeImageWithName:@"tabbar_background.png"];
 [self.tabBarController.tabBar setBackgroundImage:tabBarBackgroundImage];
}
@end

2. 实现AppDelegate

#import "AppDelegate.h" 

#import "MainViewController.h"
#import "ThemeManager.h"
#import "NotificationMacro.h" 

@interface AppDelegate () 

@end 

@implementation AppDelegate 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
 [self initUserDefaultConfig]; 

 MainViewController * rootViewController = [[MainViewController alloc] init];
 self.window.rootViewController = rootViewController; 

 return YES;
} 

- (void) initUserDefaultConfig {
 NSString * themeName = [[NSUserDefaults standardUserDefaults] objectForKey:kThemeNameKey];
 ThemeManager * themeManager = [ThemeManager sharedThemeManager];
 themeManager.themeName = themeName;
}</span></span> 
<span style="font-weight: normal;"><span style="font-weight: normal;">#import "MainViewController.h" 

#import "HomeViewController.h"
#import "MessageViewController.h"
#import "MineViewController.h" 

#import "UIFactory.h" 

@interface MainViewController () 

@end 

@implementation MainViewController 

- (id) init {
 if (self = [super init]) {
  [self initTabBarUI];
 } 

 return self;
} 

- (void)viewDidLoad {
 [super viewDidLoad]; 

} 

- (void)didReceiveMemoryWarning {
 [super didReceiveMemoryWarning];
} 

- (void) initTabBarUI {
 // 主页
 HomeViewController * homeViewController = [[HomeViewController alloc] init];
 UINavigationController * homeNavigationController = [[UINavigationController alloc] initWithRootViewController:homeViewController];
// UITabBarItem * homeTabBarItem = [[UITabBarItem alloc] initWithTitle:@"主页" image:[UIImage imageNamed:@"tabbar_home"] selectedImage:[UIImage imageNamed:@"tabbar_home_selected"]];
 UITabBarItem * homeTabBarItem = [UIFactory createTabBarItemWithTitle:@"主页" imageName:@"tabbar_home" selectedImage:@"tabbar_home_selected"];
 homeNavigationController.tabBarItem = homeTabBarItem; 

 // 消息(中心)
 MessageViewController * messageViewController = [[MessageViewController alloc] init];
 UINavigationController * messageNavigationController = [[UINavigationController alloc] initWithRootViewController:messageViewController];
// UITabBarItem * messageTabBarItem = [[UITabBarItem alloc] initWithTitle:@"消息" image:[UIImage imageNamed:@"tabbar_message_center"] selectedImage:[UIImage imageNamed:@"tabbar_message_center_selected"]];
 UITabBarItem * messageTabBarItem = [UIFactory createTabBarItemWithTitle:@"消息" imageName:@"tabbar_message_center" selectedImage:@"tabbar_message_center_selected"];
 messageNavigationController.tabBarItem = messageTabBarItem; 

 // 我
 MineViewController * mineViewController = [[MineViewController alloc] init];
 UINavigationController * mineNavigationController = [[UINavigationController alloc] initWithRootViewController:mineViewController];
// UITabBarItem * mineTabBarItem = [[UITabBarItem alloc] initWithTitle:@"我" image:[UIImage imageNamed:@"tabbar_profile"] selectedImage:[UIImage imageNamed:@"tabbar_profile_selected"]];
 UITabBarItem * mineTabBarItem = [UIFactory createTabBarItemWithTitle:@"我" imageName:@"tabbar_profile" selectedImage:@"tabbar_profile_selected"]; 

 mineNavigationController.tabBarItem = mineTabBarItem;
 NSArray * viewControllers = @[homeNavigationController, messageNavigationController, mineNavigationController];
 self.viewControllers = viewControllers;
} 

@end

3. 创建主题管理器

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> 

@interface ThemeManager : NSObject 

@property (nonatomic, copy) NSString * themeName;   // 主题名字
@property (nonatomic, retain) NSDictionary * themePlistDict; // 主题属性列表字典 

+ (ThemeManager *) sharedThemeManager; 

- (UIImage *) themeImageWithName:(NSString *)imageName;
@end</span></span>
<span style="font-weight: normal;"><span style="font-weight: normal;">#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> 

@interface ThemeManager : NSObject 

@property (nonatomic, copy) NSString * themeName;   // 主题名字
@property (nonatomic, retain) NSDictionary * themePlistDict; // 主题属性列表字典 

+ (ThemeManager *) sharedThemeManager; 

- (UIImage *) themeImageWithName:(NSString *)imageName;
@end
#import "ThemeManager.h"
#import "NotificationMacro.h"
static ThemeManager * sharedThemeManager; 

@implementation ThemeManager 

- (id) init {
 if(self = [super init]) {
  NSString * themePath = [[NSBundle mainBundle] pathForResource:@"theme" ofType:@"plist"];
  self.themePlistDict = [NSDictionary dictionaryWithContentsOfFile:themePath];
  self.themeName = nil;
 } 

 return self;
} 

+ (ThemeManager *) sharedThemeManager {
 @synchronized(self) {
  if (nil == sharedThemeManager) {
   sharedThemeManager = [[ThemeManager alloc] init];
  }
 } 

 return sharedThemeManager;
} 

// Override 重写themeName的set方法
- (void) setThemeName:(NSString *)themeName {
 _themeName = themeName;
} 

- (UIImage *) themeImageWithName:(NSString *)imageName {
 if (imageName == nil) {
  return nil;
 } 

 NSString * themePath = [self themePath];
 NSString * themeImagePath = [themePath stringByAppendingPathComponent:imageName];
 UIImage * themeImage = [UIImage imageWithContentsOfFile:themeImagePath]; 

 return themeImage;
} 

// 返回主题路径
- (NSString *)themePath {
 NSString * resourcePath = [[NSBundle mainBundle] resourcePath];
 if (self.themeName == nil || [self.themeName isEqualToString:@""]) {
  return resourcePath;
 } 

 NSString * themeSubPath = [self.themePlistDict objectForKey:self.themeName]; // Skins/blue
 NSString * themeFilePath = [resourcePath stringByAppendingPathComponent:themeSubPath]; // .../Skins/blue 

 return themeFilePath;
}
@end

4. 创建主题按钮 ThemeTabBarItem

#import <UIKit/UIKit.h>
@interface ThemeTabBarItem : UITabBarItem 

@property (nonatomic, copy) NSString * imageName;
@property (nonatomic, copy) NSString * selectedImageName; 

- (id) initWithTitle:(NSString *)title imageName:(NSString *)imageName selectedImage:(NSString *)selectedImageName; 

@end </span></span>
<span style="font-weight: normal;"><span style="font-weight: normal;">#import "ThemeTabBarItem.h"
#import "ThemeManager.h"
#import "NotificationMacro.h" 

@implementation ThemeTabBarItem 

// 初始化时注册观察者
- (id) init {
 if (self = [super init]) {
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(themeChangedNotification:) name:kThemeChangedNotification object:nil];
 } 

 return self;
} 

- (id) initWithTitle:(NSString *)title imageName:(NSString *)imageName selectedImage:(NSString *)selectedImageName {
 if (self = [self init]) {
  self.title = title;
  self.imageName = imageName;   // 此时会调用[self setImageName:imageName] ---> [self reloadThemeImage] --->[self setImage:image]
  self.selectedImageName = selectedImageName;// 此时会调用[self setSelectedImageName:selectedImageName];
 } 

 return self;
} 

#pragma mark -
#pragma mark - Override Setter
- (void) setImageName:(NSString *)imageName {
 if (_imageName != imageName) {
  _imageName = imageName;
 } 

 [self reloadThemeImage];
} 

- (void) setSelectedImageName:(NSString *)selectedImageName {
 if (_selectedImageName != selectedImageName) {
  _selectedImageName = selectedImageName;
 } 

 [self reloadThemeImage];
} 

// 主题改变之后重新加载图片
- (void)themeChangedNotification:(NSNotification *)notification {
 [self reloadThemeImage];
} 

- (void)reloadThemeImage {
 ThemeManager * themeManager = [ThemeManager sharedThemeManager]; 

 if (self.imageName != nil) {
  UIImage * image = [themeManager themeImageWithName:self.imageName];
  [self setImage:image];
 } 

 if (self.selectedImageName != nil) {
  UIImage * selectedImage = [themeManager themeImageWithName:self.selectedImageName];
  [self setSelectedImage:selectedImage];
 }
} 

- (void) dealloc {
 [[NSNotificationCenter defaultCenter] removeObserver:self];
}

5. 创建UI工厂

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> 

@interface UIFactory : NSObject 

+ (UITabBarItem *) createTabBarItemWithTitle:(NSString *)title imageName:(NSString *)imageName selectedImage:(NSString *)selectedImageName; 

@end</span></span>
<span style="font-weight: normal;"><span style="font-weight: normal;">#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> 

@interface UIFactory : NSObject 

+ (UITabBarItem *) createTabBarItemWithTitle:(NSString *)title imageName:(NSString *)imageName selectedImage:(NSString *)selectedImageName; 

@end
#import "UIFactory.h" 

#import "ThemeTabBarItem.h"
@implementation UIFactory 

+ (UITabBarItem *) createTabBarItemWithTitle:(NSString *)title imageName:(NSString *)imageName selectedImage:(NSString *)selectedImageName {
 ThemeTabBarItem * themeTabBarItem = [[ThemeTabBarItem alloc] initWithTitle:title imageName:imageName selectedImage:selectedImageName]; 

 return themeTabBarItem;
}
@end

6. 实现选中单元格的事件

#import "BaseViewController.h" 

@interface MineViewController : BaseViewController <UITableViewDelegate, UITableViewDataSource> 

@property (weak, nonatomic) IBOutlet UITableView *tableView; 

@property (nonatomic, retain) NSMutableArray * themeDataSource;
@end
#import "BaseViewController.h" 

@interface MineViewController : BaseViewController <UITableViewDelegate, UITableViewDataSource> 

@property (weak, nonatomic) IBOutlet UITableView *tableView; 

@property (nonatomic, retain) NSMutableArray * themeDataSource;
@end
#import "MineViewController.h" 

#import "ThemeManager.h"
#import "NotificationMacro.h" 

@interface MineViewController () 

@end 

@implementation MineViewController 

- (void)viewDidLoad {
 [super viewDidLoad];
 self.title = @"我"; 

 ThemeManager * themeManager = [ThemeManager sharedThemeManager];
 _themeDataSource = [NSMutableArray arrayWithArray:themeManager.themePlistDict.allKeys];
} 

- (void)didReceiveMemoryWarning {
 [super didReceiveMemoryWarning];
 // Dispose of any resources that can be recreated.
} 

#pragma mark -
#pragma mark - UITableViewDelegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 

 return self.themeDataSource.count;
} 

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 static NSString * Identifier = @"Cell";
 UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:Identifier];
 if (cell == nil) {
  cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Identifier];
 } 

 NSString * text = self.themeDataSource[indexPath.row];
 cell.textLabel.text = text; 

 ThemeManager * themeManager = [ThemeManager sharedThemeManager];
 NSString * currentTheme = themeManager.themeName;
 if (currentTheme == nil) {
  currentTheme = @"默认";
 }
 if ([currentTheme isEqualToString:text]) {
  cell.accessoryType = UITableViewCellAccessoryCheckmark;
 } else {
  cell.accessoryType = UITableViewCellAccessoryNone;
 } 

 return cell;
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

 ThemeManager * themeManager = [ThemeManager sharedThemeManager];
 NSString * themeName = self.themeDataSource[indexPath.row]; 

 if ([themeName isEqualToString:@"默认"]) {
  themeName = nil;
 } 

 // 记录当前主题名字
 themeManager.themeName = themeName;
 [[NSNotificationCenter defaultCenter] postNotificationName:kThemeChangedNotification object:nil]; 

 // 主题持久化
 NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
 [userDefaults setObject:themeName forKey:kThemeNameKey];
 [userDefaults synchronize]; 

 // 重新加载数据显示UITableViewCellAccessoryCheckmark 显示选中的对号 v
 [self.tableView reloadData];
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • iOS开发之App主题切换解决方案完整版(Swift版)

    本篇博客就来介绍一下iOS App中主题切换的常规做法,当然本篇博客中只是提到了一种主题切换的方法,当然还有其他方法,在此就不做过多赘述了.本篇博客中所涉及的Demo完全使用Swift3.0编写完成,并使用iOS的NSNotification来触发主题切换的动作.本篇博客我们先对我们的主题系统进行设计,然后给出具体实现方式.当然在我们设计本篇博客所涉及的Demo时,我们要遵循"高内聚,低耦合","面向接口编程","便于维护与扩充"等特点. 本篇博

  • 一步一步实现iOS主题皮肤切换效果

    本文实例为大家分享了iOS主题皮肤切换代码,供大家参考,具体内容如下 1. 主题皮肤功能切换介绍 主题切换就是根据用户设置不同的主题,来动态改变用户的界面,通常会改变navigationBar背景图片.tabBar背景图片.tabBar中的按钮的图片和选中的背景图片.navigationItem.title 标题的字体颜色.UI中其他元素控件 下载源代码地址: http://xiazai.jb51.net/201609/yuanma/ThemeSkinSetup(jb51.net).rar 2.

  • iOS自定义键盘切换效果

    本文实例为大家分享了iOS自定义键盘切换的相关代码,供大家参考,具体内容如下 具体代码如下 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.title = @"小飞哥键盘"; self.textField = [[UITextField alloc] initWithFrame:CGRectMa

  • jQuery无刷新切换主题皮肤实例讲解

    主题皮肤切换功能在很多网站和系统中应用,用户可以根据此功能设置自己喜欢的主题颜色风格,增强了用户体验.本文将围绕如何使用jQuery实现点击无刷新切换主题皮肤功能. 实现该功能的原理就是通过点击定义的主题样式,改变页面当前引用的主题CSS文件,并且将当前的主题样式写入cookie中或者写入数据库中,以便下次该用户重新访问页面时,调用的就是上次设置好的主题样式. 准备主题皮肤样式 首先,我准备了三个样式表CSS文件,分别是三种风格的主题皮肤,将其引入页面,放置在页面的<head>之间. <

  • 一步一步教你网站同步镜像(转载)

    1.介绍 现在的网站随着访问量的增加,单一服务器无法承担巨大的访问量,有没有什么方便快捷的方式解决这个问题呢,答案是"有"!比如建立服务器群,进行均衡负载. 但是如果要解决像电信网通这样的互访问题(中国网民的悲哀..),这个解决办法就无能为了了! 要解决这个问题最方便快捷的方式就是建立镜像网站!由访问者自己选择适合自己网络的速度最快的网站!这样即可以解决线路问题,又可以解决访问量问题! 2.网站同步的数据分类 网站数据基本分为两类: 一类是文件,比如HTML,ASP,PHP等网页文件,

  • 一步一步封装自己的HtmlHelper组件BootstrapHelper(二)

    前言:上篇介绍了下封装BootstrapHelper的一些基础知识,这篇继续来完善下.参考HtmlHelper的方式,这篇博主先来封装下一些常用的表单组件.关于BootstrapHelper封装的意义何在,上篇评论里面已经讨论得太多,这里也不想过多纠结.总之一句话:凡事有得必有失,就看你怎么去取舍.有兴趣的可以看看,没兴趣的权当博主讲了个"笑话"吧. BootstrapHelper系列文章目录 C#进阶系列--一步一步封装自己的HtmlHelper组件:BootstrapHelper

  • 教你一步一步在linux中正确的安装Xcache加速php

    首先,强烈吐槽,百度上的教程,都左复制右复制的,乱七八糟,缺东缺西的.借此微凉大大我提供我苦心整理好的教程.以便各位小菜能顺利的使用Xcache加速php,如果看完了,也操作了,还是失败了的话,请联系微凉大大的QQ 496928838,微凉大大也想看看你是如何一步一步都装不上. #第一步,下载Xcache wget http://xcache.lighttpd.net/pub/Releases/3.1.0/xcache-3.1.0.tar.gz #第一步非常简单,如果你下载不了就是人品问题. #

  • jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera

    要实现可编辑的表格功能,我们要解决以下问题: 1.明确要修改的数据在表格中是哪些列(如何找到这些单元格); 2.如何让单元格变成可以编辑的; 3.如何处理单元格的一些按键事件; 4.解决跨浏览器问题. 我们通过jQuery可以一步一步解决上述问题. 一. 绘制表格 首先我们先画好一个表格. Code1: 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww

  • 一步一步封装自己的HtmlHelper组件BootstrapHelper(三)

    前言:之前的两篇封装了一些基础的表单组件,这篇继续来封装几个基于bootstrap的其他组件.和上篇不同的是,这篇的有几个组件需要某些js文件的支持. BootstrapHelper系列文章目录 C#进阶系列--一步一步封装自己的HtmlHelper组件:BootstrapHelper C#进阶系列--一步一步封装自己的HtmlHelper组件:BootstrapHelper(二) C#进阶系列--一步一步封装自己的HtmlHelper组件:BootstrapHelper(三:附源码) 一.Nu

  • 一步一步跟我学易语言之认识窗口组件和子程序

    认识窗口组件(基本常用组件,扩展组件,外部组件) 看到了吗?易语言自带的组件.你会发现,组件工具箱里没有窗口这个组件,其实窗口是一个最基本的组件,其它组件都包容(画)在窗口上.如果要添加窗口,我们可以到易语言菜单的"插入"项,单击"新窗口".或者到工作夹(下图) 要编写出强大.实用的程序,光有窗口是远远不够的,还要有一些常用的组件,如:编辑框.图片框.外形框.画板.分组框.标签.按钮.选择夹.时钟等.它们的添加方法就要简单的多了.用鼠标左键单击要添加的组件,然后将鼠

  • 详解easyui 切换主题皮肤

    jquery cookie下载地址::http://plugins.jquery.com/cookie/ 1.需要导入的文件(我这里的easyui是jquery-easyui-1.6.11版本) 主要实现原理就是换导入css文件,这样就可以实现切换主题皮肤 <!-- 引入easyui css样式 只需引入easyui.css 其中就包含了其他的内容--> <link rel="stylesheet" id="easyuiTheme" href=&q

随机推荐