iOS开发之-屏幕适配相关小结-

屏幕适配小结

一、纯手动之Autolayout

1、VFL语言添加约束

  • VFL(Visual format language)语言是苹果为了简化手写Autolayout代码所创建的专门负责编写约束的代码。为我们简化了许多代码量。

2、使用步骤

使用步骤同手动添加约束保持一致

  • 创建控件
  • 添加到父控件
  • 禁用Aoturesizing
  • 添加约束

3、使用方法

  • 这里先展示一个实例:
	NSArray *blueHArr = [NSLayoutConstraint constraintsWithVisualFormat:
	@"H:|-20-[blueView]-20-|"
	options:kNilOptions
 	metrics:nil views:
	NSDictionaryOfVariableBindings(blueView)];

	方法介绍:
	constraintsWithVisualFormat:这个方法返回了一个数组;
	   @"H:|-20-[blueView(100)]-20-|":这句话表明所添加的约束,H的意思是水平方向添加约束,blueView 视图名称,(100)代表着blueView 的宽 
        为100blueView距离父类的左边20,距离父类的右边是20;
	options:是对其方式;
           metrics:返回的是一个字典,它的意思是可以将约束中的值用某些字符串来代理,然后在这个字典中给多对应的字符串赋值
           方便修改,并且增加可读性;
           views:返回的也是一个字典,这个字典的意思是:你可以将前面的view用其他字符串来代替,在这里在给他赋给对应的vie 
           w的名字。
        我可以将上面的约束语句改成如下这样:

		NSArray *blueHArr = [NSLayoutConstraint 
		constraintsWithVisualFormat:@"H:|-aa-[cccc(100)]-20-|"
		options:kNilOptions
        	metrics:@{@"aa":@20}
		views:@{@"cccc":blueView}];
  • 
    
    这里我用aa替换了20,cccc替换了blueVuew
    这里有一个简单的方法,就是使用NSDictionaryOfVariableBindings(blueView)来替换views中的内容也是可以的。

4、VFL的缺点

  • VFL语句不支持乘除法
  • 比如我想表示redview是blueview高度的一半,

    我们是不能这样写的:

    NSArray *redVArr = [NSLayoutConstraint
    constraintsWithVisualFormat:@"V:[blueView]-20-[redView(==blueView*0.5)]"
    options:NSLayoutFormatAlignAllRight
    metrics:nil
    views:NSDictionaryOfVariableBindings(blueView, redView)];

    原因就是这里包含了乘法,而一旦VFL语句中包含了乘除法那么系统就会不识别而崩溃。

  • 所以,当一涉及到乘除法的时候,我们又不得不再次使用系统原来的方法中来:
    NSLayoutConstraint *redWidth = [NSLayoutConstraint
    constraintWithItem:redView
    attribute:NSLayoutAttributeWidth
    relatedBy:NSLayoutRelationEqual
    toItem:blueView
    attribute:NSLayoutAttributeWidth
    multiplier:0.5
    constant:0.0];

5、关于Autolayout还有一个叫Masonry的框架

Masonry 源码:https://github.com/Masonry/Masonry

Masonry是一个轻量级的布局框架 拥有自己的描述语法 采用更优雅的链式语法封装自动布局 简洁明了 并具有高可读性 而且同时支持 iOS 和
Max OS X。

我们先来看一段官方的sample code来认识一下Masonry

	[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
   	 make.edges.equalTo(superview).with.insets(padding);}];

看到block里面的那句话: make edges equalTo superview with insets

通过链式的自然语言 就把view1给autolayout好了。

Masonry是目前最流行的AutoLayout框架.

  • 使用:将Masonry文件包拖入项目,删掉自带的info.plist文件.demo中对Masonry的引用在.pch文件中.
  • 使用Masonry不需要设置

    控件的translatesAutoresizingMaskIntoConstraints属性为NO;

Masonry简单实现

(左下角正方形):
	[targetView mas_makeConstraints:^(MASConstraintMaker *make) {
        	make.bottom.equalTo(self.view).offset(-20);
        	make.leading.equalTo(self.view).offset(20);
        	make.size.mas_equalTo(CGSizeMake(100, 100));
	}];
内边距为50:
  • 第一种实现方式

    make.leading.top.mas_equalTo(@50);
    make.trailing.bottom.mas_equalTo(@-50);
  • 第二种实现方式
    make.edges.insets(UIEdgeInsetsMake(50, 50, 50, 50));

Masonry使用技巧:

定义以下两个宏,在使用Masonry框架时就不需要加mas_前缀了

(定义宏一定要在引入Masonry.h文件之前).

	//define this constant if you want to use Masonry without the ‘mas_‘ prefix
	#define MAS_SHORTHAND
	//define this constant if you want to enable auto-boxing for default syntax
	#define MAS_SHORTHAND_GLOBALS

使用Masonry添加兄弟控件约束不需要考虑父控件.

具体实现代码如下:

	[leftView mas_makeConstraints:^(MASConstraintMaker *make) {
        	make.leading.offset(20);
        	make.bottom.offset(-20);
        	make.trailing.equalTo(rightiew.leading).offset(-20);
        	make.height.equalTo(100);
        	make.height.equalTo(rightiew.height);
    	}];
	[rightiew makeConstraints:^(MASConstraintMaker *make) {
        	make.trailing.equalTo(self.view.trailing).offset(-20);
        	make.top.equalTo(leftView.top);
        	make.width.equalTo(leftView.width);
	}];

二、xib(storyboard)进行约束

如题,利用xib文件为控件添加约束,storyboard方法一样,大家都懂得,之前的Xcode只有xib没有storyboard,storyboard当然会和xib方法一样了,使用xib的时候(记住不要勾选Use
Autolayout  )下面切入正题,如何用xib为控件添加约束。

1.添加约束主要用到下面的三个部分:

从左到右:align、pin、resolve auto layout issues。单词的意思可能有同学不是很理解,不担心,不懂就点开试一下,是什么,一试便知。

(1)、align

第一个模块主要是对齐的,那么对齐就要多个控件对齐,譬如:两个字空间左对齐、下对齐、X轴对齐、字控价和父控件中心对齐等,使用align主要是考虑多个控价对齐问题。

(2)、pin

第二个模块主要是单个控件的属性,控件在父控件中的位置,控件的宽高等,主要是针对一个控件而言的。

(3)、resolve auto layout issues

第三个模块主要是对约束进行编辑的,包括删除,添加,重置约束等。

2.添加约束的几个规则:

情况1:约束控件距离父控件的四周的距离。

第一种比较简单,也比较好理解,一个控件的上下左右的距离都控制好了,控件也就控制好了,如果你切换不同的屏幕时,控件距离屏幕边框的距离不变,会改变控件的大小。

xib中还是正方形的,但是当iPhone的屏幕上,变形了。

此处大家注意一个点,如果你是一个普通控件,像button,image view(已添加图片),label等,这些控件,当我们只给他添加三个约束时,软件不会报错,这是因为控件中有内容,软件会自适应大小,会根据内容的大小来改变控件的大小,这样虽然没有报错,但是控件的大小已经不是我们想要的大小了。。。但是对于一个view来说,你只给他控制三个边,软件会报错的,软件不知道最后一条边距离父控件多远,所以他会报错。所以,要想准确控制一个控件,就要确保确定的大小或者XY值。

情况2:控制控件相邻的两条边距离父控件的距离和控件的宽高。

控制控件相邻的两条边距离,也就控制了控件的左上角的(x,y),控制控件的宽高,也就控制了控件的右下角的(x,y),这样就能控制控件了。

情况3:控件XY轴居中,固定控件宽高。

如果只控件XY轴居中,还是那句话,一般控件像button,image view(已添加图片),label等,软件不会报错,并会自适应大小,但是大小会改变,对于view就会报错,软件给不出控件的大小。

