转:http://esoftmobile.com/2014/01/14/build-ios6-ios7-apps/

前言

前段时间,苹果在它的开发者网站上放出了iOS系统安装比例,其中iOS7占到78%,iOS6占18%,剩余4%是iOS6以下版本。我们也借此机会将手上正在进行的两个项目都升级到支持iOS6及以上版本呢,有一种幸福来的太突然的赶脚,要知道在此之前我们都还在支持iOS4.3版本。

根据苹果另外一条消息,我们需要按照iOS7风格设计我们的Apps,至于iOS6系统,也没有必要为这部分用户做两份设计,尽量向iOS7风格靠齐吧。由于iOS7简约的风格,基本上通过设置组件的颜色就能够满足大部分色设计需求,所以本文的主要内容会讲iOS6实现iOS7扁平化的一些技巧。

iOS6扁平化

这部分我们主要讲解在iOS6上实现扁平化,各个控制怎么设置。并且大部分通过各个控件 UIAppearance 协议做全局性的设置。

辅助

我们通常要判断不同的系统版本,我是通过下面的宏进行判断的:

#define IOS7_OR_LATER ([[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending)

由于很多地方iOS7可以直接设置颜色,而iOS6却只能设置图片,所以可以使用下面方法直接通过颜色生成一个纯色的图片:

+ (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size
{
CGRect rect = CGRectMake(0, 0, size.width, size.height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect); UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}

布局

iOS7中界面会从屏幕的(0, 0)点开始绘制,所以默认情况下你的内容通常会和 statusBar 和 navigationBar 冲突,如果为了省事的话,或者你的 NavigationBar 和 TabBar压根儿就不透明,那你可以直接给 viewController 的edgesForExtendedLayout 属性值为:UIRectEdgeNone。当然你如果想体现iOS7内容为主的风格,也想将内容显示在半透明的 Bar 下,那你可以严格判断系统版本调整布局了。通常建议将 edgesForExtendedLayout 设置为 UIRectEdgeBottom,这样如果ViewController中为 tableView 或 scrollView 时,内容可以显示到半透明的 tabBar 下,工作量也不是很大。

UINavigationBar

在iOS7风格中,导航栏通常是一个纯色的背景颜色,直接设置 barTintColor 就行,而iOS6中,给导航栏设置tintColor,系统也会默认加上渐变,不够扁平,所以只能设置背景图片了:

//iOS6
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageWithColor:navigationBarColor size:CGSizeMake(1, 44)]
forBarMetrics:UIBarMetricsDefault];

导航栏 title 的颜色也不同,iOS7默认为黑色,而iOS6默认为白色,而且字体大小也不一样,所以还是统一设置标题字体大小、颜色,并去掉文字阴影:

//Universal
[[UINavigationBar appearance] setTitleTextAttributes:
@{ NSForegroundColorAttributeName: [UIColor whiteColor],
NSFontAttributeName: [UIFont boldSystemFontOfSize:20],
UITextAttributeTextShadowOffset: [NSValue valueWithUIOffset:UIOffsetZero]}];

iOS7中导航栏上的按钮已经不被圆角按钮包围了,而iOS6中不管你怎么设置 UIBarButtonItem 的 style 属性都去不掉讨厌的 border,可能很多人会想通过创建 CustomView 类型的 button,其实不用那么麻烦:

//iOS6
[[UIBarButtonItem appearance] setBackgroundImage:[UIImage new]
forState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];

可以看看完成上面三步达到的效果:

 

有人会说,你别高兴得太早,那导航栏的返回按钮怎么办?能去掉iOS6上带剪头和圆角的border吗?这个都搞不定,我还敢在这儿发文章显摆吗?看码:

//iOS6
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:[[UIImage imageNamed:@"buttonItem_back"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 18, 0, 0)]
forState:UIControlStateNormal
barMetrics:UIBarMetricsDefault]; [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(5, 0)
forBarMetrics:UIBarMetricsDefault]; [[UIBarButtonItem appearance] setTitleTextAttributes:
@{ UITextAttributeFont: [UIFont systemFontOfSize:17],
UITextAttributeTextShadowOffset: [NSValue valueWithUIOffset:UIOffsetZero]} forState:UIControlStateNormal];

第一段代码给返回按钮设置一个背景图片,当然这个背景图片就做成和iOS7返回按钮那个剪头一样就好了,  可能文字和剪头靠的太紧,没关系,通过 setBackButtonTitlePositionAdjustment: 设置一下文字的偏移就好了,最后因为iOS6中 BarButtonItem 中的文字比 iOS7 小,所以统一设置一下吧。

 

UITabBar

和 NavigationBar 一样,iOS6中给 TabBar 设置 tintColor 也不够扁平,还是老老实实设置背景图片,并去掉 Tab 选中时的高光效果:

