From 13eb849e4a43139c64e35a5a738396d2c005478f Mon Sep 17 00:00:00 2001 From: Jonas Budelmann Date: Thu, 24 Oct 2013 11:03:09 +1100 Subject: [PATCH] Update existing constraint rather than adding a new one. If one exists that is the same apart from the constant property --- Masonry/MASViewAttribute.m | 13 +++++++------ Masonry/MASViewConstraint.m | 31 ++++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/Masonry/MASViewAttribute.m b/Masonry/MASViewAttribute.m index f15f1bb8..86bdbfd6 100644 --- a/Masonry/MASViewAttribute.m +++ b/Masonry/MASViewAttribute.m @@ -21,15 +21,16 @@ - (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAtt } - (BOOL)isSizeAttribute { - return self.layoutAttribute == NSLayoutAttributeWidth || self.layoutAttribute == NSLayoutAttributeHeight; + return self.layoutAttribute == NSLayoutAttributeWidth + || self.layoutAttribute == NSLayoutAttributeHeight; } -- (BOOL)isEqual:(id)object { - if ([object isKindOfClass:self.class]) { - MASViewAttribute *attr = object; - return ([self.view isEqual:attr.view] && self.layoutAttribute == attr.layoutAttribute); +- (BOOL)isEqual:(MASViewAttribute *)viewAttribute { + if ([viewAttribute isKindOfClass:self.class]) { + return [self.view isEqual:viewAttribute.view] + && self.layoutAttribute == viewAttribute.layoutAttribute; } - return [super isEqual:object]; + return [super isEqual:viewAttribute]; } - (NSUInteger)hash { diff --git a/Masonry/MASViewConstraint.m b/Masonry/MASViewConstraint.m index 4dc12c68..0d77d5af 100644 --- a/Masonry/MASViewConstraint.m +++ b/Masonry/MASViewConstraint.m @@ -291,15 +291,40 @@ - (void)install { @"couldn't find a common superview for %@ and %@", firstLayoutItem, secondLayoutItem); self.installedView = closestCommonSuperview; - [closestCommonSuperview addConstraint:layoutConstraint]; - self.layoutConstraint = layoutConstraint; } else { self.installedView = firstLayoutItem; - [firstLayoutItem addConstraint:layoutConstraint]; + } + + MASLayoutConstraint *existingConstraint = [self layoutConstraintSimiliarTo:layoutConstraint]; + if (existingConstraint) { + // just update the constant + existingConstraint.constant = layoutConstraint.constant; + self.layoutConstraint = existingConstraint; + } else { + [self.installedView addConstraint:layoutConstraint]; self.layoutConstraint = layoutConstraint; } } +- (MASLayoutConstraint *)layoutConstraintSimiliarTo:(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 in self.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.multiplier != layoutConstraint.multiplier) continue; + if (existingConstraint.priority != layoutConstraint.priority) continue; + + return (id)existingConstraint; + } + return nil; +} + - (void)uninstall { [self.installedView removeConstraint:self.layoutConstraint]; self.layoutConstraint = nil;