From 427dc0300f9d2ba094a2b1bb3e360eee9b8a4904 Mon Sep 17 00:00:00 2001 From: bibibi <418452686@qq.com> Date: Thu, 30 Jul 2015 01:44:22 +0800 Subject: [PATCH 1/5] add distribute function --- Masonry/NSArray+MASAdditions.h | 31 +++++++-- Masonry/NSArray+MASAdditions.m | 115 +++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 4 deletions(-) diff --git a/Masonry/NSArray+MASAdditions.h b/Masonry/NSArray+MASAdditions.h index 189d51f1..57ff601a 100644 --- a/Masonry/NSArray+MASAdditions.h +++ b/Masonry/NSArray+MASAdditions.h @@ -1,6 +1,6 @@ // // NSArray+MASAdditions.h -// +// // // Created by Daniel Hammond on 11/26/13. // @@ -10,6 +10,11 @@ #import "MASConstraintMaker.h" #import "MASViewAttribute.h" +typedef NS_ENUM(NSUInteger, AxisType) { + AxisTypeHorizon, + AxisTypeVertical +}; + @interface NSArray (MASAdditions) /** @@ -20,7 +25,7 @@ * * @return Array of created MASConstraints */ -- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block; +- (NSArray *)mas_makeConstraints:(void (^)(MASConstraintMaker *make))block; /** * Creates a MASConstraintMaker with each view in the callee. @@ -31,7 +36,7 @@ * * @return Array of created/updated MASConstraints */ -- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block; +- (NSArray *)mas_updateConstraints:(void (^)(MASConstraintMaker *make))block; /** * Creates a MASConstraintMaker with each view in the callee. @@ -42,6 +47,24 @@ * * @return Array of created/updated MASConstraints */ -- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block; +- (NSArray *)mas_remakeConstraints:(void (^)(MASConstraintMaker *make))block; + +/** + * distribute with fixed spaceing + * + * @param axisType horizon/vertical + * @param paddingSpace space + * @param leadSpacing head/tail + */ +- (void)mas_distributeViewsAlongAxis:(AxisType)axisType withFixedSpacing:(CGFloat)paddingSpace withLeadSpacing:(CGFloat)leadSpacing; + +/** + * distribute with fixed item size + * + * @param axisType horizon/vertical + * @param itemLength item size + * @param leadSpacing head/tail + */ +- (void)mas_distributeViewsAlongAxis:(AxisType)axisType withFixedItemLength:(CGFloat)itemLength withLeadSpacing:(CGFloat)leadSpacing; @end diff --git a/Masonry/NSArray+MASAdditions.m b/Masonry/NSArray+MASAdditions.m index dbbe6713..a1e13b61 100644 --- a/Masonry/NSArray+MASAdditions.m +++ b/Masonry/NSArray+MASAdditions.m @@ -38,4 +38,119 @@ - (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block { return constraints; } +- (void)mas_distributeViewsAlongAxis:(AxisType)axisType withFixedSpacing:(CGFloat)paddingSpace withLeadSpacing:(CGFloat)leadSpacing { + if (self.count < 2) { + return; + } + + UIView *tempSuperView = [self mas_commonSuperviewOfViews]; + if (axisType == AxisTypeHorizon) { + UIView *prev; + for (int i = 0; i < self.count; i++) { + UIView *v = [self objectAtIndex:i]; + [v mas_makeConstraints:^(MASConstraintMaker *make) { + if (prev) { + make.left.equalTo(prev.mas_right).offset(paddingSpace); + make.width.equalTo(prev); + } + else { + make.left.equalTo(tempSuperView).offset(leadSpacing); + } + if (i == (CGFloat)self.count - 1) { + make.right.equalTo(tempSuperView).offset(-leadSpacing); + } + }]; + prev = v; + } + } + else { + UIView *prev; + for (int i = 0; i < self.count; i++) { + UIView *v = [self objectAtIndex:i]; + [v mas_makeConstraints:^(MASConstraintMaker *make) { + if (prev) { + make.top.equalTo(prev.mas_bottom).offset(paddingSpace); + make.height.equalTo(prev); + } + else { + make.top.equalTo(tempSuperView).offset(leadSpacing); + } + if (i == (CGFloat)self.count - 1) { + make.bottom.equalTo(tempSuperView).offset(-leadSpacing); + } + }]; + prev = v; + } + } +} + +- (void)mas_distributeViewsAlongAxis:(AxisType)axisType withFixedItemLength:(CGFloat)itemLength withLeadSpacing:(CGFloat)leadSpacing { + if (self.count < 2) {//一个不需要均匀分布 + return; + } + + UIView *tempSuperView = [self mas_commonSuperviewOfViews]; + if (axisType == AxisTypeHorizon) { + UIView *prev; + for (int i = 0; i < self.count; i++) { + UIView *v = [self objectAtIndex:i]; + [v mas_makeConstraints:^(MASConstraintMaker *make) { + if (prev) { + CGFloat offset = (1-(i/((CGFloat)self.count-1)))*itemLength; + make.width.equalTo(@(itemLength)); + make.right.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset); + } + else { + make.left.equalTo(tempSuperView).offset(leadSpacing); + make.width.equalTo(@(itemLength)); + } + if (i == (CGFloat)self.count - 1) { + make.right.equalTo(tempSuperView).offset(-leadSpacing); + } + }]; + prev = v; + } + } + else { + UIView *prev; + for (int i = 0; i < self.count; i++) { + UIView *v = [self objectAtIndex:i]; + [v mas_makeConstraints:^(MASConstraintMaker *make) { + if (prev) { + CGFloat offset = (1-(i/((CGFloat)self.count-1)))*itemLength; + make.height.equalTo(@(itemLength)); + make.bottom.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset); + } + else { + make.top.equalTo(tempSuperView).offset(leadSpacing); + make.height.equalTo(@(itemLength)); + } + if (i == (CGFloat)self.count - 1) { + make.bottom.equalTo(tempSuperView).offset(-leadSpacing); + } + }]; + prev = v; + } + } +} + +- (UIView *)mas_commonSuperviewOfViews +{ + UIView *commonSuperview = nil; + UIView *previousView = nil; + for (id object in self) { + if ([object isKindOfClass:[UIView class]]) { + UIView *view = (UIView *)object; + if (previousView) { + commonSuperview = [view mas_closestCommonSuperview:commonSuperview]; + } else { + commonSuperview = view; + } + previousView = view; + } + } + NSAssert(commonSuperview, @"Can't constrain views that do not share a common superview. Make sure that all the views in this array have been added into the same view hierarchy."); + return commonSuperview; +} + @end From a7a78fa9849ece2d03977c41da355e008be7efe8 Mon Sep 17 00:00:00 2001 From: bibibi <418452686@qq.com> Date: Thu, 30 Jul 2015 08:30:52 +0800 Subject: [PATCH 2/5] replace uiview with mas_view --- Masonry/NSArray+MASAdditions.m | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Masonry/NSArray+MASAdditions.m b/Masonry/NSArray+MASAdditions.m index a1e13b61..7b1393da 100644 --- a/Masonry/NSArray+MASAdditions.m +++ b/Masonry/NSArray+MASAdditions.m @@ -43,11 +43,11 @@ - (void)mas_distributeViewsAlongAxis:(AxisType)axisType withFixedSpacing:(CGFloa return; } - UIView *tempSuperView = [self mas_commonSuperviewOfViews]; + MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews]; if (axisType == AxisTypeHorizon) { - UIView *prev; + MAS_VIEW *prev; for (int i = 0; i < self.count; i++) { - UIView *v = [self objectAtIndex:i]; + MAS_VIEW *v = [self objectAtIndex:i]; [v mas_makeConstraints:^(MASConstraintMaker *make) { if (prev) { make.left.equalTo(prev.mas_right).offset(paddingSpace); @@ -64,9 +64,9 @@ - (void)mas_distributeViewsAlongAxis:(AxisType)axisType withFixedSpacing:(CGFloa } } else { - UIView *prev; + MAS_VIEW *prev; for (int i = 0; i < self.count; i++) { - UIView *v = [self objectAtIndex:i]; + MAS_VIEW *v = [self objectAtIndex:i]; [v mas_makeConstraints:^(MASConstraintMaker *make) { if (prev) { make.top.equalTo(prev.mas_bottom).offset(paddingSpace); @@ -89,11 +89,11 @@ - (void)mas_distributeViewsAlongAxis:(AxisType)axisType withFixedItemLength:(CGF return; } - UIView *tempSuperView = [self mas_commonSuperviewOfViews]; + MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews]; if (axisType == AxisTypeHorizon) { - UIView *prev; + MAS_VIEW *prev; for (int i = 0; i < self.count; i++) { - UIView *v = [self objectAtIndex:i]; + MAS_VIEW *v = [self objectAtIndex:i]; [v mas_makeConstraints:^(MASConstraintMaker *make) { if (prev) { CGFloat offset = (1-(i/((CGFloat)self.count-1)))*itemLength; @@ -112,9 +112,9 @@ - (void)mas_distributeViewsAlongAxis:(AxisType)axisType withFixedItemLength:(CGF } } else { - UIView *prev; + MAS_VIEW *prev; for (int i = 0; i < self.count; i++) { - UIView *v = [self objectAtIndex:i]; + MAS_VIEW *v = [self objectAtIndex:i]; [v mas_makeConstraints:^(MASConstraintMaker *make) { if (prev) { CGFloat offset = (1-(i/((CGFloat)self.count-1)))*itemLength; @@ -134,13 +134,13 @@ - (void)mas_distributeViewsAlongAxis:(AxisType)axisType withFixedItemLength:(CGF } } -- (UIView *)mas_commonSuperviewOfViews +- (MAS_VIEW *)mas_commonSuperviewOfViews { - UIView *commonSuperview = nil; - UIView *previousView = nil; + MAS_VIEW *commonSuperview = nil; + MAS_VIEW *previousView = nil; for (id object in self) { - if ([object isKindOfClass:[UIView class]]) { - UIView *view = (UIView *)object; + if ([object isKindOfClass:[MAS_VIEW class]]) { + MAS_VIEW *view = (MAS_VIEW *)object; if (previousView) { commonSuperview = [view mas_closestCommonSuperview:commonSuperview]; } else { From 3571d1daaaca46caed515e258f8ffa7772f6b95b Mon Sep 17 00:00:00 2001 From: bibibi <418452686@qq.com> Date: Thu, 6 Aug 2015 17:49:53 +0800 Subject: [PATCH 3/5] mas prefix,test cover,examples --- .../project.pbxproj | 6 ++ .../MASExampleDistributeView.h | 13 +++ .../MASExampleDistributeView.m | 72 +++++++++++++++ .../MASExampleListViewController.m | 3 + Masonry/NSArray+MASAdditions.h | 16 ++-- Masonry/NSArray+MASAdditions.m | 58 ++++++------ Tests/Specs/NSArray+MASAdditionsSpec.m | 89 +++++++++++++++++++ 7 files changed, 225 insertions(+), 32 deletions(-) create mode 100644 Examples/Masonry iOS Examples/MASExampleDistributeView.h create mode 100644 Examples/Masonry iOS Examples/MASExampleDistributeView.m diff --git a/Examples/Masonry iOS Examples.xcodeproj/project.pbxproj b/Examples/Masonry iOS Examples.xcodeproj/project.pbxproj index 2280605b..2cdbdc99 100644 --- a/Examples/Masonry iOS Examples.xcodeproj/project.pbxproj +++ b/Examples/Masonry iOS Examples.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 00FC4A321B7359D700DCA999 /* MASExampleDistributeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 00FC4A311B7359D700DCA999 /* MASExampleDistributeView.m */; }; 114413091924B6EE008E702E /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 114413081924B6EE008E702E /* Default-568h@2x.png */; }; 27A27D461A6CF0C400D34F52 /* MASExampleAspectFitView.m in Sources */ = {isa = PBXBuildFile; fileRef = 27A27D451A6CF0C400D34F52 /* MASExampleAspectFitView.m */; }; 3C02224919D0C4EC00507321 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3C02224819D0C4EC00507321 /* Images.xcassets */; }; @@ -35,6 +36,8 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 00FC4A301B7359D700DCA999 /* MASExampleDistributeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASExampleDistributeView.h; sourceTree = ""; }; + 00FC4A311B7359D700DCA999 /* MASExampleDistributeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASExampleDistributeView.m; sourceTree = ""; }; 114413081924B6EE008E702E /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 27A27D441A6CF0C400D34F52 /* MASExampleAspectFitView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASExampleAspectFitView.h; sourceTree = ""; }; 27A27D451A6CF0C400D34F52 /* MASExampleAspectFitView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASExampleAspectFitView.m; sourceTree = ""; }; @@ -182,6 +185,8 @@ DD32C3FC18E8BFF6001F6AD2 /* MASExampleAttributeChainingView.m */, 44C0E6AD1A9B9C55003C70CF /* MASExampleMarginView.h */, 44C0E6AE1A9B9C55003C70CF /* MASExampleMarginView.m */, + 00FC4A301B7359D700DCA999 /* MASExampleDistributeView.h */, + 00FC4A311B7359D700DCA999 /* MASExampleDistributeView.m */, ); name = Views; sourceTree = ""; @@ -308,6 +313,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 00FC4A321B7359D700DCA999 /* MASExampleDistributeView.m in Sources */, DD175E6A182639FB0099129A /* MASExampleUpdateView.m in Sources */, DD52F237179CAD57005CD195 /* main.m in Sources */, 3DB1CAD5184538E200E91FC5 /* MASExampleArrayView.m in Sources */, diff --git a/Examples/Masonry iOS Examples/MASExampleDistributeView.h b/Examples/Masonry iOS Examples/MASExampleDistributeView.h new file mode 100644 index 00000000..18a5499e --- /dev/null +++ b/Examples/Masonry iOS Examples/MASExampleDistributeView.h @@ -0,0 +1,13 @@ +// +// MASExampleDistributeView.h +// Masonry iOS Examples +// +// Created by bibibi on 15/8/6. +// Copyright (c) 2015年 Jonas Budelmann. All rights reserved. +// + +#import + +@interface MASExampleDistributeView : UIView + +@end diff --git a/Examples/Masonry iOS Examples/MASExampleDistributeView.m b/Examples/Masonry iOS Examples/MASExampleDistributeView.m new file mode 100644 index 00000000..e2396e7f --- /dev/null +++ b/Examples/Masonry iOS Examples/MASExampleDistributeView.m @@ -0,0 +1,72 @@ +// +// MASExampleDistributeView.m +// Masonry iOS Examples +// +// Created by bibibi on 15/8/6. +// Copyright (c) 2015年 Jonas Budelmann. All rights reserved. +// + +#import "MASExampleDistributeView.h" + +@implementation MASExampleDistributeView + +- (id)init { + self = [super init]; + if (!self) return nil; + + NSMutableArray *arr = @[].mutableCopy; + for (int i = 0; i < 4; i++) { + UIView *view = UIView.new; + view.backgroundColor = [self randomColor]; + view.layer.borderColor = UIColor.blackColor.CGColor; + view.layer.borderWidth = 2; + [self addSubview:view]; + [arr addObject:view]; + } + + unsigned int type = arc4random()%4; + switch (type) { + case 0: + [arr mas_distributeViewsAlongAxis:MASAxisTypeHorizon withFixedSpacing:20 leadSpacing:5 tailSpacing:5]; + [arr makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(@60); + make.height.equalTo(@60); + }]; + break; + case 1: + [arr mas_distributeViewsAlongAxis:MASAxisTypeVertical withFixedSpacing:20 leadSpacing:5 tailSpacing:5]; + [arr makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(@0); + make.width.equalTo(@60); + }]; + break; + case 2: + [arr mas_distributeViewsAlongAxis:MASAxisTypeHorizon withFixedItemLength:30 leadSpacing:5 tailSpacing:5]; + [arr makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(@60); + make.height.equalTo(@60); + }]; + break; + case 3: + [arr mas_distributeViewsAlongAxis:MASAxisTypeVertical withFixedItemLength:30 leadSpacing:5 tailSpacing:5]; + [arr makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(@0); + make.width.equalTo(@60); + }]; + break; + + default: + break; + } + + return self; +} + +- (UIColor *)randomColor { + CGFloat hue = ( arc4random() % 256 / 256.0 ); // 0.0 to 1.0 + CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from white + CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from black + return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1]; +} + +@end diff --git a/Examples/Masonry iOS Examples/MASExampleListViewController.m b/Examples/Masonry iOS Examples/MASExampleListViewController.m index bd1239c0..c2e4b632 100644 --- a/Examples/Masonry iOS Examples/MASExampleListViewController.m +++ b/Examples/Masonry iOS Examples/MASExampleListViewController.m @@ -22,6 +22,7 @@ #import "MASExampleAttributeChainingView.h" #import "MASExampleAspectFitView.h" #import "MASExampleMarginView.h" +#import "MASExampleDistributeView.h" static NSString * const kMASCellReuseIdentifier = @"kMASCellReuseIdentifier"; @@ -66,6 +67,8 @@ - (id)init { viewClass:MASExampleAttributeChainingView.class], [[MASExampleViewController alloc] initWithTitle:@"Margins" viewClass:MASExampleMarginView.class], + [[MASExampleViewController alloc] initWithTitle:@"Views Distribute" + viewClass:MASExampleDistributeView.class], ]; diff --git a/Masonry/NSArray+MASAdditions.h b/Masonry/NSArray+MASAdditions.h index 57ff601a..9ed324ab 100644 --- a/Masonry/NSArray+MASAdditions.h +++ b/Masonry/NSArray+MASAdditions.h @@ -10,9 +10,9 @@ #import "MASConstraintMaker.h" #import "MASViewAttribute.h" -typedef NS_ENUM(NSUInteger, AxisType) { - AxisTypeHorizon, - AxisTypeVertical +typedef NS_ENUM(NSUInteger, MASAxisType) { + MASAxisTypeHorizon, + MASAxisTypeVertical }; @interface NSArray (MASAdditions) @@ -54,17 +54,19 @@ typedef NS_ENUM(NSUInteger, AxisType) { * * @param axisType horizon/vertical * @param paddingSpace space - * @param leadSpacing head/tail + * @param leadSpacing head + * @param tailSpacing tail */ -- (void)mas_distributeViewsAlongAxis:(AxisType)axisType withFixedSpacing:(CGFloat)paddingSpace withLeadSpacing:(CGFloat)leadSpacing; +- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)paddingSpace leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; /** * distribute with fixed item size * * @param axisType horizon/vertical * @param itemLength item size - * @param leadSpacing head/tail + * @param leadSpacing head + * @param tailSpacing tail */ -- (void)mas_distributeViewsAlongAxis:(AxisType)axisType withFixedItemLength:(CGFloat)itemLength withLeadSpacing:(CGFloat)leadSpacing; +- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)itemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; @end diff --git a/Masonry/NSArray+MASAdditions.m b/Masonry/NSArray+MASAdditions.m index 7b1393da..866d5654 100644 --- a/Masonry/NSArray+MASAdditions.m +++ b/Masonry/NSArray+MASAdditions.m @@ -38,27 +38,29 @@ - (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block { return constraints; } -- (void)mas_distributeViewsAlongAxis:(AxisType)axisType withFixedSpacing:(CGFloat)paddingSpace withLeadSpacing:(CGFloat)leadSpacing { +- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)paddingSpace leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing { if (self.count < 2) { + NSAssert(self.count>1,@"views to distribute need to bigger than one"); return; } MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews]; - if (axisType == AxisTypeHorizon) { + if (axisType == MASAxisTypeHorizon) { MAS_VIEW *prev; for (int i = 0; i < self.count; i++) { MAS_VIEW *v = [self objectAtIndex:i]; [v mas_makeConstraints:^(MASConstraintMaker *make) { if (prev) { - make.left.equalTo(prev.mas_right).offset(paddingSpace); make.width.equalTo(prev); + make.left.equalTo(prev.mas_right).offset(paddingSpace); + if (i == (CGFloat)self.count - 1) {//last one + make.right.equalTo(tempSuperView).offset(-tailSpacing); + } } - else { + else {//first one make.left.equalTo(tempSuperView).offset(leadSpacing); } - if (i == (CGFloat)self.count - 1) { - make.right.equalTo(tempSuperView).offset(-leadSpacing); - } + }]; prev = v; } @@ -69,28 +71,30 @@ - (void)mas_distributeViewsAlongAxis:(AxisType)axisType withFixedSpacing:(CGFloa MAS_VIEW *v = [self objectAtIndex:i]; [v mas_makeConstraints:^(MASConstraintMaker *make) { if (prev) { - make.top.equalTo(prev.mas_bottom).offset(paddingSpace); make.height.equalTo(prev); + make.top.equalTo(prev.mas_bottom).offset(paddingSpace); + if (i == (CGFloat)self.count - 1) {//last one + make.bottom.equalTo(tempSuperView).offset(-tailSpacing); + } } - else { + else {//first one make.top.equalTo(tempSuperView).offset(leadSpacing); } - if (i == (CGFloat)self.count - 1) { - make.bottom.equalTo(tempSuperView).offset(-leadSpacing); - } + }]; prev = v; } } } -- (void)mas_distributeViewsAlongAxis:(AxisType)axisType withFixedItemLength:(CGFloat)itemLength withLeadSpacing:(CGFloat)leadSpacing { - if (self.count < 2) {//一个不需要均匀分布 +- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)itemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing { + if (self.count < 2) { + NSAssert(self.count>1,@"views to distribute need to bigger than one"); return; } MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews]; - if (axisType == AxisTypeHorizon) { + if (axisType == MASAxisTypeHorizon) { MAS_VIEW *prev; for (int i = 0; i < self.count; i++) { MAS_VIEW *v = [self objectAtIndex:i]; @@ -98,15 +102,17 @@ - (void)mas_distributeViewsAlongAxis:(AxisType)axisType withFixedItemLength:(CGF if (prev) { CGFloat offset = (1-(i/((CGFloat)self.count-1)))*itemLength; make.width.equalTo(@(itemLength)); - make.right.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset); + if (i == (CGFloat)self.count - 1) {//last one + make.right.equalTo(tempSuperView).offset(-tailSpacing); + } + else { + make.right.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset); + } } - else { + else {//first one make.left.equalTo(tempSuperView).offset(leadSpacing); make.width.equalTo(@(itemLength)); } - if (i == (CGFloat)self.count - 1) { - make.right.equalTo(tempSuperView).offset(-leadSpacing); - } }]; prev = v; } @@ -119,15 +125,17 @@ - (void)mas_distributeViewsAlongAxis:(AxisType)axisType withFixedItemLength:(CGF if (prev) { CGFloat offset = (1-(i/((CGFloat)self.count-1)))*itemLength; make.height.equalTo(@(itemLength)); - make.bottom.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset); + if (i == (CGFloat)self.count - 1) {//last one + make.bottom.equalTo(tempSuperView).offset(-tailSpacing); + } + else { + make.bottom.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset); + } } - else { + else {//first one make.top.equalTo(tempSuperView).offset(leadSpacing); make.height.equalTo(@(itemLength)); } - if (i == (CGFloat)self.count - 1) { - make.bottom.equalTo(tempSuperView).offset(-leadSpacing); - } }]; prev = v; } diff --git a/Tests/Specs/NSArray+MASAdditionsSpec.m b/Tests/Specs/NSArray+MASAdditionsSpec.m index efec2f2d..280f94fe 100644 --- a/Tests/Specs/NSArray+MASAdditionsSpec.m +++ b/Tests/Specs/NSArray+MASAdditionsSpec.m @@ -59,4 +59,93 @@ - (void)testShouldSetRemoveExistingForArray { }]; } +- (void)testDistributeViewsWithFixedSpacingShouldFailWhenArrayContainsLessTwoViews { + MAS_VIEW *superView = MAS_VIEW.new; + + MAS_VIEW *subject1 = MAS_VIEW.new; + [superView addSubview:subject1]; + + MAS_VIEW *subject2 = MAS_VIEW.new; + [superView addSubview:subject2]; + NSArray *views = @[ subject1]; + expect(^{ + [views mas_distributeViewsAlongAxis:MASAxisTypeHorizon withFixedSpacing:10.0 leadSpacing:5.0 tailSpacing:5.0]; + }).to.raiseAny(); + +} + +- (void)testDistributeViewsWithFixedItemLengthShouldFailWhenArrayContainsLessTwoViews { + MAS_VIEW *superView = MAS_VIEW.new; + + MAS_VIEW *subject1 = MAS_VIEW.new; + [superView addSubview:subject1]; + + MAS_VIEW *subject2 = MAS_VIEW.new; + [superView addSubview:subject2]; + NSArray *views = @[ subject1]; + expect(^{ + [views mas_distributeViewsAlongAxis:MASAxisTypeHorizon withFixedSpacing:10.0 leadSpacing:5.0 tailSpacing:5.0]; + }).to.raiseAny(); + +} + +- (void)testDistributeViewsWithFixedSpacingShouldHaveCorrectNumberOfConstraints { + MAS_VIEW *superView = MAS_VIEW.new; + + MAS_VIEW *subject1 = MAS_VIEW.new; + [superView addSubview:subject1]; + + MAS_VIEW *subject2 = MAS_VIEW.new; + [superView addSubview:subject2]; + + MAS_VIEW *subject3 = MAS_VIEW.new; + [superView addSubview:subject3]; + + NSArray *views = @[ subject1,subject2,subject3 ]; + + [views mas_distributeViewsAlongAxis:MASAxisTypeHorizon withFixedSpacing:10.0 leadSpacing:5.0 tailSpacing:5.0]; + + //left view + NSArray *arr1 = [MASViewConstraint installedConstraintsForView:subject1]; + expect(arr1).to.haveCountOf(1); + + //middle view + NSArray *arr2 = [MASViewConstraint installedConstraintsForView:subject2]; + expect(arr2).to.haveCountOf(2); + + //right view + NSArray *arr3 = [MASViewConstraint installedConstraintsForView:subject3]; + expect(arr3).to.haveCountOf(3); +} + +- (void)testDistributeViewsWithFixedItemLengthShouldHaveCorrectNumberOfConstraints { + MAS_VIEW *superView = MAS_VIEW.new; + + MAS_VIEW *subject1 = MAS_VIEW.new; + [superView addSubview:subject1]; + + MAS_VIEW *subject2 = MAS_VIEW.new; + [superView addSubview:subject2]; + + MAS_VIEW *subject3 = MAS_VIEW.new; + [superView addSubview:subject3]; + + NSArray *views = @[ subject1,subject2,subject3 ]; + + [views mas_distributeViewsAlongAxis:MASAxisTypeHorizon withFixedItemLength:30.0 leadSpacing:5.0 tailSpacing:5.0]; + + //left view + NSArray *arr1 = [MASViewConstraint installedConstraintsForView:subject1]; + expect(arr1).to.haveCountOf(2); + + //middle view + NSArray *arr2 = [MASViewConstraint installedConstraintsForView:subject2]; + expect(arr2).to.haveCountOf(2); + + //right view + NSArray *arr3 = [MASViewConstraint installedConstraintsForView:subject3]; + expect(arr3).to.haveCountOf(2); +} + + SpecEnd From 15293124f8abb239f051bc98ad4546109a32c966 Mon Sep 17 00:00:00 2001 From: bibibi <418452686@qq.com> Date: Tue, 1 Sep 2015 20:33:33 +0800 Subject: [PATCH 4/5] fix a bug cause by set leading or tail space --- Examples/Masonry iOS Examples/MASExampleDistributeView.m | 4 ++-- Masonry/NSArray+MASAdditions.m | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Examples/Masonry iOS Examples/MASExampleDistributeView.m b/Examples/Masonry iOS Examples/MASExampleDistributeView.m index e2396e7f..904ca203 100644 --- a/Examples/Masonry iOS Examples/MASExampleDistributeView.m +++ b/Examples/Masonry iOS Examples/MASExampleDistributeView.m @@ -41,14 +41,14 @@ - (id)init { }]; break; case 2: - [arr mas_distributeViewsAlongAxis:MASAxisTypeHorizon withFixedItemLength:30 leadSpacing:5 tailSpacing:5]; + [arr mas_distributeViewsAlongAxis:MASAxisTypeHorizon withFixedItemLength:30 leadSpacing:200 tailSpacing:30]; [arr makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(@60); make.height.equalTo(@60); }]; break; case 3: - [arr mas_distributeViewsAlongAxis:MASAxisTypeVertical withFixedItemLength:30 leadSpacing:5 tailSpacing:5]; + [arr mas_distributeViewsAlongAxis:MASAxisTypeVertical withFixedItemLength:30 leadSpacing:30 tailSpacing:200]; [arr makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(@0); make.width.equalTo(@60); diff --git a/Masonry/NSArray+MASAdditions.m b/Masonry/NSArray+MASAdditions.m index 866d5654..36e2b6de 100644 --- a/Masonry/NSArray+MASAdditions.m +++ b/Masonry/NSArray+MASAdditions.m @@ -100,7 +100,7 @@ - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:( MAS_VIEW *v = [self objectAtIndex:i]; [v mas_makeConstraints:^(MASConstraintMaker *make) { if (prev) { - CGFloat offset = (1-(i/((CGFloat)self.count-1)))*itemLength; + CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(itemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1)); make.width.equalTo(@(itemLength)); if (i == (CGFloat)self.count - 1) {//last one make.right.equalTo(tempSuperView).offset(-tailSpacing); @@ -123,7 +123,7 @@ - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:( MAS_VIEW *v = [self objectAtIndex:i]; [v mas_makeConstraints:^(MASConstraintMaker *make) { if (prev) { - CGFloat offset = (1-(i/((CGFloat)self.count-1)))*itemLength; + CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(itemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1)); make.height.equalTo(@(itemLength)); if (i == (CGFloat)self.count - 1) {//last one make.bottom.equalTo(tempSuperView).offset(-tailSpacing); From b461e4381fa5bc51659b034de2f2d95ae2df463b Mon Sep 17 00:00:00 2001 From: bibibi <418452686@qq.com> Date: Tue, 1 Sep 2015 22:40:45 +0800 Subject: [PATCH 5/5] fix some typo and language stuff --- .../MASExampleDistributeView.m | 4 ++-- Masonry/NSArray+MASAdditions.h | 24 +++++++++---------- Masonry/NSArray+MASAdditions.m | 24 +++++++++---------- Tests/Specs/NSArray+MASAdditionsSpec.m | 8 +++---- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/Examples/Masonry iOS Examples/MASExampleDistributeView.m b/Examples/Masonry iOS Examples/MASExampleDistributeView.m index 904ca203..f447054b 100644 --- a/Examples/Masonry iOS Examples/MASExampleDistributeView.m +++ b/Examples/Masonry iOS Examples/MASExampleDistributeView.m @@ -27,7 +27,7 @@ - (id)init { unsigned int type = arc4random()%4; switch (type) { case 0: - [arr mas_distributeViewsAlongAxis:MASAxisTypeHorizon withFixedSpacing:20 leadSpacing:5 tailSpacing:5]; + [arr mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedSpacing:20 leadSpacing:5 tailSpacing:5]; [arr makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(@60); make.height.equalTo(@60); @@ -41,7 +41,7 @@ - (id)init { }]; break; case 2: - [arr mas_distributeViewsAlongAxis:MASAxisTypeHorizon withFixedItemLength:30 leadSpacing:200 tailSpacing:30]; + [arr mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedItemLength:30 leadSpacing:200 tailSpacing:30]; [arr makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(@60); make.height.equalTo(@60); diff --git a/Masonry/NSArray+MASAdditions.h b/Masonry/NSArray+MASAdditions.h index 9ed324ab..83be23d5 100644 --- a/Masonry/NSArray+MASAdditions.h +++ b/Masonry/NSArray+MASAdditions.h @@ -11,7 +11,7 @@ #import "MASViewAttribute.h" typedef NS_ENUM(NSUInteger, MASAxisType) { - MASAxisTypeHorizon, + MASAxisTypeHorizontal, MASAxisTypeVertical }; @@ -50,23 +50,23 @@ typedef NS_ENUM(NSUInteger, MASAxisType) { - (NSArray *)mas_remakeConstraints:(void (^)(MASConstraintMaker *make))block; /** - * distribute with fixed spaceing + * distribute with fixed spacing * - * @param axisType horizon/vertical - * @param paddingSpace space - * @param leadSpacing head - * @param tailSpacing tail + * @param axisType which axis to distribute items along + * @param fixedSpacing the spacing between each item + * @param leadSpacing the spacing before the first item and the container + * @param tailSpacing the spacing after the last item and the container */ -- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)paddingSpace leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; +- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; /** * distribute with fixed item size * - * @param axisType horizon/vertical - * @param itemLength item size - * @param leadSpacing head - * @param tailSpacing tail + * @param axisType which axis to distribute items along + * @param fixedItemLength the fixed length of each item + * @param leadSpacing the spacing before the first item and the container + * @param tailSpacing the spacing after the last item and the container */ -- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)itemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; +- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; @end diff --git a/Masonry/NSArray+MASAdditions.m b/Masonry/NSArray+MASAdditions.m index 36e2b6de..2988683d 100644 --- a/Masonry/NSArray+MASAdditions.m +++ b/Masonry/NSArray+MASAdditions.m @@ -38,21 +38,21 @@ - (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block { return constraints; } -- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)paddingSpace leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing { +- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing { if (self.count < 2) { NSAssert(self.count>1,@"views to distribute need to bigger than one"); return; } MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews]; - if (axisType == MASAxisTypeHorizon) { + if (axisType == MASAxisTypeHorizontal) { MAS_VIEW *prev; for (int i = 0; i < self.count; i++) { MAS_VIEW *v = [self objectAtIndex:i]; [v mas_makeConstraints:^(MASConstraintMaker *make) { if (prev) { make.width.equalTo(prev); - make.left.equalTo(prev.mas_right).offset(paddingSpace); + make.left.equalTo(prev.mas_right).offset(fixedSpacing); if (i == (CGFloat)self.count - 1) {//last one make.right.equalTo(tempSuperView).offset(-tailSpacing); } @@ -72,7 +72,7 @@ - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGF [v mas_makeConstraints:^(MASConstraintMaker *make) { if (prev) { make.height.equalTo(prev); - make.top.equalTo(prev.mas_bottom).offset(paddingSpace); + make.top.equalTo(prev.mas_bottom).offset(fixedSpacing); if (i == (CGFloat)self.count - 1) {//last one make.bottom.equalTo(tempSuperView).offset(-tailSpacing); } @@ -87,21 +87,21 @@ - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGF } } -- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)itemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing { +- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing { if (self.count < 2) { NSAssert(self.count>1,@"views to distribute need to bigger than one"); return; } MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews]; - if (axisType == MASAxisTypeHorizon) { + if (axisType == MASAxisTypeHorizontal) { MAS_VIEW *prev; for (int i = 0; i < self.count; i++) { MAS_VIEW *v = [self objectAtIndex:i]; [v mas_makeConstraints:^(MASConstraintMaker *make) { if (prev) { - CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(itemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1)); - make.width.equalTo(@(itemLength)); + CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(fixedItemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1)); + make.width.equalTo(@(fixedItemLength)); if (i == (CGFloat)self.count - 1) {//last one make.right.equalTo(tempSuperView).offset(-tailSpacing); } @@ -111,7 +111,7 @@ - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:( } else {//first one make.left.equalTo(tempSuperView).offset(leadSpacing); - make.width.equalTo(@(itemLength)); + make.width.equalTo(@(fixedItemLength)); } }]; prev = v; @@ -123,8 +123,8 @@ - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:( MAS_VIEW *v = [self objectAtIndex:i]; [v mas_makeConstraints:^(MASConstraintMaker *make) { if (prev) { - CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(itemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1)); - make.height.equalTo(@(itemLength)); + CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(fixedItemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1)); + make.height.equalTo(@(fixedItemLength)); if (i == (CGFloat)self.count - 1) {//last one make.bottom.equalTo(tempSuperView).offset(-tailSpacing); } @@ -134,7 +134,7 @@ - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:( } else {//first one make.top.equalTo(tempSuperView).offset(leadSpacing); - make.height.equalTo(@(itemLength)); + make.height.equalTo(@(fixedItemLength)); } }]; prev = v; diff --git a/Tests/Specs/NSArray+MASAdditionsSpec.m b/Tests/Specs/NSArray+MASAdditionsSpec.m index 280f94fe..5c3f7d1b 100644 --- a/Tests/Specs/NSArray+MASAdditionsSpec.m +++ b/Tests/Specs/NSArray+MASAdditionsSpec.m @@ -69,7 +69,7 @@ - (void)testDistributeViewsWithFixedSpacingShouldFailWhenArrayContainsLessTwoVie [superView addSubview:subject2]; NSArray *views = @[ subject1]; expect(^{ - [views mas_distributeViewsAlongAxis:MASAxisTypeHorizon withFixedSpacing:10.0 leadSpacing:5.0 tailSpacing:5.0]; + [views mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedSpacing:10.0 leadSpacing:5.0 tailSpacing:5.0]; }).to.raiseAny(); } @@ -84,7 +84,7 @@ - (void)testDistributeViewsWithFixedItemLengthShouldFailWhenArrayContainsLessTwo [superView addSubview:subject2]; NSArray *views = @[ subject1]; expect(^{ - [views mas_distributeViewsAlongAxis:MASAxisTypeHorizon withFixedSpacing:10.0 leadSpacing:5.0 tailSpacing:5.0]; + [views mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedSpacing:10.0 leadSpacing:5.0 tailSpacing:5.0]; }).to.raiseAny(); } @@ -103,7 +103,7 @@ - (void)testDistributeViewsWithFixedSpacingShouldHaveCorrectNumberOfConstraints NSArray *views = @[ subject1,subject2,subject3 ]; - [views mas_distributeViewsAlongAxis:MASAxisTypeHorizon withFixedSpacing:10.0 leadSpacing:5.0 tailSpacing:5.0]; + [views mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedSpacing:10.0 leadSpacing:5.0 tailSpacing:5.0]; //left view NSArray *arr1 = [MASViewConstraint installedConstraintsForView:subject1]; @@ -132,7 +132,7 @@ - (void)testDistributeViewsWithFixedItemLengthShouldHaveCorrectNumberOfConstrain NSArray *views = @[ subject1,subject2,subject3 ]; - [views mas_distributeViewsAlongAxis:MASAxisTypeHorizon withFixedItemLength:30.0 leadSpacing:5.0 tailSpacing:5.0]; + [views mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedItemLength:30.0 leadSpacing:5.0 tailSpacing:5.0]; //left view NSArray *arr1 = [MASViewConstraint installedConstraintsForView:subject1];