iOS View requiresConstraintBasedLayout 详解

 
 
  1. @interface UIView (UIConstraintBasedCompatibility)  
  2.  
  3. - (BOOL)translatesAutoresizingMaskIntoConstraints NS_AVAILABLE_IOS(6_0);  
  4. - (void)setTranslatesAutoresizingMaskIntoConstraints:(BOOL)flag NS_AVAILABLE_IOS(6_0);  
  5.  
  6. + (BOOL)requiresConstraintBasedLayout NS_AVAILABLE_IOS(6_0);  
  7.  
  8. @end 

默认情况下,View的autoresizing工作会根据当前位置自动设置约束。我们在使用代码写自己的约束布局代码时,必须设置当前View的translatesAutoresizingMaskIntoConstraints为NO,否则无法正常运作。IB默认是NO。

requiresConstraintBasedLayout :我们应该在自定义View中重写这个方法。如果我们要使用Auto Layout布局当前视图,应该设置为返回YES。

+ (BOOL)requiresConstraintBasedLayout //返回view是否是约束布局模式,ios6,返回值决定了是否是autoLayout布局模式。使用autolayout返回YES

Views

当用 Auto Layout 布局你的 view 的时候,确保在你父类中加入了下面的代码:

+ (BOOL)requiresConstraintBasedLayout
{
    return YES;
}

否则当系统没有调用 -updateConstraints 的时候,你可能会遇到奇怪的 bug。

// 调用在view 内部,而不是viewcontroller
+ (BOOL)requiresConstraintBasedLayout {
    return YES;
}
requiresConstraintBasedLayout :我们应该在自定义View中重写这个方法。如果我们要使用Auto Layout布局当前视图,应该设置为返回YES。

requiresConstraintBasedLayout   自定义view应该重写这个方法返回YES,如果它不能使用autoresing正确布局。

控制布局 http://blog.csdn.net/jeffasd/article/details/50454588

在自定义视图中,你能完全控制它子视图的布局。你可以增加本地约束;根据内容变化需要,你可以改变本地约束;你可以为子视图调整布局操作的结果;或者你可以选择抛弃自动布局。

但确保你明智的使用这个权利。大多数情况下可以简单地通过为你的子视图简单的增加本地约束来处理。

本地约束

如果我们想用几个子视图组成一个自定义视图,我们需要以某种方式布局这些子视图。在自动布局的环境中,自然会想到为这些视图增加本地约束。然而,需要注意的是,这将会使你自定义的视图是基于自动布局的,这个视图不能再被使用于未启用自动布局的 windows 中。最好通过实现 requiresConstraintBasedLayout 返回 YES 明确这个依赖。

添加本地约束的地方是 updateConstraints。确保在你的实现中增加任何你需要布局子视图的约束条件之后,调用一下 [super updateConstraints]。在这个方法中,你不会被允许禁用何约束条件,因为你已经进入上面所描述的布局过程的第一步了(参考 http://blog.csdn.net/jeffasd/article/details/50454588)。如果尝试着这样做,将会产生一个友好的错误信息 “programming error”。

如果稍后一个失效的约束条件发生了改变的话,你需要立刻移除这个约束并调用 setNeedsUpdateConstraints。事实上,仅在这种情况下你需要触发更新约束条件的操作。

控制子视图布局

如果你不能利用布局约束条件达到子视图预期的布局,你可以进一步在 iOS 里重写 layoutSubviews 或者在 OS X 里面重写layout。通过这种方式,当约束条件系统得到解决并且结果将要被应用到视图中时,你便已经进入到布局过程的第二步。

最极端的情况是不调用父类的实现,自己重写全部的 layoutSubviews / layout。这就意味着你在这个视图里的视图树里抛弃了自动布局。从现在起,你可以按喜欢的方式手动放置子视图。

如果你仍然想使用约束条件布局子视图,你需要调用 [super layoutSubviews] / [super layout],然后对布局进行微调。你可以通过这种方式创建那些通过定于约束无法实现的布,比如,由到视图大小之间的关系或是视图之间间距的关系来定义的布局。

这方面另一个有趣的使用案例就是创建一个布局依赖的视图树。当自动布局完成第一次传递并且为自定义视图的子视图设置好 frame 后,你便可以检查子视图的位置和大小,并为视图层级和(或)约束条件做出调整。WWDC session 228 – Best Practices for Mastering Auto Layout 有一个很好的例子。

你也可以在第一次布局操作完成后再决定改变约束条件。比如,如果视图变得太窄的话,将原来排成一行的子视图转变成两行。

- layoutSubviews
{
    [super layoutSubviews];
    if (self.subviews[0].frame.size.width <= MINIMUM_WIDTH)
    {
        [self removeSubviewConstraints];
        self.layoutRows += 1; [super layoutSubviews];
    }
}

- updateConstraints
{
    // 根据 self.layoutRows 添加约束...
    [super updateConstraints];
}

  • 约束
    • requiresConstraintBasedLayout – 如果你的View类需要约束才能正常工作,实现该方法
    • updateConstraints 如果你的view需要在子view间创建约束,需要实现该方法
    • alignmentRectForFrame:frameForAlignmentRect: – 实现这些方法覆盖你的view如何与其他view对齐
  • 布局
    • sizeThatFits: – 当你想在执行resize操作时有一个不同于默认的size,实现该方法。比如,你可以用这个方法阻止view收缩到子view不能正确显示的点
    • layoutSubviews – 如果你需要更精确控制子view,而不是使用限制或autoresizing行为,就需要实现该方法。
    • didAddSubview: , willRemoveSubview: 跟踪子view添加或删除事件
    • willMoveToSuperview:didMoveToSuperview 跟踪当前view在view层次里的运动
    • willMoveToWindow:,didMoveToWindow 跟踪view(即将或已经)移动到另一个Window

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值