Layout--iOS

// 系统的约束代码

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

UIView *superView = self.view;

UIView *viewDemo = [[UIView alloc] init];

viewDemo.translatesAutoresizingMaskIntoConstraints = NO;

viewDemo.backgroundColor = [UIColor orangeColor];

[superView addSubview:viewDemo];

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);

[superView addConstraints:@[

           // viewDemo顶部距离父视图superView顶部距离为padding.top(即为:10),

[NSLayoutConstraint constraintWithItem:viewDemo attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:superView attribute:NSLayoutAttributeTop multiplier:1 constant:padding.top],

[NSLayoutConstraint constraintWithItem:viewDemo attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:superView attribute:NSLayoutAttributeLeft multiplier:1 constant:padding.left],

[NSLayoutConstraint constraintWithItem:viewDemo attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:superView attribute:NSLayoutAttributeRight multiplier:1 constant:-padding.right],

[NSLayoutConstraint constraintWithItem:viewDemo attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:superView attribute:NSLayoutAttributeBottom multiplier:1 constant:-padding.bottom]

]];

}

// 注:若是把右边约束去掉,改为如下语句

// [NSLayoutConstraint constraintWithItem:viewDemo attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:superView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0]

// 则viewDemo的宽度变为superView的0.5倍!!

//***************************************************

// VFL语言

  UIView *viewLeft = [[UIView alloc] init];

viewLeft.translatesAutoresizingMaskIntoConstraints = NO;

viewLeft.backgroundColor = [UIColor orangeColor];

[self.view addSubview:viewLeft];

UIView *viewRight = [[UIView alloc] init];

viewRight.translatesAutoresizingMaskIntoConstraints = NO;

viewRight.backgroundColor = [UIColor redColor];

[self.view addSubview:viewRight];

// horizontal:水平方向距左边10,距右边10

//简单说来,NSDictionaryOfVariableBindings(scrollView)就等于@{@”scrollView”: scrollView}

NSDictionary *constraintDict = NSDictionaryOfVariableBindings(viewLeft,viewRight);

NSArray *hConstraintArrayLeft = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[viewLeft]-(10)-|" options:0 metrics:nil views:constraintDict];

// vertical: 垂直方向距顶部30,控件高度100

NSArray *vConstraintArrayLeft = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(30)-[viewLeft(100)]" options:0 metrics:nil views:constraintDict];

// 添加到父视图上

[self.view addConstraints:hConstraintArrayLeft];

[self.view addConstraints:vConstraintArrayLeft];

NSArray *hConstraintArrayRight = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[viewRight]-(10)-|" options:0 metrics:nil views:constraintDict];

// viewRight距viewLeft的垂直距离为50

NSArray *vConstraintArrayRight = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[viewLeft]-(50)-[viewRight(200)]" options:0 metrics:nil views:constraintDict];

[self.view addConstraints:hConstraintArrayRight];

[self.view addConstraints:vConstraintArrayRight];

//***************************************************

// 三方库:Masonry

// 居中

// 快速定义一个weakSelf,用于block里面,防止循环引用

#define WS(weakSelf)  __weak __typeof(&*self)weakSelf = self

WS(ws);

UIView *sv = [UIView new];

sv.backgroundColor = [UIColor orangeColor];

// 在做autoLayout之前 一定要先将view添加到superView上 否则会报错

[self.view addSubview:sv];

[sv mas_makeConstraints:^(MASConstraintMaker *make) {

// 居中

make.center.equalTo(ws.view);

// 设置size

make.size.mas_equalTo(CGSizeMake(300, 300));

}];

3. [初级] 让两个高度为150的view垂直居中且等宽且等间隔排列 间隔为10(自动计算其宽度)


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

int padding1 = 10;

[sv2 mas_makeConstraints:^(MASConstraintMaker *make) {

    make.centerY.mas_equalTo(sv.mas_centerY);

    make.left.equalTo(sv.mas_left).with.offset(padding1);

    make.right.equalTo(sv3.mas_left).with.offset(-padding1);

    make.height.mas_equalTo(@150);

    make.width.equalTo(sv3);

}];

