使用auto layout自定义flipBar

原创 2016年05月30日 10:46:17

最近有在看一本关于auto layout的书,受益匪浅,然后突然想到我要解决的一个问题其实正好可以用到这个auto layout的技巧,现在进行一个讲解


我们之前看新闻、视频等的软件,常看到过这样的功能(如图蓝椭圆内)

      

      


我最早做这个功能的时候,是通过计算frame相应的值进行布局。其实这样很low,尤其如果button所对应的内容不一定时,计算就简直了,后来看了auto layout,觉得可以试一试使用它。

在这里主要涉及到俩个知识点,1.几何约束。2.内容约束


先晒代码,在做解释


#define buttonTag 1000


@interface ViewController ()

@property(nonatomic,strong)UIScrollView *scrollView;

@property(nonatomic,strong)NSArray *buttonContents;


@end


@implementation ViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    

    self.buttonContents = @[@"button1",@"longButton2",@"longlongButton3",@"btn",@"b",@"这是一个超长button",@"这个button更长更长更更长"];

    self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];

    self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;

    [self.view addSubview:self.scrollView];



    UIButton *btn;

    for (int i = 0; i < self.buttonContents.count; i++) {

        btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];

        btn.translatesAutoresizingMaskIntoConstraints = NO;

        [btn setTitle:self.buttonContents[i] forState:UIControlStateNormal];

        btn.tag = buttonTag+i;

        [btn addTarget:self action:@selector(clickBtn:) forControlEvents:UIControlEventTouchUpInside];

        [self.scrollView addSubview:btn];


        [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:btn attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:btn.intrinsicContentSize.width+10.0]];

        if (i == 0) {

            [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:btn attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.scrollView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]];

            [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:btn attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.scrollView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:10]];

            

        }else{

            UIButton *preBtn = [self.scrollView viewWithTag:999+i];

            [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:btn attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:preBtn attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]];

            [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:btn attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:preBtn attribute:NSLayoutAttributeRight multiplier:1.0 constant:0]];

        }

        [btn layoutIfNeeded];

    }

    

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:100]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:btn attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0]];

    self.scrollView.contentSize = CGSizeMake(btn.frame.origin.x+btn.frame.size.width, btn.frame.size.height);

    

    

}



- (void)clickBtn:(id)sender{

    UIButton *btn = (UIButton *)sender;

    

    NSString *buttonContent = self.buttonContents[btn.tag - buttonTag];

    NSLog(@"button title is %@",buttonContent);

}




最终结果如上图,图中区域可以左右滑动显示更多内容


flipBar只需要俩个控件,1.UIScrollView. 2.UIButton

如果有需要,你完全可以自定义一个UIButton


1.首先需要初始化scrollView,注意不需要指定frame的具体值


2.其次涉及到translatesAutoresizingMaskIntoConstraints属性,它的默认值是YES.其中开发文档中是这样描述它

If this property’s value is YES, the system creates a set of constraints that duplicate the behavior specified by the view’s autoresizing mask. This also lets you modify the view’s size and location using the view’s framebounds, or center properties, allowing you to create a static, frame-based layout within Auto Layout.

Note that the autoresizing mask constraints fully specify the view’s size and position; therefore, you cannot add additional constraints to modify this size or position without introducing conflicts. If you want to use Auto Layout to dynamically calculate the size and position of your view, you must set this property to NO, and then provide a non ambiguous, nonconflicting set of constraints for the view.

By default, the property is set to YES for any view you programmatically create. If you add views in Interface Builder, the system automatically sets this property to NO.


如果属性值是YES,重复被viewautoresizing mask指定的行为。也就是让你通过frameboundcenter等属性来修改视图的sizelocation,允许您用auto layout创建静态,框架布局。

注意autoresizing mask约束完全指定视图的sizeposition;因此,你在不引入冲突的情况下不能添加额外约束来修改size或者position(言外之意,属性设置YES,只要修改size或者position就会带来冲突)。如果你想要使用Auto Layout来动态的计算你视图的sizeposition,你必须设置此属性为NO,并且提供一系列不模棱两可的,无冲突的的视图约束。

编程方式创建视图,属性默认值是YES。如果在IB中添加views,系统自动设置属性为NO.


