NSLayoutConstraint

//
//  NSLayoutConstraint.h
//  UIKit
//  
//  Copyright (c) 2009-2015 Apple Inc. All rights reserved.
//

#import <Foundation/NSObject.h>
#import <UIKit/UIGeometry.h>

NS_ASSUME_NONNULL_BEGIN

@class NSArray, NSDictionary;


// 约束关系枚举
typedef NS_ENUM(NSInteger, NSLayoutRelation) {
    NSLayoutRelationLessThanOrEqual = -1,      // 大于等于
    NSLayoutRelationEqual = 0,                 // 等于 
    NSLayoutRelationGreaterThanOrEqual = 1,    // 小于等于
};


// 布局属性
typedef NS_ENUM(NSInteger, NSLayoutAttribute) {
    NSLayoutAttributeLeft = 1,    // 左边
    NSLayoutAttributeRight,       // 右边
    NSLayoutAttributeTop,         // 上边  
    NSLayoutAttributeBottom,      //  下边
    NSLayoutAttributeLeading,     // 前边
    NSLayoutAttributeTrailing,    // 后边
    NSLayoutAttributeWidth,       // 宽度
    NSLayoutAttributeHeight,      // 高度
    NSLayoutAttributeCenterX,     // 中心 x   
    NSLayoutAttributeCenterY,     // 中心 y
    NSLayoutAttributeBaseline,    // 基准线
    NSLayoutAttributeLastBaseline = NSLayoutAttributeBaseline,


    // 下面这些是 iOS 8 才有的
    NSLayoutAttributeFirstBaseline NS_ENUM_AVAILABLE_IOS(8_0),
    
    
    NSLayoutAttributeLeftMargin NS_ENUM_AVAILABLE_IOS(8_0),            //  左边间隙
    NSLayoutAttributeRightMargin NS_ENUM_AVAILABLE_IOS(8_0),           // 右边间隙
    NSLayoutAttributeTopMargin NS_ENUM_AVAILABLE_IOS(8_0),             // 顶部间隙
    NSLayoutAttributeBottomMargin NS_ENUM_AVAILABLE_IOS(8_0),          // 底部间隙
    NSLayoutAttributeLeadingMargin NS_ENUM_AVAILABLE_IOS(8_0),         // 前边间隙
    NSLayoutAttributeTrailingMargin NS_ENUM_AVAILABLE_IOS(8_0),        // 后边间隙
    NSLayoutAttributeCenterXWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),  // 和中心 x 轴的间隙
    NSLayoutAttributeCenterYWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),  // 和中心 y 轴的间隙
    
    NSLayoutAttributeNotAnAttribute = 0                                // 没有设置  
};


// 格式属性枚举
typedef NS_OPTIONS(NSUInteger, NSLayoutFormatOptions) {
    NSLayoutFormatAlignAllLeft = (1 << NSLayoutAttributeLeft),
    NSLayoutFormatAlignAllRight = (1 << NSLayoutAttributeRight),
    NSLayoutFormatAlignAllTop = (1 << NSLayoutAttributeTop),
    NSLayoutFormatAlignAllBottom = (1 << NSLayoutAttributeBottom),
    NSLayoutFormatAlignAllLeading = (1 << NSLayoutAttributeLeading),
    NSLayoutFormatAlignAllTrailing = (1 << NSLayoutAttributeTrailing),
    NSLayoutFormatAlignAllCenterX = (1 << NSLayoutAttributeCenterX),
    NSLayoutFormatAlignAllCenterY = (1 << NSLayoutAttributeCenterY),
    NSLayoutFormatAlignAllBaseline = (1 << NSLayoutAttributeBaseline),
    NSLayoutFormatAlignAllLastBaseline = NSLayoutFormatAlignAllBaseline,
    NSLayoutFormatAlignAllFirstBaseline NS_ENUM_AVAILABLE_IOS(8_0) = (1 << NSLayoutAttributeFirstBaseline),
    
    NSLayoutFormatAlignmentMask = 0xFFFF,
    
    /* choose only one of these three
     */
    NSLayoutFormatDirectionLeadingToTrailing = 0 << 16, // default
    NSLayoutFormatDirectionLeftToRight = 1 << 16,
    NSLayoutFormatDirectionRightToLeft = 2 << 16,  
    
    NSLayoutFormatDirectionMask = 0x3 << 16,  
};


// 约束的优先级
typedef float UILayoutPriority;
static const UILayoutPriority UILayoutPriorityRequired NS_AVAILABLE_IOS(6_0) = 1000; 
// A required constraint.  Do not exceed this.
一个必须的约束,不要超过这个约束优先级。

