IOS 纯代码 怎么在循环中创建的控件 是它自动布局bootstrap 自适应布局屏幕大小

2261人阅读
ios autolayout(22)
AutoLayout(自动布局)入门
这是博主的WWDC2012笔记系列中的一篇,完整的笔记列表可以参看。如果您是首次来到本站,也许您会有兴趣通过,或者通过页面左侧的邮件订阅的方式订阅本站。
AutoLayout在去年的WWDC上被引入Cocoa,而在今年的WWDC上,Apple不惜花费了三个Session的前所未见的篇幅来详细地向开发者讲解AutoLayout在iOS上的应用,是由起原因的:iPhone5的屏幕将变为4寸,开发者即将面临为不同尺寸屏幕进行应用适配的工作。Android平台开发中最令人诟病的适配工作的厄运现在似乎也将降临在iOS开发者的头上。基于这样的情况,Apple大力推广使用AutoLayout的方法来进行UI布局,以一举消除适配的烦恼。AutoLayout将是自Interface
Builder和StoryBoard之后UI制作上又一次重要的变化,也必然是之后iOS开发的趋势,因此这个专题很值得学习。
AutoLayout是什么?
使用一句Apple的官方定义的话
AutoLayout是一种基于约束的,描述性的布局系统。 Auto Layout Is a Constraint-Based, Descriptive Layout System.
基于约束 - 和以往定义frame的位置和尺寸不同,AutoLayout的位置确定是以所谓相对位置的约束来定义的,比如x坐标为superView的中心,y坐标为屏幕底部上方10像素等
描述性 - 约束的定义和各个view的关系使用接近自然语言或者可视化语言(稍后会提到)的方法来进行描述
布局系统 - 即字面意思,用来负责界面的各个元素的位置。
总而言之,AutoLayout为开发者提供了一种不同于传统对于UI元素位置指定的布局方法。以前,不论是在IB里拖放,还是在代码中写,每个UIView都会有自己的frame属性,来定义其在当前视图中的位置和尺寸。使用AutoLayout的话,就变为了使用约束条件来定义view的位置和尺寸。这样的最大好处是一举解决了不同分辨率和屏幕尺寸下view的适配问题,另外也简化了旋转时view的位置的定义,原来在底部之上10像素居中的view,不论在旋转屏幕或是更换设备(iPad或者iPhone5或者以后可能出现的mini
iPad)的时候,始终还在底部之上10像素居中的位置,不会发生变化。
使用约束条件来描述布局,view的frame会依据这些约束来进行计算 Describe the layout with constraints, and frames are calculated automatically.
AutoLayout和Autoresizing Mask的区别
Autoresizing Mask是我们的老朋友了…如果你以前一直是代码写UI的话,你肯定写过UIViewAutoresizingFlexibleWidth之类的枚举;如果你以前用IB比较多的话,一定注意到过每个view的size inspector中都有一个红色线条的Autoresizing的指示器和相应的动画缩放的示意图,这就是Autoresizing Mask。在iOS6之前,关于屏幕旋转的适配和iPhone,iPad屏幕的自动适配,基本都是由Autoresizing Mask来完成的。但是随着大家对iOS
app的要求越来越高,以及已经以及今后可能出现的多种屏幕和分辨率的设备来说,Autoresizing Mask显得有些落伍和迟钝了。AutoLayout可以完成所有原来Autoresizing Mask能完成的工作,同时还能够胜任一些原来无法完成的任务,其中包括:
AutoLayout可以指定任意两个view的相对位置,而不需要像Autoresizing Mask那样需要两个view在直系的view hierarchy中。
AutoLayout不必须指定相等关系的约束,它可以指定非相等约束(大于或者小于等);而Autoresizing Mask所能做的布局只能是相等条件的。
AutoLayout可以指定约束的优先级,计算frame时将优先按照满足优先级高的条件进行计算。
Autoresizing Mask是AutoLayout的子集,任何可以用Autoresizing Mask完成的工作都可以用AutoLayout完成。AutoLayout还具备一些Autoresizing Mask不具备的优良特性,以帮助我们更方便地构建界面。
AutoLayout基本使用方法
Interface Builder
最简单的使用方法是在IB中直接拖。在IB中任意一个view的File inspector下面,都有Use Autolayout的选择框(没有的同学可以考虑升级一下Xcode了=。=),钩上,然后按照平常那样拖控件就可以了。拖动控件后在左边的view hierarchy栏中会出现Constraints一向,其中就是所有的约束条件。
选中某个约束条件后,在右边的Attributes inspector中可以更改约束的条件,距离值和优先度等:&
对于没有自动添加的约束,可以在IB中手动添加。选择需要添加约束的view,点击菜单的Edit-&Pin里的需要的选项,或者是点击IB主视图右下角的按钮,即可添加格外的约束条件。
可视化的添加不仅很方便直观,而且基本不会出错,是优先推荐的添加约束的方式。但是有时候只靠IB是无法完成某些约束的添加的(比如跨view hierarchy的约束),有时候IB添加的约束不能满足要求,这时就需要使用约束的API进行补充。
手动使用API添加约束
iOS6中新加入了一个类:NSLayoutConstraint,一个形如这样的约束
item1.attribute = multiplier ? item2.attribute + constant
对应的代码为
[NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-padding]
这对应的约束是“button的底部(y) = superview的底部 -10”。
在创建约束之后,需要将其添加到作用的view上。UIView(当然NSView也一样)加入了一个新的实例方法:
-(void)addConstraint:(NSLayoutConstraint *) 用来将约束添加到view。在添加时唯一要注意的是添加的目标view要遵循以下规则:
对于两个同层级view之间的约束关系,添加到他们的父view上
* 对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上
* 对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上
可以通过-setNeedsUpdateConstraints和-layoutIfNeeded两个方法来刷新约束的改变,使UIView重新布局。这和CoreGraphic的-setNeedsDisplay一套东西是一样的~
Visual Format Language 可视格式语言
UIKit团队这次相当有爱,估计他们自己也觉得新加约束的API名字太长了,因此他们发明了一种新的方式来描述约束条件,十分有趣。这种语言是对视觉描述的一种抽象,大概过程看起来是这样的:
accept按钮在cancel按钮右侧默认间距处
最后使用VFL(Visual Format Language)描述变成这样:
[NSLayoutConstraint constraintsWithVisualFormat:@&[cancelButton]-[acceptButton]&
metrics:nil
views:viewsDictionary];&/pre&
其中viewsDictionary是绑定了view的名字和对象的字典,对于这个例子可以用以下方法得到对应的字典:
UIButton *cancelButton = ...
UIButton *acceptButton = ...
viewsDictionary = NSDictionaryOfVariableBindings(cancelButton,acceptButton);
生成的字典为
acceptButton = &&; cancelButton = &&; }
当然,不嫌累的话自己手写也未尝不可。现在字典啊数组啊写法相对简化了很多了,因此也不复杂。关于Objective-C的新语法,可以参考我之前的一篇WWDC 2012笔记:。
在view名字后面添加括号以及连接处的数字可以赋予表达式更多意义,以下进行一些举例:
[cancelButton(72)]-12-[acceptButton(50)]
取消按钮宽72point,accept按钮宽50point,它们之间间距12point
[wideView(&=60@700)]
wideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束越先被满足)
V:[redBox][yellowBox(==redBox)]
竖直布局,先是一个redBox,其下方紧接一个宽度等于redBox宽度的yellowBox
H:|-[Find]-[FindNext]-[FindField(&=20)]-|
水平布局,Find距离父view左边缘默认间隔宽度,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘的间距都是默认宽度。(竖线'|‘ 表示superview的边缘)
容易出现的错误
因为涉及约束问题,因此约束模型下的所有可能出现的问题这里都会出现,具体来说包括两种:
Ambiguous Layout 布局不能确定
Unsatisfiable Constraints 无法满足约束
布局不能确定指的是给出的约束条件无法唯一确定一种布局,也即约束条件不足,无法得到唯一的布局结果。这种情况一般添加一些必要的约束或者调整优先级可以解决。无法满足约束的问题来源是有约束条件互相冲突,因此无法同时满足,需要删掉一些约束。两种错误在出现时均会导致布局的不稳定和错误,Ambiguous可以被容忍并且选择一种可行布局呈现在UI上,Unsatisfiable的话会无法得到UI布局并报错。
对于不能确定的布局,可以通过调试时暂停程序,在debugger中输入
po [[UIWindow keyWindow] _autolayoutTrace]
来检查是否存在Ambiguous Layout以及存在的位置,来帮助添加条件。另外还有一些检查方法,来查看view的约束和约束状态:
[view constraintsAffectingLayoutForOrientation/Axis: NSLayoutConstraintOrientationHorizontal/Vertical]
[view hasAmbiguousLayout]
[view exerciseAmbiguityInLayout]
日作者更新:在iOS7和Xcode5中,IB在添加和检查Autolayout约束方面有了长足的进步。现在使用IB可以比较容易地完成复杂约束,而得益于新的IB的约束检查机制,我们也很少再会遇到遗漏或者多余约束情况的出现(有问题的约束条件将直接在IB中得到错误或者警告)。但是对于确实很奇葩的约束条件有可能使用IB无法达成,这时候还是有可能需要代码补充的。
动画是UI体验的重要部分,更改布局以后的动画也非常关键。说到动画,Core Animation又立功了..自从CA出现以后,所有的动画效果都非常cheap,在auto layout中情况也和collection view里一样,很简单(可以参考),只需要把layoutIfNeeded放到animation block中即可~
[UIView animateWithDuration:0.5 animations:^{
[view layoutIfNeeded];
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:931179次
积分:8378
积分:8378
排名:第1575名
原创:11篇
转载:285篇
评论:106条
(1)(3)(1)(4)(1)(5)(3)(4)(9)(40)(23)(52)(22)(11)(15)(3)(22)(35)(2)(2)(22)(2)(1)(1)(7)(3)(6)(6)(3)(5)(18)(23)(4)(1)主题 : IOS 纯代码 怎么在循环中创建的控件 是它自动布局适应屏幕大小?
级别: 新手上路
可可豆: 44 CB
威望: 46 点
在线时间: 33(时)
发自: Web Page
来源于&&分类
IOS 纯代码 怎么在循环中创建的控件 是它自动布局适应屏幕大小?&&&
这个Cell中的每一个产品信息是一个UIView。它是根据数组大小来决定的。所以需要代码设定。问题就是我如何设定UIView创建的时候与下一个UIView的间距呢。如何自适应屏幕?这个布局是我通过计算屏幕的宽度除以3得来的。但是在5s中布局展示出来的画面就不理想了。看下图!看到5s的结果很拥挤。间距不能像6那么宽。但是纯代码如何布局?查了之后代码布局可以使用开源框架Masonry嬀/color]但是对这个框架本身不够那么理解。使用只会简单的调调。 所以想问各位大神。我该如何写才能实现屏幕适配宽度。(附上代码)- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier Array:(NSArray *)array {    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];    if (self) {               UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, AppWidth, 220)];        scrollView.delegate =        scrollView.pagingEnabled = YES;        scrollView.showsHorizontalScrollIndicator = NO;        NSInteger scrollCount = 0;        if (array.count % 3 == 0) {            scrollCount = round(array.count / 3);        }else {            scrollCount = round(array.count / 3 + 0.5);        }               scrollView.contentSize = CGSizeMake(scrollCount * AppWidth, 220);        [self addSubview:scrollView];        NSInteger key = 0;        for (NSInteger i = 0; i & scrollC i++) {            UIView *view = [[UIView alloc]initWithFrame:CGRectMake(AppWidth * i, 0, AppWidth, 200)];            [scrollView addSubview:view];            [view mas_makeConstraints:^(MASConstraintMaker *make) {                //make.left.equalTo(scrollView.mas_right).with.multipliedBy(5);                //make.right.equalTo(scrollView.mas_right).offset(20);            }];            for (NSInteger j = j & array.) {                                CGRect frame = CGRectMake((j - key)* AppWidth / 3 - 28, 0, AppWidth / 3, 200);                SsCartLine *model = array[j];                SSRecommentBtnView *btnView = [[SSRecommentBtnView alloc] initWithFrame:frame title:model.ssTongchou.projectName imageStr:model.ssTongchou.orderTitlePic printStr:[ToolsClass setupPrice:model.ssTongchou.curPrice]];                btnView.tag = 10 +                [view addSubview:btnView];                UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(OnTapBtnView:)];                [btnView addGestureRecognizer:tap];                j++;                if (j % 3 == 0 && j != 0) {                                    }            }            key += 3;        }        _pageControl = [[UIPageControl alloc] init];        _pageControl.currentPage = 0;        _pageControl.numberOfPages = scrollC        _pageControl.currentPageIndicatorTintColor = navigationBarC        _pageControl.pageIndicatorTintColor = [UIColor grayColor];        _pageControl.enabled = YES;        [self addSubview:_pageControl];        [_pageControl mas_makeConstraints:^(MASConstraintMaker *make) {            make.centerX.equalTo(self);            make.bottom.equalTo(self.mas_bottom).with.offset(10);            make.size.mas_equalTo(CGSizeMake(0, 20));        }];           }    } [ 此帖被lxkbest在 18:54重新编辑 ]
级别: 新手上路
可可豆: 44 CB
威望: 46 点
在线时间: 33(时)
发自: Web Page
级别: 新手上路
可可豆: 44 CB
威望: 46 点
在线时间: 33(时)
发自: Web Page
级别: 侠客
可可豆: 507 CB
威望: 507 点
在线时间: 277(时)
发自: Web Page
图看不到&&你重新传一下
级别: 侠客
UID: 450994
可可豆: 1017 CB
威望: 651 点
在线时间: 598(时)
发自: Web Page
試試UICollectionView吧,蠻好用的
级别: 新手上路
可可豆: 57 CB
威望: 57 点
在线时间: 10(时)
发自: Web Page
基本的概念差不多是这样  
    // self.contentView is the subview for self.scrollView
   // constraints for self.contentView is make.edges.equalTo(self.scrollView)
    UIView *lastV
    for (NSDictionary *slide in self.slides) {
        TFCarouselViewCell *slideCell = [[TFCarouselViewCell alloc] init];
        // Configure your cell
        [self.contentView addSubview:slideCell];
        [slideCell mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(self.contentView);
            if (lastView) {
                make.left.equalTo(lastView.mas_right);
            } else {
                make.left.equalTo(self.contentView);
            }
            make.width.equalTo(self.contentView); //use .multipliedBy()/.dividedBy() if you want to display multiple slides in one row
        }];
        
        lastView = slideC
    }
    
    [self.contentView mas_updateConstraints:^(MASConstraintMaker *make) {
        if (lastView) {
            make.right.equalTo(lastView.mas_right);
        } else {
            make.right.equalTo(self.scrollView);
        }
        make.bottom.greaterThanOrEqualTo(self.contentView.subviews);
    }];
大概的意思就是这样.关键点是不对height做限制, 而是让self.contentView对subviews的高度自适应.这样当屏幕比较窄的时候, 比如4/5 s, 每个subview就会自动拉长.另外, 我是比较习惯用autolayout的时候不调用initWithFrame...或者frame传一个CGRectZero.个人习惯问题吧...
级别: 新手上路
可可豆: 44 CB
威望: 46 点
在线时间: 33(时)
发自: Web Page
回 5楼(cinderllaff) 的帖子
感谢~你的思路让我豁然开朗。 我都没想过在循环外面设置一个空的UIView来&&做动布局的参照
级别: 新手上路
可可豆: 44 CB
威望: 46 点
在线时间: 33(时)
发自: Web Page
回 3楼(wz1383691) 的帖子
看不到图 可以看这个地址 。 因为我图片是引用知乎的图片链接
级别: 新手上路
可可豆: 44 CB
威望: 46 点
在线时间: 33(时)
发自: Web Page
回 4楼(bearnewboy) 的帖子
我之前也是使用这个来实现,但是分页的时候滑动的效果。不一样。或许是我还不会用吧。觉得挺难的。所以为了不浪费时间就使用scrollView 添加UIView来实现
级别: 新手上路
UID: 514009
可可豆: 141 CB
威望: 100 点
在线时间: 104(时)
发自: Web Page
虽然楼主已经解决了问题,但是还是回复下吧。没图,不过猜一下你的问题吧。cell的宽度会随着手机的不同而改变,造成需要显示的内容横向排布数量变化,继而造成cell的高度变化。讲下新手思路。数组存储表示数量不可预知。那么,先确定一个产品信息显示所需要的view 的size,知道了view宽度,由屏幕宽决定横向排布有几个view,用变量纪录,再由数组count和此变量决定纵向排布数量以此确定cell高度。至于每一个view的布局,由纪录的横向数量来判定。其实和文字流相似嘛
发呆的水瓶座♒,没心没肺流泪。
关注本帖(如果有新回复会站内信通知您)
4*5+2 正确答案:22
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版IOS 纯代码 怎么在循环中创建的控件 是它自动布局适应屏幕大小_百度知道
IOS 纯代码 怎么在循环中创建的控件 是它自动布局适应屏幕大小
存放在数组
|:所有数值的字典 views:
[NSLayoutConstrain constrainsWithVisualFormat:&quot:添加的顺序从左到右(默认的就可以) metrics:火星语 options:是父视图的边界
[视图的对象名==(另一个视图)]:|-space-[view1(==space)]-|&H##代码添加自动布局
NSLayoutConstrain
使用vfl可以生成多个NSLayoutConstrain对象
知道智能回答机器人
我是知道站内的人工智能,可高效智能地为您解答问题。很高兴为您服务。
其他类似问题
为您推荐:
ios的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁IOS 纯代码 怎么在循环中创建的控件 是它自动布局适应屏幕大小?
这个Cell中的每一个产品信息是一个UIView。它是根据数组大小来决定的。所以需要代码设定。问题就是我如何设定UIView创建的时候与下一个UIView的间距呢。如何自适应屏幕?这个布局是我通过计算屏幕的宽度除以3得来的。但是在5s中布局展示出来的画面就不理想了。看下图!&br&&img src=&/bc5f22ecb93bb02cf5ec71ec_b.png& data-rawwidth=&872& data-rawheight=&698& class=&origin_image zh-lightbox-thumb& width=&872& data-original=&/bc5f22ecb93bb02cf5ec71ec_r.png&&&br&看到5s的结果很拥挤。间距不能像6那么宽。但是纯代码如何布局?查了之后代码布局可以使用开源框架Masonry 但是对这个框架本身不够那么理解。使用只会简单的调调。 所以想问各位大神。我该如何写才能实现屏幕适配宽度。(附上代码)&br&&img src=&/edac4a6603fafc8ab91be6b60aa5df5c_b.png& data-rawwidth=&806& data-rawheight=&586& class=&origin_image zh-lightbox-thumb& width=&806& data-original=&/edac4a6603fafc8ab91be6b60aa5df5c_r.png&&&br&&br&&div class=&highlight&&&pre&&code class=&language-objective-c&&&span class=&p&&-&/span& &span class=&p&&(&/span&&span class=&kt&&instancetype&/span&&span class=&p&&)&/span&&span class=&nf&&initWithStyle:&/span&&span class=&p&&(&/span&&span class=&n&&UITableViewCellStyle&/span&&span class=&p&&)&/span&&span class=&nv&&style&/span& &span class=&nf&&reuseIdentifier:&/span&&span class=&p&&(&/span&&span class=&bp&&NSString&/span& &span class=&o&&*&/span&&span class=&p&&)&/span&&span class=&nv&&reuseIdentifier&/span& &span class=&nf&&Array:&/span&&span class=&p&&(&/span&&span class=&bp&&NSArray&/span& &span class=&o&&*&/span&&span class=&p&&)&/span&&span class=&nv&&array&/span& &span class=&p&&{&/span&
&span class=&nb&&self&/span& &span class=&o&&=&/span& &span class=&p&&[&/span&&span class=&nb&&super&/span& &span class=&nl&&initWithStyle&/span&&span class=&p&&:&/span&&span class=&n&&style&/span& &span class=&nl&&reuseIdentifier&/span&&span class=&p&&:&/span&&span class=&n&&reuseIdentifier&/span&&span class=&p&&];&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&nb&&self&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&bp&&UIScrollView&/span& &span class=&o&&*&/span&&span class=&n&&scrollView&/span& &span class=&o&&=&/span& &span class=&p&&[[&/span&&span class=&bp&&UIScrollView&/span& &span class=&n&&alloc&/span&&span class=&p&&]&/span& &span class=&nl&&initWithFrame&/span&&span class=&p&&:&/span&&span class=&n&&CGRectMake&/span&&span class=&p&&(&/span&&span class=&mi&&0&/span&&span class=&p&&,&/span& &span class=&mi&&0&/span&&span class=&p&&,&/span& &span class=&n&&AppWidth&/span&&span class=&p&&,&/span& &span class=&mi&&220&/span&&span class=&p&&)];&/span&
&span class=&n&&scrollView&/span&&span class=&p&&.&/span&&span class=&n&&delegate&/span& &span class=&o&&=&/span& &span class=&nb&&self&/span&&span class=&p&&;&/span&
&span class=&n&&scrollView&/span&&span class=&p&&.&/span&&span class=&n&&pagingEnabled&/span& &span class=&o&&=&/span& &span class=&nb&&YES&/span&&span class=&p&&;&/span&
&span class=&n&&scrollView&/span&&span class=&p&&.&/span&&span class=&n&&showsHorizontalScrollIndicator&/span& &span class=&o&&=&/span& &span class=&nb&&NO&/span&&span class=&p&&;&/span&
&span class=&n&&NSInteger&/span& &span class=&n&&scrollCount&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&array&/span&&span class=&p&&.&/span&&span class=&n&&count&/span& &span class=&o&&%&/span& &span class=&mi&&3&/span& &span class=&o&&==&/span& &span class=&mi&&0&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&n&&scrollCount&/span& &span class=&o&&=&/span& &span class=&n&&round&/span&&span class=&p&&(&/span&&span class=&n&&array&/span&&span class=&p&&.&/span&&span class=&n&&count&/span& &span class=&o&&/&/span& &span class=&mi&&3&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&&span class=&k&&else&/span& &span class=&p&&{&/span&
&span class=&n&&scrollCount&/span& &span class=&o&&=&/span& &span class=&n&&round&/span&&span class=&p&&(&/span&&span class=&n&&array&/span&&span class=&p&&.&/span&&span class=&n&&count&/span& &span class=&o&&/&/span& &span class=&mi&&3&/span& &span class=&o&&+&/span& &span class=&mf&&0.5&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&span class=&n&&scrollView&/span&&span class=&p&&.&/span&&span class=&n&&contentSize&/span& &span class=&o&&=&/span& &span class=&n&&CGSizeMake&/span&&span class=&p&&(&/span&&span class=&n&&scrollCount&/span& &span class=&o&&*&/span& &span class=&n&&AppWidth&/span&&span class=&p&&,&/span& &span class=&mi&&220&/span&&span class=&p&&);&/span&
&span class=&p&&[&/span&&span class=&nb&&self&/span& &span class=&nl&&addSubview&/span&&span class=&p&&:&/span&&span class=&n&&scrollView&/span&&span class=&p&&];&/span&
&span class=&n&&NSInteger&/span& &span class=&n&&key&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&
&span class=&k&&for&/span& &span class=&p&&(&/span&&span class=&n&&NSInteger&/span& &span class=&n&&i&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span& &span class=&n&&i&/span& &span class=&o&&&&/span& &span class=&n&&scrollCount&/span&&span class=&p&&;&/span& &span class=&n&&i&/span&&span class=&o&&++&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&bp&&UIView&/span& &span class=&o&&*&/span&&span class=&n&&view&/span& &span class=&o&&=&/span& &span class=&p&&[[&/span&&span class=&bp&&UIView&/span& &span class=&n&&alloc&/span&&span class=&p&&]&/span&&span class=&nl&&initWithFrame&/span&&span class=&p&&:&/span&&span class=&n&&CGRectMake&/span&&span class=&p&&(&/span&&span class=&n&&AppWidth&/span& &span class=&o&&*&/span& &span class=&n&&i&/span&&span class=&p&&,&/span& &span class=&mi&&0&/span&&span class=&p&&,&/span& &span class=&n&&AppWidth&/span&&span class=&p&&,&/span& &span class=&mi&&200&/span&&span class=&p&&)];&/span&
&span class=&p&&[&/span&&span class=&n&&scrollView&/span& &span class=&nl&&addSubview&/span&&span class=&p&&:&/span&&span class=&n&&view&/span&&span class=&p&&];&/span&
&span class=&p&&[&/span&&span class=&n&&view&/span& &span class=&nl&&mas_makeConstraints&/span&&span class=&p&&:&/span&&span class=&o&&^&/span&&span class=&p&&(&/span&&span class=&n&&MASConstraintMaker&/span& &span class=&o&&*&/span&&span class=&n&&make&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&c1&&//make.left.equalTo(scrollView.mas_right).with.multipliedBy(5);&/span&
&span class=&c1&&//make.right.equalTo(scrollView.mas_right).offset(20);&/span&
&span class=&p&&}];&/span&
&span class=&k&&for&/span& &span class=&p&&(&/span&&span class=&n&&NSInteger&/span& &span class=&n&&j&/span& &span class=&o&&=&/span& &span class=&n&&key&/span&&span class=&p&&;&/span& &span class=&n&&j&/span& &span class=&o&&&&/span& &span class=&n&&array&/span&&span class=&p&&.&/span&&span class=&n&&count&/span&&span class=&p&&;)&/span& &span class=&p&&{&/span&
&span class=&bp&&CGRect&/span& &span class=&n&&frame&/span& &span class=&o&&=&/span& &span class=&n&&CGRectMake&/span&&span class=&p&&((&/span&&span class=&n&&j&/span& &span class=&o&&-&/span& &span class=&n&&key&/span&&span class=&p&&)&/span&&span class=&o&&*&/span& &span class=&n&&AppWidth&/span& &span class=&o&&/&/span& &span class=&mi&&3&/span& &span class=&o&&-&/span& &span class=&mi&&28&/span&&span class=&p&&,&/span& &span class=&mi&&0&/span&&span class=&p&&,&/span& &span class=&n&&AppWidth&/span& &span class=&o&&/&/span& &span class=&mi&&3&/span&&span class=&p&&,&/span& &span class=&mi&&200&/span&&span class=&p&&);&/span&
&span class=&n&&SsCartLine&/span& &span class=&o&&*&/span&&span class=&n&&model&/span& &span class=&o&&=&/span& &span class=&n&&array&/span&&span class=&p&&[&/span&&span class=&n&&j&/span&&span class=&p&&];&/span&
&span class=&n&&SSRecommentBtnView&/span& &span class=&o&&*&/span&&span class=&n&&btnView&/span& &span class=&o&&=&/span& &span class=&p&&[[&/span&&span class=&n&&SSRecommentBtnView&/span& &span class=&n&&alloc&/span&&span class=&p&&]&/span& &span class=&nl&&initWithFrame&/span&&span class=&p&&:&/span&&span class=&n&&frame&/span& &span class=&nl&&title&/span&&span class=&p&&:&/span&&span class=&n&&model&/span&&span class=&p&&.&/span&&span class=&n&&ssTongchou&/span&&span class=&p&&.&/span&&span class=&n&&projectName&/span& &span class=&nl&&imageStr&/span&&span class=&p&&:&/span&&span class=&n&&model&/span&&span class=&p&&.&/span&&span class=&n&&ssTongchou&/span&&span class=&p&&.&/span&&span class=&n&&orderTitlePic&/span& &span class=&nl&&printStr&/span&&span class=&p&&:[&/span&&span class=&n&&ToolsClass&/span& &span class=&nl&&setupPrice&/span&&span class=&p&&:&/span&&span class=&n&&model&/span&&span class=&p&&.&/span&&span class=&n&&ssTongchou&/span&&span class=&p&&.&/span&&span class=&n&&curPrice&/span&&span class=&p&&]];&/span&
&span class=&n&&btnView&/span&&span class=&p&&.&/span&&span class=&n&&tag&/span& &span class=&o&&=&/span& &span class=&mi&&10&/span& &span class=&o&&+&/span& &span class=&n&&j&/span&&span class=&p&&;&/span&
&span class=&p&&[&/span&&span class=&n&&view&/span& &span class=&nl&&addSubview&/span&&span class=&p&&:&/span&&span class=&n&&btnView&/span&&span class=&p&&];&/span&
&span class=&bp&&UITapGestureRecognizer&/span& &span class=&o&&*&/span&&span class=&n&&tap&/span& &span class=&o&&=&/span& &span class=&p&&[[&/span&&span class=&bp&&UITapGestureRecognizer&/span& &span class=&n&&alloc&/span&&span class=&p&&]&/span& &span class=&nl&&initWithTarget&/span&&span class=&p&&:&/span&&span class=&nb&&self&/span& &span class=&nl&&action&/span&&span class=&p&&:&/span&&span class=&k&&@selector&/span&&span class=&p&&(&/span&&span class=&nl&&OnTapBtnView&/span&&span class=&p&&:)];&/span&
&span class=&p&&[&/span&&span class=&n&&btnView&/span& &span class=&nl&&addGestureRecognizer&/span&&span class=&p&&:&/span&&span class=&n&&tap&/span&&span class=&p&&];&/span&
&span class=&n&&j&/span&&span class=&o&&++&/span&&span class=&p&&;&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&j&/span& &span class=&o&&%&/span& &span class=&mi&&3&/span& &span class=&o&&==&/span& &span class=&mi&&0&/span& &span class=&o&&&&&/span& &span class=&n&&j&/span& &span class=&o&&!=&/span& &span class=&mi&&0&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&k&&break&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&n&&key&/span& &span class=&o&&+=&/span& &span class=&mi&&3&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&n&&_pageControl&/span& &span class=&o&&=&/span& &span class=&p&&[[&/span&&span class=&bp&&UIPageControl&/span& &span class=&n&&alloc&/span&&span class=&p&&]&/span& &span class=&n&&init&/span&&span class=&p&&];&/span&
&span class=&n&&_pageControl&/span&&span class=&p&&.&/span&&span class=&n&&currentPage&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&
&span class=&n&&_pageControl&/span&&span class=&p&&.&/span&&span class=&n&&numberOfPages&/span& &span class=&o&&=&/span& &span class=&n&&scrollCount&/span&&span class=&p&&;&/span&
&span class=&n&&_pageControl&/span&&span class=&p&&.&/span&&span class=&n&&currentPageIndicatorTintColor&/span& &span class=&o&&=&/span& &span class=&n&&navigationBarColor&/span&&span class=&p&&;&/span&
&/code&&/pre&&/div&&img src=&/ee82c0cc785fe391c0d232d8dfbf5112_b.png& data-rawwidth=&558& data-rawheight=&369& class=&origin_image zh-lightbox-thumb& width=&558& data-original=&/ee82c0cc785fe391c0d232d8dfbf5112_r.png&&文字超过3000字了所以后面截图补上
这个Cell中的每一个产品信息是一个UIView。它是根据数组大小来决定的。所以需要代码设定。问题就是我如何设定UIView创建的时候与下一个UIView的间距呢。如何自适应屏幕?这个布局是我通过计算屏幕的宽度除以3得来的。但是在5s中布局展示出来的画面就不理想了。看下图!看到5s的结果很拥挤。间距不能像6那么宽。但是纯代码如何布局?查了之后代码布局可以使用开源框架Masonry 但是对这个框架本身不够那么理解。使用只会简单的调调。 所以想问各位大神。我该如何写才能实现屏幕适配宽度。(附上代码)…
纯代码编写了多年了,写多了,自己加以总结出一些规律和方法来,遇到这样的布局,其实都只是写简单的数学问题。看到楼主发的图,可以知道大概是把商品按频宽隔分成3块然后分页排在Scrollview上试想只有把商品类抽象出来,这个问题其实很简单商品是item看图决定商品的宽高只有一个重要因素,就是item的宽x,因为商品标题和价格页高度是固定的那先假设高为(h1+h2)所以商品item的高度就是x+(h1+h2);而还学要抽象的是价格Label和加入菜单Button的的宽度分布,因为看6的布局可以猜到到5的时候这里可能会需要调整,所以要把这里的宽抽象,或是按比例0.5或者固定button的宽,然后再用x作差求出label的宽,故可以得以下代码- (id)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self) {
CGFloat itemWidth = self.frame.size.
// 主要参数
CGFloat titleHeight = 30.f;
// 标题的高度
CGFloat bottomBarHeight = 20.f;
// 底部价格和加入菜单按钮的高度
CGFloat itemHeight = itemWidth+titleHeight+bottomBarH // item的高度
// 商品图,这里商品图应该是正方形所以才会出现以上的计算,如果商品图的高度是按比例的,也可以按不同比例自己加以乘除就可以了
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, itemWidth, itemWidth)];
[self addSubview:imageView];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, itemWidth, itemWidth, titleHeight)];
[self addSubview:titleLabel];
// 价格和加入菜单按钮
CGFloat biZhi = 0.5;
// 价格和菜单按钮的比值 也可以让button是固定长度,然后计算price label的长度这样可能会好点
UILabel *priceLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, itemWidth+titleHeight, itemWidth*biZhi, bottomBarHeight)];
[self addSubview:priceLabel];
UIButton *addButton = [[UIButton alloc] initWithFrame:CGRectMake(priceLabel.frame.size.width, itemWidth+titleHeight, itemWidth*biZhi, bottomBarHeight)];
[self addSubview:addButton];
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, itemWidth, itemHeight);
// 到这里就可以确定了 item的自身高度了,还保留了一个可以按照不同屏幕尺寸调整的比值
然后就到上一层决定ScrollView 里面Item的位置的方法了- (instancetype)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self) {
CGFloat containorWidth = self.frame.size. // 根据楼主给的设计图,其实这个宽,就是屏幕的宽,因为在cell实例化改对象的时候的宽,应该是取tableView的宽,而tableView得宽就是controller.view的宽
CGFloat padding = 10.f;
// 各个item的间隔,其实还会出现设计有的顶部的padding和item间的padding会不一样,不过这个只要另外加上算就可以了,比较简单
NSInteger numberInRow = 3; // 一列多少个item
CGFloat itemWidth = (containorWidth-(numberInRow+1)*padding)/3.f; // 这里是算出item的宽度
// 注:有些设计的padding并不是在item外平分的,可能是算item里面的一个间隔,这样设计这里的padding就会是0,然后再在item里面加一个间隔值,就同等于item里面加个描边一样的道理了,不过都是共通的
NSArray *dataA
// 假设商品放在dataArray里面
[dataArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSInteger currentRow = (idx/numberInRow);
// 在第几行
按数值可以知道0是第一行,1是第二行...
NSInteger currentColumn = (idx%numberInRow); // 在第几列
// 楼主这个只有一行,但是多页,可以让多行,currentRow这个参数,决定在第几页
// 可以算出item的位置
CGFloat itemTop =
// 因为没有实际的行数,都是一行,就是只有padding的位置了 // 如果是有行,那就是itemTop = padding+(padding+itemHeight)*currentR (注:itemHeight是可以计算的,参照方法1)
// 前面括号计算当前页的item的left的位置,然后后面括号计算第n页后需要加上每页的差
CGFloat itemLeft = (padding+(padding+itemWidth)*currentColumn) + (currentRow*containorWidth);
ItemView *itemView = [[ItemView alloc] initWithFrame:CGRectMake(itemLeft, itemTop, itemWidth, 0)]; // height是内部根据itemWidth计算的
[self addSubview:itemView];
/* ***********
华丽分割线 ************
如果要熟练,楼主需要自己多以纯代码适配屏幕的方式写代码
像我这样,写多了,加上写上这么多得心酸注释,也就是一共花30分钟分钟左右吧,完成
这样的布局页面,用纯代码写,做全部尺寸的适配,熟练了的话,15分钟到20分钟也足够了的,所以还是得多加练习
***********
华丽分割线 ************ */
已有帐号?
无法登录?
社交帐号登录

我要回帖

更多关于 css两列自适应布局 的文章

 

随机推荐