[sv3 mas_makeConstraints:^(MASConstraintMaker *make) {

    make.centerY.mas_equalTo(sv.mas_centerY);

    make.left.equalTo(sv2.mas_right).with.offset(padding1);

    make.right.equalTo(sv.mas_right).with.offset(-padding1);

    make.height.mas_equalTo(@150);

    make.width.equalTo(sv2);

}];

代码效果

这里我们在两个子view之间互相设置的约束 可以看到他们的宽度在约束下自动的被计算出来了

4. [中级] 在UIScrollView顺序排列一些view并自动计算contentSize


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

UIScrollView *scrollView = [UIScrollView new];

scrollView.backgroundColor = [UIColor whiteColor];

[sv addSubview:scrollView];

[scrollView mas_makeConstraints:^(MASConstraintMaker *make) {

    make.edges.equalTo(sv).with.insets(UIEdgeInsetsMake(5,5,5,5));

}];

UIView *container = [UIView new];

[scrollView addSubview:container];

[container mas_makeConstraints:^(MASConstraintMaker *make) {

    make.edges.equalTo(scrollView);

    make.width.equalTo(scrollView);

}];

int count = 10;

UIView *lastView = nil;

for ( int i = 1 ; i <= count ; ++i )

{

    UIView *subv = [UIView new];

    [container addSubview:subv];

    subv.backgroundColor = [UIColor colorWithHue:( arc4random() % 256 / 256.0 )

                                      saturation:( arc4random() % 128 / 256.0 ) + 0.5

                                      brightness:( arc4random() % 128 / 256.0 ) + 0.5

                                           alpha:1];

    

    [subv mas_makeConstraints:^(MASConstraintMaker *make) {

        make.left.and.right.equalTo(container);

        make.height.mas_equalTo(@(20*i));

        

        if ( lastView )

        {

            make.top.mas_equalTo(lastView.mas_bottom);

        }

        else

        {

            make.top.mas_equalTo(container.mas_top);

        }

    }];

    

    lastView = subv;

}

[container mas_makeConstraints:^(MASConstraintMaker *make) {

    make.bottom.equalTo(lastView.mas_bottom);

}];

头部效果

尾部效果

从scrollView的scrollIndicator可以看出 scrollView的内部已如我们所想排列好了

这里的关键就在于container这个view起到了一个中间层的作用 能够自动的计算uiscrollView的contentSize

5. [高级] 横向或者纵向等间隙的排列一组view

很遗憾 autoLayout并没有直接提供等间隙排列的方法(Masonry的官方demo中也没有对应的案例) 但是参考案例3 我们可以通过一个小技巧来实现这个目的 为此我写了一个Category


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

@implementation UIView(Masonry_LJC)

- (void) distributeSpacingHorizontallyWith:(NSArray*)views

{

    NSMutableArray *spaces = [NSMutableArray arrayWithCapacity:views.count+1];

    

    for ( int i = 0 ; i < views.count+1 ; ++i )

    {

        UIView *v = [UIView new];

        [spaces addObject:v];

        [self addSubview:v];

        

        [v mas_makeConstraints:^(MASConstraintMaker *make) {

            make.width.equalTo(v.mas_height);

        }];

    }    

    

    UIView *v0 = spaces[0];

    

    __weak __typeof(&*self)ws = self;

    

    [v0 mas_makeConstraints:^(MASConstraintMaker *make) {

        make.left.equalTo(ws.mas_left);

        make.centerY.equalTo(((UIView*)views[0]).mas_centerY);

    }];

    

    UIView *lastSpace = v0;

    for ( int i = 0 ; i < views.count; ++i )

    {

        UIView *obj = views[i];

        UIView *space = spaces[i+1];

        

        [obj mas_makeConstraints:^(MASConstraintMaker *make) {

            make.left.equalTo(lastSpace.mas_right);

        }];

        

        [space mas_makeConstraints:^(MASConstraintMaker *make) {

            make.left.equalTo(obj.mas_right);

            make.centerY.equalTo(obj.mas_centerY);

            make.width.equalTo(v0);

        }];

        

        lastSpace = space;

    }

    

    [lastSpace mas_makeConstraints:^(MASConstraintMaker *make) {

        make.right.equalTo(ws.mas_right);

    }];

    

}