情况4:控件X或Y居中,另一个方向的边距离父控件的距离,宽高。

建议:建议大家在写demo的时候用view,如果用其他的控件,可能会有些问题不报错,但是用view就会暴露出来。

关于xib(storyboard)的适配详细的可以参考下篇博客:

http://justsee.iteye.com/blog/2148987

三、像素适配

以上说的两点都是屏幕大小适配,也就是我们常说的屏幕自适应仅仅只是坐标和大小的适配,避免出现严重的bug和控件溢出等现象,现在要谈的便是像素适配,也就是根据用户所用的机型信息判断出是什么设备,从而提供相应的@xx图片。

目前在iPhone的阵营中,iphone4~6s图片均采用@2x,只有6 plus&6s plus采用@3x。所以可以进行机型的判断从而使用正确的图片。

三种常用的办法获取iOS设备的型号:

1. [UIDevice currentDevice].model (推荐);

2. uname(struct utsname *name) ,使用此函数需要#include ;

3.sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp,

size_t newlen) ,使用此函数需要#include ,#include;

推荐使用第一种方法,为最上层的API,在项目开发中推荐使用高级的API ,因为其识别度高,更简洁易用。2、3两种都是BSD级别的API ,为底层的API,不推荐。

示例:

1. NSString * strModel  = [UIDevice currentDevice].model ;

2. struct utsname systemInfo

uname(&systemInfo)

NSString * strModel = [NSString stringWithCString:systemInfo.machine

encoding:NSUTF8StringEncoding];

3. size_t size

sysctlbyname ("hw.machine" , NULL , &size ,NULL ,0)

char *model = (char *)malloc(size)

sysctlbyname ("hw.machine" , model , &size ,NULL ,0)

NSString * strModel = [NSString stringWithCString: model

encoding:NSUTF8StringEncoding];

获取了设备型号之后,还不能准确的了解其设备类型,还需要找到与其型号对应的设备说明。

该链接为各机型设备信息对应表 :  https://www.theiphonewiki.com/wiki/Models

此外,因为苹果现在的手机的长宽比并未改变依旧是16:9,所以我们可以在准备素材的时候,以点为单位,而不是像素。非矢量素材,就可以做尺寸最大的,之后再进行缩小。比如你需要兼容3x的屏幕,就直接做最高那种图片。因为之后几种机型长宽比都是9:16,可以直接拉伸。已有非矢量素材,直接拉伸放大到@3x。矢量图就直接做点那个尺寸。比如44
x 66个点的按钮。就建立一个44 x 66的场景。之后再导出成2倍图,3倍图,因为矢量放大不失真。不要建立一个3x的场景,导出成大图片,再进行缩小,这样就容易失真。

以下为这方面的资料可以参考一下

《iPhone屏幕适配,历史及现状》http://hjcapple.github.io/2014/10/10/iphone-screen.html

《APP设计师必读-快速适配iPhone6及plus的诀窍》http://www.ui.cn/project.php?id=25685

《iPhone6分辨率与适配》http://www.cocoachina.com/ios/20140912/9601.html

总结:

以后我们再开发的时候,要使用autolayout,减少frame的使用,这样更方便屏幕的适配,要尽量使用点这个单位进行思考,而不要使用像素。比如,你需要做44 x 66个点的按钮,2x模式,就乘以2, 3x模式就乘以3。这样的思考方式可以大致估计到真实的物理长度。44个点,就是手机上导航栏,工具栏的高度。假如用像素思考,容易使得做出的图片过大或者过小。假如是那种导航栏,工具栏之类的背景图,需要横跨整个屏幕。可以只切一小块,让程序拉伸,拉伸方式是保持两边的像素不动,只拉伸最中间的一列像素。需要拉伸的话,横方向就不要出现一些渐变色。

时间: 2024-08-08 04:13:37

iOS开发之-屏幕适配相关小结-的相关文章

iOS开发- 游戏屏幕适配(SpriteKit)