static const UILayoutPriority UILayoutPriorityDefaultHigh NS_AVAILABLE_IOS(6_0) = 750; 
// This is the priority level with which a button resists compressing its content.
一个按钮内容能抵抗压缩的优先级水平

static const UILayoutPriority UILayoutPriorityDefaultLow NS_AVAILABLE_IOS(6_0) = 250; 
// This is the priority level at which a button hugs its contents horizontally.
一个按钮内容被水平拥抱的优先级水平

static const UILayoutPriority UILayoutPriorityFittingSizeLevel NS_AVAILABLE_IOS(6_0) = 50; 
/* When you send -[UIView systemLayoutSizeFittingSize:], the size fitting most closely to the target size (the argument) is computed. 
UILayoutPriorityFittingSizeLevel is the priority level with which the view wants to conform to the target size in that computation.  
It's quite low.  
It is generally not appropriate to make a constraint at exactly this priority.  
You want to be higher or lower.
*/
大小合适的水平




NS_CLASS_AVAILABLE_IOS(6_0)
// 布局约束的类
@interface NSLayoutConstraint : NSObject

/* Create an array of constraints using an ASCII art-like visual format string.
    使用 VF 格式创建一个约束数组
 */
+ (NSArray<__kindof NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format 
                                                                options:(NSLayoutFormatOptions)opts 
                                                                metrics:(nullable NSDictionary<NSString *,id> *)metrics 
                                                                  views:(NSDictionary<NSString *, id> *)views;

下面这个宏默认就是调用上面的方法
/* This macro is a helper for making view dictionaries for +constraintsWithVisualFormat:options:metrics:views:.  
 NSDictionaryOfVariableBindings(v1, v2, v3) is equivalent to [NSDictionary dictionaryWithObjectsAndKeys:v1, @"v1", v2, @"v2", v3, @"v3", nil];
 */
#define NSDictionaryOfVariableBindings(...) _NSDictionaryOfVariableBindings(@"" # __VA_ARGS__, __VA_ARGS__, nil)
UIKIT_EXTERN  NSDictionary *_NSDictionaryOfVariableBindings(NSString *commaSeparatedKeysString, __nullable id firstValue, ...) NS_AVAILABLE_IOS(6_0); // not for direct use


/* Create constraints explicitly.  
Constraints are of the form "view1.attr1 = view2.attr2 * multiplier + constant" 
 If your equation does not have a second view and attribute, use nil and NSLayoutAttributeNotAnAttribute.

创建一个明确的约束。
约束的形式是这样的: "view1.attr1 = view2.attr2 * multiplier + constant"
如果你的式子中没有第二个视图和属性。 可以使用 nil 和NSLayoutAttributeNotAnAttribute。  
 */
+(instancetype)constraintWithItem:(id)view1 
                        attribute:(NSLayoutAttribute)attr1 
                        relatedBy:(NSLayoutRelation)relation 
                           toItem:(nullable id)view2 
                        attribute:(NSLayoutAttribute)attr2 
                       multiplier:(CGFloat)multiplier 
                         constant:(CGFloat)c;

属性的优先级
/* If a constraint's priority level is less than UILayoutPriorityRequired, then it is optional.  
 如果约束的优先级水平是比 UILayoutPriorityRequired 小。那么 优先级水平就是可选的。
 Higher priority constraints are met before lower priority constraints.
 高优先级的约束遇到低优先级的约束
 Constraint satisfaction is not all or nothing. 
 约束不是全部满足或者全部不满足
 If a constraint 'a == b' is optional, that means we will attempt to minimize 'abs(a-b)'.
 如果一个约束 a == b 是可选的。意味着我们会试着去最小化 abs(a - b)
 This property may only be modified as part of initial set up. 
  约束可能被修改作为约束初始化的一部分
 An exception will be thrown if it is set after a constraint has been added to a view.
如果它被设置在一个约束添加到一个视图。
 */
@property UILayoutPriority priority;

/* When a view is archived, it archives some but not all constraints in its -constraints array.  
The value of shouldBeArchived informs UIView if a particular constraint should be archived by UIView.
If a constraint is created at runtime in response to the state of the object, it isn't appropriate to archive the constraint - rather you archive the state that gives rise to the constraint.  
Since the majority of constraints that should be archived are created in Interface Builder (which is smart enough to set this prop to YES), the default value for this property is NO.
 */
// 将要被归档
@property BOOL shouldBeArchived;



/* accessors 属性访问器
 firstItem.firstAttribute {==,<=,>=} secondItem.secondAttribute * multiplier + constant
 */
@property (readonly, assign) id firstItem;                              // 第一个视图
@property (readonly) NSLayoutAttribute firstAttribute;                  // 第一个视图属性
@property (readonly) NSLayoutRelation relation;                         // 视图关系
@property (nullable, readonly, assign) id secondItem;                   // 第二个视图
@property (readonly) NSLayoutAttribute secondAttribute;                 // 第二个视图属性
@property (readonly) CGFloat multiplier;                                // 倍率

/* Unlike the other properties, the constant may be modified after constraint creation.
  不像另外一些属性一样。这个属性的值在创建后可以进行修改。
  Setting the constant on an existing constraint performs much better than removing the constraint and adding a new one that's just like the old but for having a new constant.
 */
@property CGFloat constant;

/* The receiver may be activated or deactivated by manipulating this property.  Only active constraints affect the calculated layout.  Attempting to activate a constraint whose items have no common ancestor will cause an exception to be thrown.  Defaults to NO for newly created constraints. */
// 约束进行激活
@property (getter=isActive) BOOL active NS_AVAILABLE(10_10, 8_0);

/* Convenience method that activates each constraint in the contained array, in the same manner as setting active=YES. 
 便利方法:激活容器数组中的每一个约束。都是使用 active = yes 的这种方式
This is often more efficient than activating each constraint individually.
这通常是更有效的比单独激活每个约束。
 */
+ (void)activateConstraints:(NSArray<NSLayoutConstraint *> *)constraints NS_AVAILABLE(10_10, 8_0);

/* Convenience method that deactivates each constraint in the contained array, in the same manner as setting active=NO.
  便利方法: 取消激活容器中的每一个约束。都是使用 active = no 的这种方式。
 This is often more efficient than deactivating each constraint individually. 
 这通常是更有效的比单取消独激活每个约束。
*/
+ (void)deactivateConstraints:(NSArray<NSLayoutConstraint *> *)constraints NS_AVAILABLE(10_10, 8_0);
@end




// 约束的表示分类
@interface NSLayoutConstraint (NSIdentifier)
/* For ease in debugging, name a constraint by setting its identifier, which will be printed in the constraint's description.
 Identifiers starting with UI and NS are reserved by the system.
 为了便于调试,通过给约束设置表示来设置名字。通过 print  constraint's description 的时候可以看到。
标识符从UI和NS是系统保留的。
*/
@property (nullable, copy) NSString *identifier NS_AVAILABLE_IOS(7_0);

@end





/*
 UILayoutSupport protocol is implemented by layout guide objects
 returned by UIViewController properties topLayoutGuide and bottomLayoutGuide.
 These guide objects may be used as layout items in the NSLayoutConstraint
 factory methods.
 布局支持协议
 */
@class NSLayoutYAxisAnchor, NSLayoutDimension;
@protocol UILayoutSupport <NSObject>
@property(nonatomic,readonly) CGFloat length;  
// As a courtesy when not using auto layout, this value is safe to refer to in -viewDidLayoutSubviews, or in -layoutSubviews after calling super

/* Constraint creation conveniences. See NSLayoutAnchor.h for details.
 */
@property(readonly, strong) NSLayoutYAxisAnchor *topAnchor NS_AVAILABLE_IOS(9_0);
@property(readonly, strong) NSLayoutYAxisAnchor *bottomAnchor NS_AVAILABLE_IOS(9_0);
@property(readonly, strong) NSLayoutDimension *heightAnchor NS_AVAILABLE_IOS(9_0);
@end

NS_ASSUME_NONNULL_END
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容

  • 去茶水间休息的片刻,和她打了个招呼,她就去忙了。看她娇小的身躯对着电脑,散乱的头发和憔悴的面庞,我真的想让她赶...
    酵母阅读 327评论 1 2
  • 出了酒吧的门,雪儿随即叫了辆出租车。 “师傅,麻烦找家最近的酒店” 很快出租车停在了一家酒店的门口,她搀扶着阿水走...
    我说故事给你听阅读 801评论 0 0
  • 他曾经向她许诺: 若有天能够成熟稳重。定会归来,陪伴她守护她,终结她的破碎流离。 性格、习惯、爱好、背景都不算般配...
    Zerohated阅读 422评论 3 2
  • 慢慢的改变 你所希望的会如期而至 不用慌张 到那一天你一定可以从容应对 我们能做到的只有相信自己
    巧朵甜功阅读 178评论 0 0
  • 夜华拉着浅浅去了一个确实不会迷路的地方,那里就一座小亭,在浅浅看来,和迷谷的那茅草亭没什么两样,她正想责备夜华,就...
    寻找十年的足迹阅读 1,210评论 11 10