//iOS6
[[UITabBar appearance] setBackgroundImage:[UIImage imageWithColor:RGB(245, 245, 245) size:CGSizeMake(1, 49)]]; [[UITabBar appearance] setSelectionIndicatorImage:[UIImage new]];

iOS6中 Tab 选中后,图片默认会加上高光效果,title默认为白色,而iOS7中默认为选中后图片和文字默认都变为 TabBar 的 tintColor 颜色,所以这里的处理方法是准备两套 tabBarItem 的图标,默认状态和选中状态,iOS7直接调用initWithTitle: image: selectedImage:方法初始化 tabBarItem,iOS6在初始化后,再通过setFinishedSelectedImage: withFinishedUnselectedImage:方法设置默认状态和选中状态下的图标,我通常会给UITabBarItem 增加一个分类,新增一个统一的初始化方法:

@implementation UITabBarItem (Universal)
+ (instancetype)itemWithTitle:(NSString *)title image:(UIImage *)image selectedImage:(UIImage *)selectedImage
{
UITabBarItem *tabBarItem = nil;
if (IOS7_OR_LATER) {
tabBarItem = [[UITabBarItem alloc] initWithTitle:title image:image selectedImage:selectedImage];
} else {
tabBarItem = [[UITabBarItem alloc] initWithTitle:title image:nil tag:0];
[tabBarItem setFinishedSelectedImage:selectedImage withFinishedUnselectedImage:image];
}
return tabBarItem;
}
@end

标题单独设置:

//iOS6
[[UITabBarItem appearance] setTitleTextAttributes:
@{ UITextAttributeTextShadowOffset: [NSValue valueWithUIOffset:UIOffsetMake(0, 0)],
UITextAttributeTextColor: tabBarTintColor }
forState:UIControlStateSelected];

 

UIToolbar

UIToolbar 和 UINavigationBar 相似,建议通过设置背景图片,上面的 item 和 NavigationBar 的 item 设置通用。

UISegmentControl

像 UISegmentControl 通过自定义或者第三方控件,很容易实现 iOS6 和 iOS7 一致风格,如果你就想用系统的控件让 iOS6 实现 iOS7 的风格也不是没有办法。我们可以设置 segment 部分选中状态和非选中状态下的背景图片,segment 之间的分割线图片。因为 iOS6 上 UISegmentControl 的 title 字体比 iOS7 上大,也可以一并做一下修改:

//iOS6
[[UISegmentedControl appearance] setBackgroundImage:[UIImage imageWithColor:selectedColor size:CGSizeMake(1, 29)]
forState:UIControlStateSelected
barMetrics:UIBarMetricsDefault]; [[UISegmentedControl appearance] setBackgroundImage:[UIImage imageWithColor:normalColor size:CGSizeMake(1, 29)]
forState:UIControlStateNormal
barMetrics:UIBarMetricsDefault]; [[UISegmentedControl appearance] setDividerImage:[UIImage imageWithColor:selectedColor size:CGSizeMake(1, 29)]
forLeftSegmentState:UIControlStateNormal
rightSegmentState:UIControlStateSelected
barMetrics:UIBarMetricsDefault]; [[UISegmentedControl appearance] setTitleTextAttributes:@{
UITextAttributeTextColor: selectedColor,
UITextAttributeFont: [UIFont systemFontOfSize:14],
UITextAttributeTextShadowOffset: [NSValue valueWithUIOffset:UIOffsetMake(0, 0)] }
forState:UIControlStateNormal]; [[UISegmentedControl appearance] setTitleTextAttributes:@{
UITextAttributeTextColor: normalColor,
UITextAttributeFont: [UIFont systemFontOfSize:14],
UITextAttributeTextShadowOffset: [NSValue valueWithUIOffset:UIOffsetMake(0, 0)]}
forState:UIControlStateSelected];

通过 appearance 只能到这里了,还差 border 和 小圆角。 鉴于 UISegmentControl 设置还需要每个控件单独设置,所以还是推荐封装一下。

if (!IOS7_OR_LATER) {
self.segmentControl.layer.borderColor = selectedColor;
self.segmentControl.layer.borderWidth = 1.0f;
self.segmentControl.layer.cornerRadius = 4.0f;
self.segmentControl.layer.masksToBounds = YES;
}

 

结束

就写这么多吧,如果没有找到你想拍扁的控件,自己动手吧,如果你懒,那就去 GitHub 上找找吧 :]

