IOS 自动布局-UIStackPanel和UIGridPanel(五)

试想这样的一个需求场合,一个button靠右显示,并且距离superView的顶部和右边间距分别为10和5。如下图所示:

要实现这样的需求,如果不用自动布局技术,那么我们能想到的就是老老实实的使用绝对布局的坐标计算来实现了,假如这个button宽高都是100,父视图的宽是300,那么这个button的坐标就是:(300-100-5,10)。但要是父视图的宽度变了,我们还得重新计算一遍。颇为麻烦。

幸好我们有自动布局技术。要实现这样的需求还是相对比较简单的。

既然我们要实现这样的需求,而且这个需求其实也是具有普遍性的,那么我们直接封装下好了。我们给UIView添加两个扩展属性:horizontalAlignment和verticalAlignment。两个属性都是枚举。

typedef NS_ENUM(NSInteger, UIViewVerticalAlignment) {
    UIViewVerticalAlignmentFill    = 0,
    UIViewVerticalAlignmentCenter  = 1,
    UIViewVerticalAlignmentTop     = 2,
    UIViewVerticalAlignmentBottom  = 3

};

typedef NS_ENUM(NSInteger, UIViewHorizontalAlignment) {
    UIViewHorizontalAlignmentFill    = 0,
    UIViewHorizontalAlignmentCenter  = 1,
    UIViewHorizontalAlignmentLeft    = 2,
    UIViewHorizontalAlignmentRight   = 3
};

@property (nonatomic,assign)UIViewHorizontalAlignment horizontalAlignment;

@property (nonatomic,assign)UIViewVerticalAlignment verticalAlignment;

实现的思路如下:

我下面以水平停靠举例,对于水平停靠有四种情况,首先就是不停靠完全的填充,也就是我们把该subview的宽度跟superview的宽度绑定到一起。第二种情况是左边停靠,依次还有居中停靠和右边停靠。

对于非填充停靠,在宽度方面肯定不能直接绑定到superview的宽度了,只能使用UIView的扩展属性size的宽度了。

现在以上述场景的实现为例,就是水平方向右边停靠。那么我们只要把subview的NSLayoutAttributeRight跟superview的NSLayoutAttributeRight对齐就好了。代码如下:

[self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self
                                                             attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeRight multiplier:1.0f constant:-margin.right]];

对于左边停靠和居中停靠无非就是对齐的属性不一样。对于垂直停靠来说也是这样。

完整的停靠代码如下:

UIEdgeInsets margin=self.margin;
    switch (self.verticalAlignment) {
        case UIViewVerticalAlignmentFill:
        {
            NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-top-[view]-bottom-|" options:0 metrics:@{ @"top" : @(margin.top),@"bottom":@(margin.bottom)} views:@{ @"view" : self}];
            [self.superview addConstraints:constraints];
        }
            break;
        case UIViewVerticalAlignmentBottom:
        {
            [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self
                                                             attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeBottom multiplier:1.0f constant:-margin.bottom]];
        }
            break;
        case UIViewVerticalAlignmentCenter:
        {
            [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self
                                                             attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0]];
        }
            break;
        case UIViewVerticalAlignmentTop:
        {
            [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self
                                                             attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeTop multiplier:1.0f constant:margin.top]];
        }
            break;
        default:
            break;
    }

    switch (self.horizontalAlignment) {
        case UIViewHorizontalAlignmentFill:{
            NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-left-[view]-right-|" options:0 metrics:@{ @"left" : @(margin.left),@"right":@(margin.right)} views:@{ @"view" : self}];//添加宽度的约束
            [self.superview addConstraints:constraints];
        }
            break;
        case UIViewHorizontalAlignmentCenter:{
            [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self
                                                             attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0]];
        }
            break;
        case UIViewHorizontalAlignmentLeft:{
            [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self
                                                             attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeLeft multiplier:1.0f constant:margin.left]];
        }
            break;
        case UIViewHorizontalAlignmentRight:{
            [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self
                                                             attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeRight multiplier:1.0f constant:-margin.right]];
        }
            break;
        default:
            break;
    }

对于停靠,我们前面写的UIStackPanel和UIGridView势必也要支持的。因此我也修改了下原来的代码。

然后对于图中 的那个button的代码就是如下:

   UIButton *btn=[[UIButton alloc] initWithSize:CGSizeMake(100, 100)];
    [btn setBackgroundColor:[UIColor blueColor]];
    btn.isBindSizeToSuperView=YES;
    [btn setTitle:@"button1" forState:UIControlStateNormal];
    btn.horizontalAlignment=UIViewHorizontalAlignmentRight;
    btn.verticalAlignment=UIViewVerticalAlignmentTop;
    btn.margin=UIEdgeInsetsMake(10, 0, 0, 5);
    [self.view addSubview:btn];

完整的源码请点击下载。

时间: 2024-11-05 20:40:40

IOS 自动布局-UIStackPanel和UIGridPanel(五)的相关文章

IOS 自动布局-UIStackPanel和UIGridPanel(三)

