/* 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. Use of this method is not recommended. Constraints should be created using anchor objects on views and layout guides. */ + (instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullableid)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
/** * Sets the constraint relation to NSLayoutRelationEqual * returns a block which accepts one of the following: * MASViewAttribute, UIView, NSValue, NSArray * see readme for more details. */ - (MASConstraint * (^)(id attr))equalTo;
/** * Sets the constraint relation to NSLayoutRelationGreaterThanOrEqual * returns a block which accepts one of the following: * MASViewAttribute, UIView, NSValue, NSArray * see readme for more details. */ - (MASConstraint * (^)(id attr))greaterThanOrEqualTo;
/** * Sets the constraint relation to NSLayoutRelationLessThanOrEqual * returns a block which accepts one of the following: * MASViewAttribute, UIView, NSValue, NSArray * see readme for more details. */ - (MASConstraint * (^)(id attr))lessThanOrEqualTo;
/** * Modifies the NSLayoutConstraint constant based on a value type */ - (MASConstraint * (^)(NSValue *value))valueOffset;
// MASConstraintMaker /** * Whether or not to check for an existing constraint instead of adding constraint */ @property (nonatomic, assign) BOOL updateExisting;
/** * Whether or not to remove existing constraints prior to installing */ @property (nonatomic, assign) BOOL removeExisting;
// MASConstraint /** * Whether or not to check for an existing constraint instead of adding constraint */ @property (nonatomic, assign) BOOL updateExisting;
//////////////////////////////////////////////// MASLayoutConstraint *existingConstraint = nil; if (self.updateExisting) { existingConstraint = [self layoutConstraintSimilarTo:layoutConstraint]; } if (existingConstraint) { // just update the constant existingConstraint.constant = layoutConstraint.constant; self.layoutConstraint = existingConstraint; } else { [self.installedView addConstraint:layoutConstraint]; self.layoutConstraint = layoutConstraint; [firstLayoutItem.mas_installedConstraints addObject:self]; }
- (MASLayoutConstraint *)layoutConstraintSimilarTo:(MASLayoutConstraint *)layoutConstraint { // check if any constraints are the same apart from the only mutable property constant
// go through constraints in reverse as we do not want to match auto-resizing or interface builder constraints // and they are likely to be added first. for (NSLayoutConstraint *existingConstraint inself.installedView.constraints.reverseObjectEnumerator) { if (![existingConstraint isKindOfClass:MASLayoutConstraint.class]) continue; if (existingConstraint.firstItem != layoutConstraint.firstItem) continue; if (existingConstraint.secondItem != layoutConstraint.secondItem) continue; if (existingConstraint.firstAttribute != layoutConstraint.firstAttribute) continue; if (existingConstraint.secondAttribute != layoutConstraint.secondAttribute) continue; if (existingConstraint.relation != layoutConstraint.relation) continue; if (existingConstraint.multiplier != layoutConstraint.multiplier) continue; if (existingConstraint.priority != layoutConstraint.priority) continue;
// MASConstraint /** * Usually MASConstraintMaker but could be a parent MASConstraint */ @property (nonatomic, weak) id<MASConstraintDelegate> delegate;
/** * Notifies the delegate when the constraint needs to be replaced with another constraint. For example * A MASViewConstraint may turn into a MASCompositeConstraint when an array is passed to one of the equality blocks */ - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint;