From db3d753e10dc91bcba5f6df11be0e17db52d707d Mon Sep 17 00:00:00 2001 From: Thomas Visser Date: Tue, 23 Jun 2015 09:14:03 +0200 Subject: [PATCH] Adding baseline align support --- Pod/Classes/OAStackView+Traversal.h | 2 + Pod/Classes/OAStackView.h | 5 +- Pod/Classes/OAStackView.m | 4 ++ Pod/Classes/OAStackViewAlignmentStrategy.h | 4 +- Pod/Classes/OAStackViewAlignmentStrategy.m | 72 +++++++++++++++++++++- 5 files changed, 82 insertions(+), 5 deletions(-) diff --git a/Pod/Classes/OAStackView+Traversal.h b/Pod/Classes/OAStackView+Traversal.h index 92c4007..d545454 100644 --- a/Pod/Classes/OAStackView+Traversal.h +++ b/Pod/Classes/OAStackView+Traversal.h @@ -18,6 +18,8 @@ - (void)iterateVisibleViews:(void (^) (UIView *view, UIView *previousView))block; +- (NSArray*)currentVisibleViews; + - (UIView*)lastVisibleItem; - (NSLayoutConstraint*)firstViewConstraint; diff --git a/Pod/Classes/OAStackView.h b/Pod/Classes/OAStackView.h index 4a358d6..bcf9817 100644 --- a/Pod/Classes/OAStackView.h +++ b/Pod/Classes/OAStackView.h @@ -55,7 +55,7 @@ typedef NS_ENUM(NSInteger, OAStackViewAlignment) { */ OAStackViewAlignmentLeading, OAStackViewAlignmentTop = OAStackViewAlignmentLeading, - OAStackViewAlignmentFirstBaseline, // Valid for horizontal axis only + OAStackViewAlignmentFirstBaseline NS_ENUM_AVAILABLE_IOS(8_0), // Valid for horizontal axis only /* Center the items in a vertical stack horizontally or the items in a horizontal stack vertically @@ -68,7 +68,8 @@ typedef NS_ENUM(NSInteger, OAStackViewAlignment) { */ OAStackViewAlignmentTrailing, OAStackViewAlignmentBottom = OAStackViewAlignmentTrailing, - OAStackViewAlignmentLastBaseline, // Valid for horizontal axis only + OAStackViewAlignmentBaseline, + OAStackViewAlignmentLastBaseline = OAStackViewAlignmentBaseline, // Valid for horizontal axis only }; // Keep older versions of the compiler happy diff --git a/Pod/Classes/OAStackView.m b/Pod/Classes/OAStackView.m index 5c4b687..200fab8 100644 --- a/Pod/Classes/OAStackView.m +++ b/Pod/Classes/OAStackView.m @@ -112,6 +112,7 @@ - (void)setAlignment:(OAStackViewAlignment)alignment { [self iterateVisibleViews:^(UIView *view, UIView *previousView) { [self.alignmentStrategy addConstraintsOnOtherAxis:view]; + [self.alignmentStrategy alignView:view withPreviousView:previousView]; }]; } @@ -134,6 +135,7 @@ - (void)setDistribution:(OAStackViewDistribution)distribution { [self iterateVisibleViews:^(UIView *view, UIView *previousView) { [self.alignmentStrategy addConstraintsOnOtherAxis:view]; [self.distributionStrategy alignView:view afterView:previousView]; + [self.alignmentStrategy alignView:view withPreviousView:previousView]; }]; } @@ -239,8 +241,10 @@ - (void)insertArrangedSubview:(UIView *)view atIndex:(NSUInteger)stackIndex newI } [self.distributionStrategy alignView:view afterView:previousView]; + [self.alignmentStrategy alignView:view withPreviousView:previousView]; [self.alignmentStrategy addConstraintsOnOtherAxis:view]; [self.distributionStrategy alignView:nextView afterView:view]; + [self.alignmentStrategy alignView:nextView withPreviousView:view]; } - (void)removeViewFromArrangedViews:(UIView*)view permanently:(BOOL)permanently { diff --git a/Pod/Classes/OAStackViewAlignmentStrategy.h b/Pod/Classes/OAStackViewAlignmentStrategy.h index bb27509..6e5bfc8 100644 --- a/Pod/Classes/OAStackViewAlignmentStrategy.h +++ b/Pod/Classes/OAStackViewAlignmentStrategy.h @@ -15,6 +15,8 @@ + (OAStackViewAlignmentStrategy*)strategyWithStackView:(OAStackView *)stackView; - (void)addConstraintsOnOtherAxis:(UIView*)view; -- (void)removeAddedConstraints;; +- (void)alignView:(UIView*)view withPreviousView:(UIView*)previousView; + +- (void)removeAddedConstraints; @end diff --git a/Pod/Classes/OAStackViewAlignmentStrategy.m b/Pod/Classes/OAStackViewAlignmentStrategy.m index 631ab5a..6f38e67 100644 --- a/Pod/Classes/OAStackViewAlignmentStrategy.m +++ b/Pod/Classes/OAStackViewAlignmentStrategy.m @@ -20,6 +20,16 @@ @interface OAStackViewAlignmentStrategyLeading : OAStackViewAlignmentStrategy @interface OAStackViewAlignmentStrategyCenter: OAStackViewAlignmentStrategy @end +@interface OAStackViewAlignmentStrategyBaseline: OAStackViewAlignmentStrategy +- (NSLayoutAttribute)baselineAttribute; +@end + +@interface OAStackViewAlignmentStrategyLastBaseline: OAStackViewAlignmentStrategyBaseline +@end + +@interface OAStackViewAlignmentStrategyFirstBaseline: OAStackViewAlignmentStrategyBaseline +@end + @interface OAStackViewAlignmentStrategy () @property(nonatomic, weak) OAStackView *stackView; @property(nonatomic) NSMutableArray *constraints; @@ -47,7 +57,15 @@ + (OAStackViewAlignmentStrategy*)strategyWithStackView:(OAStackView *)stackView case OAStackViewAlignmentCenter: cls = [OAStackViewAlignmentStrategyCenter class]; break; - + + case OAStackViewAlignmentBaseline: + cls = [OAStackViewAlignmentStrategyLastBaseline class]; + break; + + case OAStackViewAlignmentFirstBaseline: + cls = [OAStackViewAlignmentStrategyFirstBaseline class]; + break; + default: break; } @@ -75,7 +93,14 @@ - (void)addConstraintsOnOtherAxis:(UIView*)view { id arr = [self constraintsalignViewOnOtherAxis:view]; [self.constraints addObjectsFromArray:arr]; - [self.stackView addConstraints:arr]; + if (arr) { [self.stackView addConstraints:arr]; } +} + +- (void)alignView:(UIView*)view withPreviousView:(UIView*)previousView { + id arr = [self constraintsAlignView:view afterPreviousView:previousView]; + [self.constraints addObjectsFromArray:arr]; + + if (arr) { [self.stackView addConstraints:arr]; } } - (NSMutableArray *)constraints { @@ -93,6 +118,8 @@ - (void)removeAddedConstraints { - (NSArray*)constraintsalignViewOnOtherAxis:(UIView*)view { /* subclassing */ return nil; } +- (NSArray*)constraintsAlignView:(UIView *)view afterPreviousView:(UIView*)afterView { /* subclassing */ return nil; } + @end @implementation OAStackViewAlignmentStrategyFill @@ -150,3 +177,44 @@ - (NSArray*)constraintsalignViewOnOtherAxis:(UIView*)view { } @end + +@implementation OAStackViewAlignmentStrategyBaseline + +- (NSArray*)constraintsalignViewOnOtherAxis:(UIView*)view { + id constraintString = [NSString stringWithFormat:@"%@:|-(>=0@750)-[view]-(>=0@750)-|", [self otherAxisString]]; + + return [NSLayoutConstraint constraintsWithVisualFormat:constraintString + options:0 + metrics:nil + views:NSDictionaryOfVariableBindings(view)]; +} + +- (NSArray*)constraintsAlignView:(UIView *)view afterPreviousView:(UIView*)afterView { + if (!view || !afterView) { return nil; } + + return @[[NSLayoutConstraint constraintWithItem:view + attribute:[self baselineAttribute] + relatedBy:NSLayoutRelationEqual toItem:afterView + attribute:[self baselineAttribute] multiplier:1.0f + constant:0.0f]]; +} + +- (NSLayoutAttribute)baselineAttribute +{ + return NSLayoutAttributeBaseline; +} + +@end + +@implementation OAStackViewAlignmentStrategyFirstBaseline + +- (NSLayoutAttribute)baselineAttribute +{ + return NSLayoutAttributeFirstBaseline; +} + +@end + +@implementation OAStackViewAlignmentStrategyLastBaseline + +@end