扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
p 在iOS开发中, 我们可以通过Storyboard或Xib进行可视化界面的布局, 然后使用AutoLayout进行屏幕适配, 此时我们在模拟器上运行是比较费时的, 原因是要切换到不同大小的屏幕上观看样式, 而切换模拟器需要一定的时间, 如果Mac的性能较差, 那就非常痛苦了
南浔网站建设公司创新互联,南浔网站设计制作,有大型网站制作公司丰富经验。已为南浔上1000家提供企业网站建设服务。企业网站搭建\外贸营销网站建设要多少钱,请找那个售后服务好的南浔做网站的公司定做!
p不过Xcode上已经给我们添加了一个不需要切换模拟器就能预览各个屏幕上界面的功能
p以下就是可视化界面布局的预览功能流程图:
效果图
.h
```
@interfaceVMTagsView :UIView
/**
*根据传入的要布局的总宽度和标题数组返回总高度和封装好的view的字典对应key为height tagsview
*
*@param titleArray标题数组
*@param allWidth需要布局的宽度
*
*@return
*/
+ (NSDictionary*)tagsViewForTitleArray:(NSArray*)titleArray andWidth:(CGFloat)allWidth;
/**
*根据传入的布局的总宽度和标题数组返回总高度和下面的init配合使用和上面效果一样
*
*@param titleArray标题数组
*@param allWidth需要布局的宽度
*
*@return总高度
*/
+ (CGFloat)tagsViewHeightForTitleArray:(NSArray*)titleArray andWidth:(CGFloat)allWidth;
- (instancetype)initWithFrame:(CGRect)frame titleArray:(NSArray*)titleArray;
/**
*view上button被点击的block回调 参数为被点击button的序号
*/
@property(nonatomic,copy)void(^buttonClickedBlock)(NSInteger);
@end
```
.m
```
#import"VMTagsView.h"
#define kButtonHeight28
#define KColorFromRGB(rgbValue) \
[UIColor colorWithRed:((float)((rgbValue 0xFF0000) 16))/255.0\
green:((float)((rgbValue 0xFF00) 8))/255.0\
blue:((float)(rgbValue 0xFF))/255.0alpha:1.0]
#define kMainTextGrayColorKColorFromRGB(0x5d5d5d)
#define Font(FONT)[UIFont systemFontOfSize:FONT]
#define kCommenFont14
@interfaceVMTagsView()
/**
*存放创建的button用于取下标或者找对应的button也可以用tag,但我觉得太low
*/
@property(nonatomic,strong)NSMutableArray*buttonArr;
@property(nonatomic)NSIntegerindex;
@end
@implementationVMTagsView
- (NSMutableArray*)buttonArr {
if(!_buttonArr) {
_buttonArr= [[NSMutableArrayalloc]init];
}
return_buttonArr;
}
- (instancetype)initWithFrame:(CGRect)frame titleArray:(NSArray*)titleArray {
self= [superinitWithFrame:frame];
if(self) {
[selfcreatSubviewsWithWidth:frame.size.widthtitleArray:titleArray];
}
returnself;
}
- (CGFloat)creatSubviewsWithWidth:(CGFloat)allWidth titleArray:(NSArray*)titleArray{
CGFloatx =0;
CGFloatnowWidth =0;
CGFloatnextWidth =0;
intnum_per_line =0;//每行btn的个数
intnum_of_line =0;//行数
for(inti =0; i titleArray.count; i ++) {
UIButton*button = [UIButtonbuttonWithType:UIButtonTypeCustom];
//添加到数组内
[self.buttonArraddObject:button];
[buttonaddTarget:selfaction:@selector(buttonAction:)forControlEvents:UIControlEventTouchUpInside];
[buttonsetTitleColor:kMainTextGrayColorforState:UIControlStateNormal];
button.layer.borderColor=KColorFromRGB(0xE1E1E1).CGColor;
button.layer.borderWidth=1;
button.layer.cornerRadius=kButtonHeight/2;
button.layer.masksToBounds=YES;
button.titleLabel.font=Font(kCommenFont);
[buttonsetTitle:titleArray[i]forState:UIControlStateNormal];
[selfaddSubview:button];
CGFloattitleWidth = [VMTagsViewwidthForText:titleArray[i]andFontSize:kCommenFontheight:10];
titleWidth +=15;//给按钮标题距离左右边框留点间距
nextWidth = nextWidth + titleWidth +10;//将要布局下一个按钮的宽度
if(nextWidth allWidth) {
//如果大于限定的宽度置0另起一行
nextWidth =0;
nextWidth = nextWidth + titleWidth;
num_of_line ++;
nowWidth =0;
nowWidth = nowWidth + titleWidth;
num_per_line =0;
button.frame=CGRectMake(x,5+ (kButtonHeight+10) * num_of_line, titleWidth,kButtonHeight);
}else{
button.frame=CGRectMake(x + nowWidth + num_per_line *10,5+ (kButtonHeight+10) * num_of_line, titleWidth,kButtonHeight);
nowWidth = nowWidth + titleWidth;
}
num_per_line ++;
}
return(kButtonHeight+10) * (num_of_line +1);
}
+ (CGFloat)tagsViewHeightForTitleArray:(NSArray*)titleArray andWidth:(CGFloat)allWidth{
CGFloatnowWidth =0;
CGFloatnextWidth =0;
intnum_per_line =0;//每行btn的个数
intnum_of_line =0;//行数
for(inti =0; i titleArray.count; i ++) {
CGFloattitleWidth = [selfwidthForText:titleArray[i]andFontSize:kCommenFontheight:10];
titleWidth +=15;
nextWidth = nextWidth + titleWidth +10;
if(nextWidth allWidth) {
nextWidth =0;
nextWidth = nextWidth + titleWidth;
num_of_line ++;
nowWidth =0;
nowWidth = nowWidth + titleWidth;
num_per_line =0;
}else{
nowWidth = nowWidth + titleWidth;
}
num_per_line ++;
}
CGFloatallheight = (kButtonHeight+10) * (num_of_line +1);
returnallheight;
}
+ (NSDictionary*)tagsViewForTitleArray:(NSArray*)titleArray andWidth:(CGFloat)allWidth {
VMTagsView*tagsview = [[selfalloc]init];
CGFloatheight = [tagsviewcreatSubviewsWithWidth:allWidthtitleArray:titleArray];
return@{@"height":@(height),@"tagsview":tagsview};
}
/**
*点击事件
*
*@param button
*/
- (void)buttonAction:(UIButton*)button {
UIButton*btn = (UIButton*)[self.buttonArrobjectAtIndex:self.index];
[btnsetTitleColor:kMainTextGrayColorforState:UIControlStateNormal];
btn.layer.borderColor=KColorFromRGB(0xE1E1E1).CGColor;
[buttonsetTitleColor:[UIColorredColor]forState:UIControlStateNormal];
button.layer.borderColor= [UIColorredColor].CGColor;
NSIntegerindex = [self.buttonArrindexOfObject:button];
self.buttonClickedBlock(index);
self.index= index;
}
+ (CGFloat)widthForText:(NSString*)text andFontSize:(CGFloat)fontSize height:(CGFloat)height {
NSDictionary*textDic =@{NSFontAttributeName:Font(fontSize)};
CGSizesize = [textboundingRectWithSize:CGSizeMake(0, height)options:NSStringDrawingUsesLineFragmentOriginattributes:textDiccontext:nil].size;
returnsize.width;
}
```
Git: 传送门
以前做android的时候已经觉得布局方便的不行,几种简单的布局容器,再加上停靠和weight,基本所有需求都能满足,后来接触ios开发,一开始还担心自动布局复杂,学习成本高。接触几天后发现,一旦找到窍门,在布局的自由度上更胜android一筹,简直就是想怎么玩就怎么玩。
一:总
自动布局的核心用一句话表示就是:通过各种方法“确定”控件的位置和大小。这里的各种方法就是约束。
二:约束
(1)位置类约束
以上约束来举例,可以设置本控件的上边距离其它控件位置点(位置点包括:上下左右和中间)的距离。这里的距离是一个等式,可以通过这样的方式来理解:y=ax+b;y是最后设置的效果距离值,x是其他控件位置点的距离值,至于a,b都是你可以设置的参数值。使用时,本控件的位置点可以按需自由的参照其他控件的位置点来设置约束。比如,本控件的水平中间点可以等于父容器控件的水平中间点,这样就实现了水平居中。
(2)大小类约束
印象中就三个:宽,高,宽高比
三:最后
位置类约束和大小约束没必要都使用上,只要现有约束已经确定大小和位置了就没必要加冗余约束,会引起冲突。比如,你设置了一个控件的上下左右约束,这时候不仅位置,大小也都确定了。还有文字类的控件(UILabel类),本身就自带大小,所以可以不指定宽高。
待补充。。
状态栏:40px 导航栏:88px 标签栏:98px
状态栏:40px 导航栏:88px 标签栏:98px
状态栏:60px 导航栏:132px 标签栏:147px
状态栏:132px 导航栏:132px 标签栏:147px
状态栏:88px 导航栏:88px 标签栏:98px
全局边距: 32px、30px、24px、20px(建议最小20px,边距数字选择偶数)
卡片间距: 20px、24px、30px、40px(通常上下间距最小不低于16px,过小的间距会造成用户的紧张情绪)
最常用的两种布局方式,列表式和卡片式
「信息」页面通常采用列表式布局。注:列表舒适体验的最小高度是80px,最大高度视内容而定。
例: 微信高度:136px QQ高度:132px 自如高度110px 唯品会高度:106px。
每张卡片的内容和形式都是相互独立的互不干扰。
卡片本身一般是白色,而卡片之间的间距颜色一般是浅色,不同产品风格颜色可能不同。
双栏卡片布局形式,常见于图片信息为主导,每一屏显示至少4张卡片。
常见图片尺寸比例:16:9、4:3、1:1、1:0.618(黄金比例)等
对齐、对称、分组
文字是APP中最核心的元素,是产品传达给用户的主要内容。
在APP中字号范围一般在20-36之间(@2x)。iOS 11中出现了大标题的设计,字号还是要根据产品属性酌情设定。
36px: 用在少数标题。例:导航标题、分类名称等。
32px: 用在少数标题。例:店铺标题等。
30px: 用在较为重要的文字或操作按钮。例:列表性标题分类名称等。
28px: 用于段落文字。例:列表性商品标题等。
26px: 用于段落文字。例:小标题模块描述等。
24px: 用于辅助性文字。例:次要的标语等。
22px: 用于辅助性文字。例:次要的备注信息等。
iOS 主流设备的分辨率分别是:
640x1136px:【(@2x)iPhone SE 】
750 x1134px:【(@2x)iPhone6s/7/8 】
1242x2208px:【(@3x)iPhone 6s/7/8 Plus 】
1125x2436px:【(@3x)iPhone X 】
750x1624px:【(@2x)iPhone X 】
注: 基准设计尺寸:750px x 1334px。
目录:
注意:
- 不管以上那种情况,scrollView 本身的大小和位置一定要相对固定!
- 可以使用frame直接设置,也可以使用自动布局设置。
根据排列组合,共有 2*2 = 4 中情况,下面分别分析:
这种情况没什么好说的,直接设置即可。
这种情况相当于是第四种情况的简化版,故请先看[第四种方式]。
我们知道,只要设置 scrollView 的 contentSize,就限定了 scrollView 的可滚动范围。所以这种情况,并不能很好的根据子控件的变化而动态显示完整的内容。
所以子控件bounds变化的情况,需要使用[第四种方式]设置。
首先来做个分析:
第1条,两种设置方式,自己根据实际情况选择一种即可;
第2条,将所有子视图塞进一个容器视图中。即先给scrollView添加一个 唯一直接子视图 。
通俗点说就是创建一个 sizeView 设置其大小(直接设置frame或者使用autolayout设置皆可),然后将其添加到scrollView的子视图,其他七七八八的所有小子视图都添加在这个直接子视图 sizeView 中,这个直接子视图就相当于 contentView。
这样只要设置这个直接子视图 sizeView 的大小和约束就好了。
如果设置好了这个直接子视图 sizeView 的约束,那么这个直接子视图 sizeView 的范围就是 scrollView 的滚动范围喽!
第3条,其实设置子视图布局就2个要点:
如图1、图2
图2为竖直、水平方向皆可滚动,注意观察滚动条位置。
图2为竖直、水平方向皆可滚动,注意观察滚动条位置。
如此设置布局是不是很方便呢?
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流