所以如果是动态计算sizeposition,就需要设置属性值是NO,之后的button也会将此属性设置为NO


3.一定要先addSubView:,才能设置一系列的约束,否则一定会报错


4.通过for的方式添加button,添加的button也不需要设置frame,因为在设置translatesAutoresizingMaskIntoConstraintsNO时,button会自动根据内容设置其它的大小

但在内容约束的基础上,我们往往希望内别逗挤在一起,所以在此处设置了内容约束基础上扩宽10PX,你可以按照自己喜好设置


5.然后,其实第一个button是有点不太一样的,它的几何约束是以scrollView为基础的,而剩下的button都是以前面的button为基础,具体你可以参照代码


6.layoutIfNeeded的应用,其中,使用这个属性的话,就自动布局,最明显的反应就是frame值不是0了,在下面也有很好的使用


7.接下来auto layout 约束scrollview,然后设置它的contentSize,其中主要利用了最后一个button的frame值


flipBar大概就是这样


对代码做了一些改进后的demo地址:https://github.com/xiujiePei/PXJSlidButtonBar


Auto Layout 使用心得(三)—— 自定义 cell 并使用 Auto Layout

转自:https://lvwenhan.com/ Auto Layout 使用心得(三)—— 自定义 cell 并使用 Auto Layout 此系列文章代码仓库在 https://g...
  • zhh152
  • zhh152
  • 2016年08月29日 16:14
  • 79

Auto Layout 使用心得(三)—— 自定义 cell 并使用 Auto Layout

此系列文章代码仓库在 https://github.com/johnlui/AutoLayout ,有不明白的地方可以参考我的 Auto Layout 设置哦,下载到本地打开就可以了。 简介...
  • bluewindaa
  • bluewindaa
  • 2015年06月11日 17:31
  • 357

Auto Layout入门详解

原文:Beginning Auto Layout Tutorial in iOS 7: Part 1 感谢翻译小组成员@answer-huang(博客)热心翻译。如果您有不错的原创或译文,欢迎提交...
  • u012894479
  • u012894479
  • 2015年05月29日 11:29
  • 461

ExtJS中layout的12种布局风格

·  absolute 顾名思义,在容器内部,根据指定的坐标定位显示  layout: 'absolute', items:[{ title: 'Panel 1', x: 50,...
  • xys_00
  • xys_00
  • 2016年03月13日 21:43
  • 665

Auto Layout 使用心得

本文转载自:http://www.cocoachina.com/ios/20150422/11632.html Auto Layout 使用心得(一)--初体验 本系列文章将从...
  • a19860903
  • a19860903
  • 2015年06月03日 17:24
  • 759

Auto Layout 使用心得

Auto Layout 使用心得(一)--初体验 本系列文章将从一个慢慢摸索中的新手的角度介绍 Auto Layout,讲述我在这两个月的学习中对它一点一滴的感受,最终目的是让大家在阅读完之后能够自...
  • Liangyc0129
  • Liangyc0129
  • 2016年03月26日 16:48
  • 728

自定义View之Layout方法详解

自定义View之onLayout、Layout分析
  • qq_29951983
  • qq_29951983
  • 2017年04月01日 12:02
  • 752

iOS 8 Auto Layout界面自动布局系列1-自动布局的基本原理

http://blog.csdn.net/pucker/article/details/41832939 苹果今年如约放出了新的iPhone 6与iOS 8系统,SDK针对新的设备和系统...
  • jeffasd
  • jeffasd
  • 2015年10月28日 10:17
  • 210

Unity新UI系统概述——Auto Layout

Rect Transform拥有的布局系统对于各种类型的布局是足够灵活的,并且它也可以让你自由放置元素。但是,有时候更多结构化的东西是需要的。 自动布局系统提供了在嵌套布局组(如水平组、竖直组或者格子...
  • u014630768
  • u014630768
  • 2014年11月29日 19:29
  • 4752

Unity UGUI 原理篇(五):Auto Layout 自動佈局

Auto Layout System Auto Layout System 是基於 Rect Transform Layout System 之上的系統,自動調整一個或多個的元素大小、位置、間格,又...
  • gz_huangzl
  • gz_huangzl
  • 2016年09月09日 10:17
  • 2901
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用auto layout自定义flipBar
举报原因:
原因补充:

(最多只允许输入30个字)