在这一篇了我将继续讲解UIGridPanel. 在iphone的app里面可以经常看到一些九宫格布局的应用,做过html开发的对这类布局应该是很熟悉的.在IOS中要实现这样的布局方法还是蛮多的,但是我这次主要是讲解直接通过控件来实现,我直接指定某个subview处于gridpanel的某行某列.甚至我要求该subview跨多行多列来显示. 要实现以上的需求,那么首先就得要求该panel具有行和列的属性,也就是该panel可以被拆分成多少行多少列.用代码表示如下: @interface UIGri

IOS 自动布局-UIStackPanel和UIGridPanel

我以前是做windows phone开发的,后来转做IOS的开发,因此很多windows phone上面的开发经验也被我带到了IOS中.其实有些经验本身跟平台无关,跟平台有关的无非就是实现方法而已.好了,废话不多说. 我今天给大家介绍一个IOS自动华布局的辅助类(UIPanel   UIStackPanel  UIGridPanel),做过windows phone开发的同学看到这三个类肯定很眼熟,没错,这三个类正是windows phone布局的核心,只是名称稍微有点不一样而已. 我先介绍下我

IOS 自动布局-UIStackPanel和UIGridPanel(四)

为什么说scrollview的自动化布局是难点? 对scrollview做自动化布局,无非就是想对scrollview里面的subviews来做自动化布局.但是scrollview里面的subviews的自动化布局不是由scrollview的高宽来决定的,而是由scrollview的contentSize共同决定的,这样就出现一个问题了,就算scrollview的高宽是改变了,但是只要contentSize不变,那么对于scrollview里面的subviews的高宽其实是没有影响的.而实现自动

cocos2d-x ios游戏开发初认识(五) CCsprite精灵类

这次写一下精灵创建的几种类型: 一.通过文件创建: 在原有的基础上添加如下代码: //一.通过文件创建精灵 CCSprite *bg =CCSprite::create("map.png"); CCSize winSize  =CCDirector::sharedDirector()->getWinSize(); //得到屏幕的尺寸 bg->setPosition(ccp(winSize.width/2, winSize.height/2)); this->addCh

iOS 自动布局

自动布局框架 Masonry PureLayout FLKAutoLayout KeepLayout UIView+Autolayout 相关教程: iOS 开发实践之 Auto Layout Masonry介绍与使用实践(快速上手Autolayout) IOS自动布局之Autoresizing iOS中的相对布局:AutoLayout

iOS 自动布局详细介绍

1. 自动布局的理解 iOS自动布局很有用,可以在不同size的屏幕上运行,原先看的头痛,还是习惯用最蠢的[UIScreen mainScreen].bounds.size.width等来布局,后来实在不行了,开始好好地看自动布局,发现理解后真的很好用,现在就来分享分享我的心得吧. 首先要明白一个控件在屏幕上的位置怎么样才能真正地确定.最简单的情况是: 1. 例如一个矩形,只要知道它左上角点的坐标,宽,高,那么位置就固定了. 2. 例如一个圆,只要知道它的圆心坐标,半径,那么位置就固定了. 自动

iOS自动布局——Masonry详解

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由鹅厂新鲜事儿发表于云+社区专栏 作者:oceanlong | 腾讯 移动客户端开发工程师 前言 UI布局是整个前端体系里不可或缺的一环.代码的布局是设计语言与用户视觉感受沟通的桥梁,不论它看起来多么简单或是琐碎,但不得不承认,绝大部分软件开发的问题,都是界面问题.那么,如何高效的完成UI开发,也是软件行业一直在克服的问题. 所以,软件界面开发的核心点即是:如何减少UI设计稿的建模难度和减少建模转化到代码的实现难度 最初iOS提供了

iOS 自动布局扩展应用:代码中动态调整布局常量

一.设计需求 iOS Storyboard 自动布局技术,是iOS 6才出来的新技术,相当于多屏幕分辩率下自适应的技术. 但是一些复杂情况还是难处理. 比如有一个界面需求,进度条上显示标签,这个需求不难,难的是显要在显示表格框内,在各种机型显示正常. 最初设定是垂直居中向上偏15个像素 这是iPhone 4S 显示效果,下面与滑块还有错位 但是在iPhone 6下显示,下面有错位,但是上面留空太多 但如果把偏移量设为21.则出现另一种情况. 大屏幕的手机显示完美. 但是iPhone 4S下就错位

iOS自动布局学习(UIView+AutoLayout)

自动布局虽然在iOS6的时候已经推出,不过由于各个原因并没有被开发组广泛使用.一方面是大家的app支持版本都是低于iOS6的,另一方面来说是Xcode支持木有现在这么好.以前由于iPhone设备相对固定,所以在纯代码,纯坐标的布局下很流行,不过现在随着iPhone6发布,如果还要写一大堆乱七八糟的绝对坐标去适配,那工作量和维护成本是很大的. 下面的一些基础直接拿小伙伴分享整理的吧,之后向大家推荐一个开源的库,对AutoLayout进行了封装,用起来很简单也高效. 1.AutoLayout是什么?