- (void) distributeSpacingVerticallyWith:(NSArray*)views

{

    NSMutableArray *spaces = [NSMutableArray arrayWithCapacity:views.count+1];

    

    for ( int i = 0 ; i < views.count+1 ; ++i )

    {

        UIView *v = [UIView new];

        [spaces addObject:v];

        [self addSubview:v];

        

        [v mas_makeConstraints:^(MASConstraintMaker *make) {

            make.width.equalTo(v.mas_height);

        }];

    }

    

    

    UIView *v0 = spaces[0];

    

    __weak __typeof(&*self)ws = self;

    

    [v0 mas_makeConstraints:^(MASConstraintMaker *make) {

        make.top.equalTo(ws.mas_top);

        make.centerX.equalTo(((UIView*)views[0]).mas_centerX);

    }];

    

    UIView *lastSpace = v0;

    for ( int i = 0 ; i < views.count; ++i )

    {

        UIView *obj = views[i];

        UIView *space = spaces[i+1];

        

        [obj mas_makeConstraints:^(MASConstraintMaker *make) {

            make.top.equalTo(lastSpace.mas_bottom);

        }];

        

        [space mas_makeConstraints:^(MASConstraintMaker *make) {

            make.top.equalTo(obj.mas_bottom);

            make.centerX.equalTo(obj.mas_centerX);

            make.height.equalTo(v0);

        }];

        

        lastSpace = space;

    }

    

    [lastSpace mas_makeConstraints:^(MASConstraintMaker *make) {

        make.bottom.equalTo(ws.mas_bottom);

    }];

}

@end

简单的来测试一下


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

UIView *sv11 = [UIView new];

UIView *sv12 = [UIView new];

UIView *sv13 = [UIView new];

UIView *sv21 = [UIView new];

UIView *sv31 = [UIView new];

sv11.backgroundColor = [UIColor redColor];

sv12.backgroundColor = [UIColor redColor];

sv13.backgroundColor = [UIColor redColor];

sv21.backgroundColor = [UIColor redColor];

sv31.backgroundColor = [UIColor redColor];

[sv addSubview:sv11];

[sv addSubview:sv12];

[sv addSubview:sv13];

[sv addSubview:sv21];

[sv addSubview:sv31];

//给予不同的大小 测试效果

[sv11 mas_makeConstraints:^(MASConstraintMaker *make) {

    make.centerY.equalTo(@[sv12,sv13]);

    make.centerX.equalTo(@[sv21,sv31]);

    make.size.mas_equalTo(CGSizeMake(40, 40));

}];

[sv12 mas_makeConstraints:^(MASConstraintMaker *make) {

    make.size.mas_equalTo(CGSizeMake(70, 20));

}];

[sv13 mas_makeConstraints:^(MASConstraintMaker *make) {

    make.size.mas_equalTo(CGSizeMake(50, 50));

}];

[sv21 mas_makeConstraints:^(MASConstraintMaker *make) {

    make.size.mas_equalTo(CGSizeMake(50, 20));

}];

[sv31 mas_makeConstraints:^(MASConstraintMaker *make) {

    make.size.mas_equalTo(CGSizeMake(40, 60));

}];

[sv distributeSpacingHorizontallyWith:@[sv11,sv12,sv13]];

[sv distributeSpacingVerticallyWith:@[sv11,sv21,sv31]];

[sv showPlaceHolderWithAllSubviews];

[sv hidePlaceHolder];

代码效果

perfect! 简洁明了的达到了我们所要的效果

这里所用的技巧就是 使用空白的占位view来填充我们目标view的旁边 这点通过图上的空白标注可以看出来

引自:http://www.cocoachina.com/ios/20141219/10702.html

若有侵权,请告知

时间: 2024-10-21 14:59:39

Layout--iOS的相关文章

iOS Programming Auto Layout: Programmatic Constraints 自动布局:通过编程限制

