//
// NSLayoutConstraint.h
// UIKit
//
// Copyright (c) 2009-2015 Apple Inc. All rights reserved.
//
#import
#import
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 *)metrics
views:(NSDictionary *)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 *)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 *)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
@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