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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

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

友情链接更多精彩内容