iOS Programming? Auto Layout: Programmatic Constraints? 1.? However, if your views are created in code, then you will need to constrain them programmatically. 如果你的view是由代码创建的,那么你需要用编程限制它了. To have a view to work with, you are going to recreate the im

ios UIView setFrame not working

ios UIView setFrame not working: 很奇怪吧,又不报错,打印frame正常,可就是frame set无效. 最简单的方法取interface builder 对该xib取消选择auto layout; ios UIView setFrame not working,布布扣,bubuko.com

iOS开发常用三方库、插件、知名博客等等

TimLiu-iOS   Swift版本点击这里 欢迎加入QQ交流群: 594119878 介绍 这是一个用于iOS开发的各种开源库.开源资料.开源技术等等的索引库. github排名 https://github.com/trending,github搜索:https://github.com/search 使用方法 根据目录关键字搜索,记得包含@,以保证搜索目录关键字的唯一性. 问题反馈 期待大家和我们一起共同维护,同时也期望大家随时能提出宝贵的意见(直接提交issues即可).请广大网友只

iOS 强大第三方资源库

Github用法 git-recipesGit recipes in Chinese. 高质量的Git中文教程. lark怎样在Github上面贡献代码 my-git有关 git 的学习资料 gitignore非常赞 有用的.gitignore模板集合(忽略上传的文件集合),包含了各种语言. 完整[email protected] open-source-ios-apps- iOS开源App集合,分:swift与Objective-C--国外人整理. NewsBlur作者独自一个人 Samuel

iOS 第三方库、插件、知名博客总结

用到的组件1.通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SDWebImage多个缩略图缓存组件 UICKeyChainStore存放用户账号密码组件 Reachability监测网络状态 DateTools友好化时间 MBProgressHUD一款提示框第三方库 MWPhotoBrowser一款简单的 iOS 照片浏览控件 CTAssetsPickerController一个选择器组件, 支持从用户的相片库选择多张照片和视频. QB

Topics

Topics Introduction (starting with old devices) How to handle a new Firmware How to set up your Mac and Device for Vuln Research/Exploit Development How to boot own Kernels How to patch own Code into the Kernel How to write Code for your iDevice Low

Automatic Preferred Max Layout Width is not available on iOS versions prior to 8.0

今天在真机调试低版本系统的时候出现如题类似Layout Max Width在ios 8 之前不适用的问题, 初步估计是autolayout 所导致的 查找资料解决方法如下: 将label下Preffered Width 设置成大于0.

iOS开发之Auto Layout入门

随着iPhone6与iOS8的临近,适配的问题讲更加复杂,最近学习了一下Auto Layout的使用,与大家分享.  什么是Auto Layout? Auto Layout是iOS6发布后引入的一个全新的布局特性,其目的是弥补以往Autoresizing在布局方面的不足之处,以及未来面对更多尺寸适配时界面布局可以更好的适应. 为什么要用Auto Layout? Autolayout能解决不同屏幕(iPhone4,iPhone5,iPad...)之间的适配问题. 在iPhone4时代开发者只需要适

iOS之layout方法-layoutSubviews、layoutIfNeeded、setNeedsLayout

下面列举下iOS layout的相关方法: layoutSubviews layoutIfNeeded setNeedsLayout setNeedsDisplay drawRect sizeThatFits sizeToFit 大概常用的上面几个 , 具体的应该还有别的. layoutSubviews 这个方法,默认没有做任何事情,需要子类进行重写 . 系统在很多时候会去调用这个方法: 1.初始化不会触发layoutSubviews,但是如果设置了不为CGRectZero的frame的时候就会

iOS屏幕适配方案-Auto Layout

市场上的android手机五花八门.各种尺寸的屏幕让android程序员们比較头疼. 也有一些大神写了一些博客提出了自己的观点.iOS貌似也迎来了大屏6+,因此屏幕适配的问题也是有滴,因此苹果也有自己的方法-auto Layout . 本人初学iOS.今天学了自己主动布局.在学习的过程中,毕竟还是有些知识点没有接触到的,因此写这篇博客来深入的了解一下Auto Layout. 官方解释: Auto Layout 是一个系统,能够让你通过创建元素之间关系的数学描写叙述来布局应用程序的用户界面.--<