ios 统一设计,iOS6也玩扁平化的更多相关文章

  1. 扁平化设计的最新趋势 – 长阴影(Long Shadow)

    随着互联网的发展,网页设计变得越来越复杂,如今设计的外观和感觉实现网站功能说使用的开发技术一样重要.互联网的功能远远不只是基本的信息共享,现在人们对网站的期望是远远大于几年前的. 如今,HTML5 & ...

  2. 腾讯CDC谈扁平化设计

    扁平化设计无疑是当前讨论最多,最火的设计形式,自ios7面世以来更是将扁平化设计的讨论推向风口浪尖. 在这里我不想分析拟物设计和扁平化设计的优劣,更不想说谁更好!在形式服从内容的今天,我只能说哪种设计 ...

  3. AppBox升级进行时 - 扁平化的权限设计

    AppBox 是基于 FineUI 的通用权限管理框架,包括用户管理.职称管理.部门管理.角色管理.角色权限管理等模块. AppBox v2.0中的权限实现 AppBox v2.0中权限管理中涉及三个 ...

  4. 扁平化设计五大原则(转自CSDN翻译)

    Cousins表示他虽然对扁平化设计的感觉非常强烈,但并没有特别热爱或者特别讨厌扁平化设计.他认为好的设计不应当局限于某种设计风格,而需要更注重可用性.有用性.如果因为时尚的缘故,那就顺其自然吧.但该 ...

  5. Android自定义扁平化对话框

    平时我们开发的大多数的Android.iOS的APP,它们的风格都是拟物化设计.如今Android 4.X.iOS 7.WP8采用的是扁平化设计,可以看出扁平化设计是未来UI设计的趋势.其实扁平化设计 ...

  6. Flatty Shadow图标自动产生器——在线生成各种扁平化 ICON

    在扁平化风格越来越流行的今天,网页.软件界面和图标的设计大都采用了扁平化风格.特别是扁平化图标的设计,摒弃了一切3D元素的设计,阴影.纹理.透视神马的统统不要,让图标简洁高效,富有现代感. 今天给大家 ...

  7. PPT扁平化设计总结

    注:以下内容基本都来自知乎,由于已经不记得网址了,所以未能附上所有相关链接,抱歉. PPT扁平化设计原则一.亲密:意思相近的内容放在一起二.对齐:页面上的某两个元素之间总是围绕一条直线对齐三.对比:有 ...

  8. 11款扁平化设计的 Twitter Bootstrap 主题和模板

    扁平化设计和 Bootstrap 框架是2013年网页设计领域的两大设计潮流.把这两者集合起来不是件容易的事情,使用下面这些主题和模板将节省我们的开发时间,因为我们可以修改已有的基础代码,而不是从零开 ...

  9. 16个时髦的扁平化设计的 HTML5 & CSS3 网站模板

    创建网站最好办法之一是使用现成的网站模板或使用开源 CMS 应用程序.所以,今天这篇文章给大家带来的是16款基于 HTML5 & CSS3 的精美的扁平风格网站模板,大家可以借助这些优秀的网站 ...

随机推荐

  1. Linux su命令参数及用法详解--Linux切换用户命令

    建议大家切换用户的时候 使用  su -  root  这样,否则可能发现某些命令执行不了 关于su .su - 及 sudo的区别 请往下看 1.命令作用 su的作用是变更为其它使用者的身份,超级用 ...

  2. asp.net mvc easyui datagrid分页

    提到 asp.net mvc 中的分页,很多是在用aspnetpager,和easyui datagrid结合的分页却不多,本文介绍的是利用easyui 中默认的分页控件,实现asp.net mvc分 ...

  3. Asp.Net MVC中递归死循环问题

    在写代码的时候,很欢乐地发现报错了. An unhandled exception of type 'System.StackOverflowException' occurred in mscorl ...

  4. Cocos2d-x开发---关于安卓打包所遇到的错误记录

         非常久都没有在安卓打过包了.之前的项目因为某些问题没有考虑做安卓版本号,所以涉及到安卓打包的时候都是自己在折腾.      这段时间离职了,空余时间就有非常多了.所以我能够折腾点事了.想起来 ...

  5. jqchart 使用的几点小技巧

    官网demo地址:http://www.jqchart.com/jquery/chart 简单示例: [javascript] $('#jqChart').jqChart({ title: 'jqCh ...

  6. 解决gremlin-dirver访问tinkerpop服务器提示序列化错误

    解决gremlin-dirver访问tinkerpop服务器提示序列化错误 问题描述 程序集成了gremlin-driver,访问远程tinkerpop服务器,在执行创建节点操作时,返回如下错误栈: ...

  7. c3p0 一个数据库链接的例子

    首先需要准备三个依赖包 c3p0-0.9.5.2.jar.mchange-commons-java-0.2.11.jar.mysql-connector-java-5.1.47.jar 下载链接 ht ...

  8. 544. Top k Largest Numbers【medium】

    Given an integer array, find the top k largest numbers in it.   Example Given [3,10,1000,-99,4,100] ...

  9. 0050 MyBatis关联映射--一对多关系

    一对多关系更加常见,比如用户和订单,一个用户可以有多个订单 DROP TABLE IF EXISTS customer; /*用户表*/ CREATE TABLE customer( `pk` INT ...

  10. 动态加载图片的Adapter

    package com.example.cc.ecustapp.Adapter; import android.app.Activity;import android.content.Context; ...