我们开发一个App的时候, 通常希望它在 iPhone, iPad, Mac上同时能运行, 尤其是游戏. 这样就需要我们考虑不同设备不同的分辨率,处理起来比较麻烦. 比如说,按照官方的做法,我们需要提供诸如 xx.png, [email protected], [email protected], xx~iPad.png, and [email protected] 这样不同的图片, 另外还有在程序中写大量 if (...){...} else if {...}这样的代码来区分不同的设备, 想想

Android 尺寸单位转换和屏幕适配相关

一:Android 屏幕适配 众所周知,Android机型尺寸各种各样,于是屏幕适配就成了Android开发中很重要的一环.Android屏幕适配可能一些开发者都会遇到这样的问题,今天就来分享下屏幕适配,其实Android屏幕适配也可以很简单. 基本概念 Android屏幕适配必须要理解的一些概念: px 是英文单词pixel的缩写,意为像素,屏幕上的点.我们通常所说的分辨率如480X800就是指的像素. 在设计领域中,像素是用来计算数码影像的最小单位.计算机中显示的图像并非连续的线条组成,而是

[转]android – 多屏幕适配相关

1.基本概念 屏幕大小(screen size) – 屏幕的实际大小,用屏幕对角线长度来衡量(比如3.4寸,3.8寸).android把屏幕分为以下4种:small,normal,large,extra large.怎么判断? 屏幕密度(Screen Density) -  一 块实际的屏幕区域有多少个像素,一般用dpi衡量(每英寸有多少个点).相比起medium.high屏幕密度的设备,在一块确定大小的屏幕区域l密度为 low的屏幕拥有的像素更少.android把屏幕密度分为4种:low,me

iOS开发系列之四 - UITextView 用法小结

// 初始化输入框并设置位置和大小 UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(10, 10, 300, 180)]; // 设置预设文本 textView.text = @""; // 设置文本字体 textView.font = [UIFont fontWithName:@"Arial" size:16.5f]; // 设置文本颜色 textView.textColor

iOS开发系列之一 - UIButton 用法小结

// 初始化按钮并设置类型 UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; // 能够定义的UIButton类型有以下6种: // typedef enum { // UIButtonTypeCustom = 0, 自定义风格 // UIButtonTypeRoundedRect, 圆角矩形 // UIButtonTypeDetailDisclosure, 蓝色小箭头按钮,主要做详细说明用 // UIButto

iOS 开发之 - iOS6 适配, UITextField 文本,placeholder没有居中对齐

先上一张图: 为了方便观察,我给UITextField设置了一个背景颜色. 是不是赶脚偏了? 通过一个方法解决: _telTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; 如图: 就ok了.. iOS 开发之 - iOS6 适配, UITextField 文本,placeholder没有居中对齐

iOS 开发之 - iOS6适配 - 导航栏按钮透明方法

首先上张图: 1:ios6导航栏默认按钮 rightBarButtonItem   是不是很丑的赶脚? 现在通过以下方法来改变以下:code: UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeCustom]; rightButton.frame = CGRectMake(0, 0, 40, 40); [rightButton setTitle:@"提交" forState:UIControlStateNormal

android - 多屏幕适配相关

1.基本概念 屏幕大小(screen size) – 屏幕的实际大小,用屏幕对角线长度来衡量(比如3.4寸,3.8寸).android把屏幕分为以下4种:small,normal,large,extra large.怎么判断? 屏幕密度(Screen Density) - 一块实际的屏幕区域有多少个像素,一般用dpi衡量(每英寸有多少个点).相比起medium.high屏幕密度的设备,在一块确定大小的屏幕区域l密度为low的屏幕拥有的像素更少.android把屏幕密度分为4种:low,mediu

iOS开发系列之三 - UITextField 用法小结

// 初始化输入框并设置位置和大小 UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 100, 300, 30)]; // 设置输入框提示 textField.placeholder = @"TextField Tip"; // 输入框中预先输入的文字 textField.text = @"预先输入的文字"; // 设置输入框文本的字体 textField.font