From 988ac834172fd1a84bfee78ad713503d450a30be Mon Sep 17 00:00:00 2001 From: Ignacio Romero Zurbuchen Date: Fri, 5 Feb 2016 01:40:10 -0300 Subject: [PATCH 1/8] Lighter hairline for @3x devices --- Source/DZNSegmentedControl.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/DZNSegmentedControl.m b/Source/DZNSegmentedControl.m index 3d7d4ea..5486aa1 100644 --- a/Source/DZNSegmentedControl.m +++ b/Source/DZNSegmentedControl.m @@ -342,7 +342,9 @@ - (UIColor *)hairlineColor - (CGRect)hairlineRect { - CGRect frame = CGRectMake(0.0f, 0.0f, self.frame.size.width, 0.5f); + CGFloat hairlineWidth = 1.0 / [UIScreen mainScreen].scale; + + CGRect frame = CGRectMake(0.0f, 0.0f, self.frame.size.width, hairlineWidth); frame.origin.y = (self.barPosition > UIBarPositionBottom) ? 0.0f : self.frame.size.height; return frame; From 2b072f198b68c7e301679f6aa6c1ae9753e503b1 Mon Sep 17 00:00:00 2001 From: Ignacio Romero Zurbuchen Date: Mon, 8 Feb 2016 22:31:34 -0800 Subject: [PATCH 2/8] Also updates the selection indicator's background color when changing the tint color of the entire view. --- Source/DZNSegmentedControl.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/DZNSegmentedControl.m b/Source/DZNSegmentedControl.m index 5486aa1..a822ee1 100644 --- a/Source/DZNSegmentedControl.m +++ b/Source/DZNSegmentedControl.m @@ -494,6 +494,8 @@ - (void)setTintColor:(UIColor *)color [self setTitleColor:color forState:UIControlStateHighlighted]; [self setTitleColor:color forState:UIControlStateSelected]; } + + self.selectionIndicator.backgroundColor = color; } - (void)setScrollOffset:(CGPoint)scrollOffset contentSize:(CGSize)contentSize From 21aeeab14d736970d1dd087f7cd94870acd19038 Mon Sep 17 00:00:00 2001 From: Ignacio Romero Zurbuchen Date: Tue, 9 Feb 2016 10:39:05 -0800 Subject: [PATCH 3/8] Fixes disableSelectedSegment not being honoured anymore. Also, disables any highlight state of the buttons. --- .../TableView-Example.storyboard | 16 ++-- .../TableView Example/TableViewController.m | 3 + Source/DZNSegmentedControl.m | 79 ++++++++++++------- 3 files changed, 58 insertions(+), 40 deletions(-) diff --git a/Examples/Sample/TableView Example/TableView-Example.storyboard b/Examples/Sample/TableView Example/TableView-Example.storyboard index bf381ba..42e59ed 100644 --- a/Examples/Sample/TableView Example/TableView-Example.storyboard +++ b/Examples/Sample/TableView Example/TableView-Example.storyboard @@ -1,7 +1,8 @@ - + - + + @@ -11,13 +12,13 @@ - + - + - + @@ -52,10 +53,5 @@ - - - - - diff --git a/Examples/Sample/TableView Example/TableViewController.m b/Examples/Sample/TableView Example/TableViewController.m index 2135a56..c88d856 100644 --- a/Examples/Sample/TableView Example/TableViewController.m +++ b/Examples/Sample/TableView Example/TableViewController.m @@ -87,6 +87,7 @@ - (DZNSegmentedControl *)control _control.delegate = self; _control.selectedSegmentIndex = 1; _control.bouncySelectionIndicator = NO; + _control.disableSelectedSegment = NO; _control.height = 60.0f; // _control.height = 120.0f; @@ -201,6 +202,8 @@ - (void)updateControlCounts - (void)didChangeSegment:(DZNSegmentedControl *)control { + NSLog(@"%s",__FUNCTION__); + [self.tableView reloadData]; } diff --git a/Source/DZNSegmentedControl.m b/Source/DZNSegmentedControl.m index a822ee1..15a8565 100644 --- a/Source/DZNSegmentedControl.m +++ b/Source/DZNSegmentedControl.m @@ -10,6 +10,9 @@ #import "DZNSegmentedControl.h" +@interface DZNSaticButton : UIButton +@end + @interface DZNSegmentedControl () @property (nonatomic) BOOL initializing; @@ -190,23 +193,23 @@ - (NSArray *)buttons { NSMutableArray *buttons = [NSMutableArray arrayWithCapacity:self.items.count]; - for (UIView *view in self.subviews) { - if ([view isKindOfClass:[UIButton class]]) { - [buttons addObject:view]; + for (DZNSaticButton *btn in self.subviews) { + if ([btn isKindOfClass:[DZNSaticButton class]]) { + [buttons addObject:btn]; } } return buttons; } -- (UIButton *)buttonAtIndex:(NSUInteger)segment +- (DZNSaticButton *)buttonAtIndex:(NSUInteger)segment { if (self.items.count > 0 && segment < [self buttons].count) { - return (UIButton *)[[self buttons] objectAtIndex:segment]; + return (DZNSaticButton *)[[self buttons] objectAtIndex:segment]; } return nil; } -- (UIButton *)selectedButton +- (DZNSaticButton *)selectedButton { if (self.selectedSegmentIndex >= 0) { return [self buttonAtIndex:self.selectedSegmentIndex]; @@ -220,7 +223,7 @@ - (NSString *)stringForSegmentAtIndex:(NSUInteger)segment return nil; } - UIButton *button = [self buttonAtIndex:segment]; + DZNSaticButton *button = [self buttonAtIndex:segment]; return [[button attributedTitleForState:UIControlStateNormal] string]; } @@ -293,7 +296,7 @@ - (BOOL)autoAdjustSelectionIndicatorWidth - (CGRect)selectionIndicatorRect { - UIButton *button = [self selectedButton]; + DZNSaticButton *button = [self selectedButton]; id item = self.items[button.tag]; @@ -481,7 +484,7 @@ - (void)setTintColor:(UIColor *)color if (self.isImageMode) { - for (UIButton *btn in self.buttons) { + for (DZNSaticButton *btn in self.buttons) { UIImage *normalImage = [btn imageForState:UIControlStateNormal]; UIImage *selectedImage = [normalImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; @@ -555,7 +558,10 @@ - (void)setSelectedSegmentIndex:(NSInteger)segment animated:(BOOL)animated UIButton *targetButton = self.buttons[segment]; targetButton.selected = YES; - targetButton.userInteractionEnabled = NO; + + if (self.disableSelectedSegment) { + targetButton.userInteractionEnabled = NO; + } _selectedSegmentIndex = segment; @@ -592,7 +598,7 @@ - (void)setTintColor:(UIColor *)tintColor forSegmentAtIndex:(NSUInteger)segment NSAssert([tintColor isKindOfClass:[UIColor class]], @"Cannot assign a tint color with an unvalid color object."); - UIButton *button = [self buttonAtIndex:segment]; + DZNSaticButton *button = [self buttonAtIndex:segment]; if (!self.isImageMode) { button.backgroundColor = tintColor; @@ -662,7 +668,7 @@ - (void)setImage:(UIImage *)image forSegmentAtIndex:(NSUInteger)segment - (void)setAttributedTitle:(NSAttributedString *)attributedString forSegmentAtIndex:(NSUInteger)segment { - UIButton *button = [self buttonAtIndex:segment]; + DZNSaticButton *button = [self buttonAtIndex:segment]; button.titleLabel.numberOfLines = (self.showsCount) ? 2 : 1; [button setAttributedTitle:attributedString forState:UIControlStateNormal]; @@ -686,9 +692,9 @@ - (void)setTitleColor:(UIColor *)color forState:(UIControlState)state NSAssert([color isKindOfClass:[UIColor class]], @"Cannot assign a title color with an unvalid color object."); - for (UIButton *button in [self buttons]) { + for (DZNSaticButton *btn in [self buttons]) { - NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:[button attributedTitleForState:state]]; + NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:[btn attributedTitleForState:state]]; NSString *string = attributedString.string; NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init]; @@ -739,7 +745,7 @@ - (void)setTitleColor:(UIColor *)color forState:(UIControlState)state [attributedString addAttribute:NSForegroundColorAttributeName value:color range:NSMakeRange(0, attributedString.string.length)]; } - [button setAttributedTitle:attributedString forState:state]; + [btn setAttributedTitle:attributedString forState:state]; } NSString *key = [NSString stringWithFormat:@"UIControlState%d", (int)state]; @@ -792,7 +798,7 @@ - (void)setNumberFormatter:(NSNumberFormatter *)numberFormatter - (void)setEnabled:(BOOL)enabled forSegmentAtIndex:(NSUInteger)segment { - UIButton *button = [self buttonAtIndex:segment]; + DZNSaticButton *button = [self buttonAtIndex:segment]; button.enabled = enabled; } @@ -812,6 +818,14 @@ - (void)setAdjustsButtonTopInset:(BOOL)adjustsButtonTopInset [self layoutSubviews]; } +- (void)setDisableSelectedSegment:(BOOL)disableSelectedSegment +{ + _disableSelectedSegment = disableSelectedSegment; + + DZNSaticButton *button = [self selectedButton]; + button.userInteractionEnabled = !disableSelectedSegment; +} + #pragma mark - DZNSegmentedControl Configuration @@ -828,7 +842,7 @@ - (void)insertAllSegments - (void)addButtonForSegment:(NSUInteger)segment { - UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; + DZNSaticButton *button = [DZNSaticButton buttonWithType:UIButtonTypeCustom]; [button addTarget:self action:@selector(willSelectedButton:) forControlEvents:UIControlEventTouchDown]; [button addTarget:self action:@selector(didSelectButton:) forControlEvents:UIControlEventTouchDragOutside|UIControlEventTouchDragInside|UIControlEventTouchDragEnter|UIControlEventTouchDragExit|UIControlEventTouchCancel|UIControlEventTouchUpInside|UIControlEventTouchUpOutside]; @@ -845,8 +859,8 @@ - (void)addButtonForSegment:(NSUInteger)segment - (void)configureSegments { - for (UIButton *button in [self buttons]) { - [self configureButtonForSegment:button.tag]; + for (DZNSaticButton *btn in [self buttons]) { + [self configureButtonForSegment:btn.tag]; } [self configureAccessoryViews]; @@ -906,19 +920,17 @@ - (void)configureButtonTitle:(NSString *)title forSegment:(NSUInteger)segment - (void)configureButtonImage:(UIImage *)image forSegment:(NSUInteger)segment { - UIButton *button = [self buttonAtIndex:segment]; + DZNSaticButton *button = [self buttonAtIndex:segment]; [button setImage:image forState:UIControlStateNormal]; [self setAttributedTitle:nil forSegmentAtIndex:segment]; } -- (void)willSelectedButton:(id)sender +- (void)willSelectedButton:(DZNSaticButton *)sender { - UIButton *button = (UIButton *)sender; - - if (self.selectedSegmentIndex != button.tag) { - [self setSelectedSegmentIndex:button.tag animated:YES]; + if (self.selectedSegmentIndex != sender.tag) { + [self setSelectedSegmentIndex:sender.tag animated:YES]; [self sendActionsForControlEvents:UIControlEventValueChanged]; } else if (!self.disableSelectedSegment) { @@ -926,12 +938,10 @@ - (void)willSelectedButton:(id)sender } } -- (void)didSelectButton:(id)sender +- (void)didSelectButton:(DZNSaticButton *)sender { - UIButton *button = (UIButton *)sender; - - button.highlighted = NO; - button.selected = YES; + sender.highlighted = NO; + sender.selected = YES; } - (void)unselectAllButtons @@ -972,3 +982,12 @@ + (NSNumberFormatter *)defaultFormatter } @end + + +@implementation DZNSaticButton + +- (void)setHighlighted:(BOOL)highlighted { + // Let's not call super here, so there is no highlight state. +} + +@end From db295c372260bee7258cb7a85719767940052882 Mon Sep 17 00:00:00 2001 From: Ignacio Romero Zurbuchen Date: Tue, 9 Feb 2016 10:44:13 -0800 Subject: [PATCH 4/8] Typo --- Source/DZNSegmentedControl.m | 45 +++++++++++++++--------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/Source/DZNSegmentedControl.m b/Source/DZNSegmentedControl.m index 15a8565..830e47c 100644 --- a/Source/DZNSegmentedControl.m +++ b/Source/DZNSegmentedControl.m @@ -10,7 +10,7 @@ #import "DZNSegmentedControl.h" -@interface DZNSaticButton : UIButton +@interface DZNStaticButton : UIButton @end @interface DZNSegmentedControl () @@ -191,25 +191,18 @@ - (NSUInteger)numberOfSegments - (NSArray *)buttons { - NSMutableArray *buttons = [NSMutableArray arrayWithCapacity:self.items.count]; - - for (DZNSaticButton *btn in self.subviews) { - if ([btn isKindOfClass:[DZNSaticButton class]]) { - [buttons addObject:btn]; - } - } - return buttons; + return self.items; } -- (DZNSaticButton *)buttonAtIndex:(NSUInteger)segment +- (DZNStaticButton *)buttonAtIndex:(NSUInteger)segment { if (self.items.count > 0 && segment < [self buttons].count) { - return (DZNSaticButton *)[[self buttons] objectAtIndex:segment]; + return (DZNStaticButton *)[[self buttons] objectAtIndex:segment]; } return nil; } -- (DZNSaticButton *)selectedButton +- (DZNStaticButton *)selectedButton { if (self.selectedSegmentIndex >= 0) { return [self buttonAtIndex:self.selectedSegmentIndex]; @@ -223,7 +216,7 @@ - (NSString *)stringForSegmentAtIndex:(NSUInteger)segment return nil; } - DZNSaticButton *button = [self buttonAtIndex:segment]; + DZNStaticButton *button = [self buttonAtIndex:segment]; return [[button attributedTitleForState:UIControlStateNormal] string]; } @@ -296,7 +289,7 @@ - (BOOL)autoAdjustSelectionIndicatorWidth - (CGRect)selectionIndicatorRect { - DZNSaticButton *button = [self selectedButton]; + DZNStaticButton *button = [self selectedButton]; id item = self.items[button.tag]; @@ -484,7 +477,7 @@ - (void)setTintColor:(UIColor *)color if (self.isImageMode) { - for (DZNSaticButton *btn in self.buttons) { + for (DZNStaticButton *btn in self.buttons) { UIImage *normalImage = [btn imageForState:UIControlStateNormal]; UIImage *selectedImage = [normalImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; @@ -598,7 +591,7 @@ - (void)setTintColor:(UIColor *)tintColor forSegmentAtIndex:(NSUInteger)segment NSAssert([tintColor isKindOfClass:[UIColor class]], @"Cannot assign a tint color with an unvalid color object."); - DZNSaticButton *button = [self buttonAtIndex:segment]; + DZNStaticButton *button = [self buttonAtIndex:segment]; if (!self.isImageMode) { button.backgroundColor = tintColor; @@ -668,7 +661,7 @@ - (void)setImage:(UIImage *)image forSegmentAtIndex:(NSUInteger)segment - (void)setAttributedTitle:(NSAttributedString *)attributedString forSegmentAtIndex:(NSUInteger)segment { - DZNSaticButton *button = [self buttonAtIndex:segment]; + DZNStaticButton *button = [self buttonAtIndex:segment]; button.titleLabel.numberOfLines = (self.showsCount) ? 2 : 1; [button setAttributedTitle:attributedString forState:UIControlStateNormal]; @@ -692,7 +685,7 @@ - (void)setTitleColor:(UIColor *)color forState:(UIControlState)state NSAssert([color isKindOfClass:[UIColor class]], @"Cannot assign a title color with an unvalid color object."); - for (DZNSaticButton *btn in [self buttons]) { + for (DZNStaticButton *btn in [self buttons]) { NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:[btn attributedTitleForState:state]]; NSString *string = attributedString.string; @@ -798,7 +791,7 @@ - (void)setNumberFormatter:(NSNumberFormatter *)numberFormatter - (void)setEnabled:(BOOL)enabled forSegmentAtIndex:(NSUInteger)segment { - DZNSaticButton *button = [self buttonAtIndex:segment]; + DZNStaticButton *button = [self buttonAtIndex:segment]; button.enabled = enabled; } @@ -822,7 +815,7 @@ - (void)setDisableSelectedSegment:(BOOL)disableSelectedSegment { _disableSelectedSegment = disableSelectedSegment; - DZNSaticButton *button = [self selectedButton]; + DZNStaticButton *button = [self selectedButton]; button.userInteractionEnabled = !disableSelectedSegment; } @@ -842,7 +835,7 @@ - (void)insertAllSegments - (void)addButtonForSegment:(NSUInteger)segment { - DZNSaticButton *button = [DZNSaticButton buttonWithType:UIButtonTypeCustom]; + DZNStaticButton *button = [DZNStaticButton buttonWithType:UIButtonTypeCustom]; [button addTarget:self action:@selector(willSelectedButton:) forControlEvents:UIControlEventTouchDown]; [button addTarget:self action:@selector(didSelectButton:) forControlEvents:UIControlEventTouchDragOutside|UIControlEventTouchDragInside|UIControlEventTouchDragEnter|UIControlEventTouchDragExit|UIControlEventTouchCancel|UIControlEventTouchUpInside|UIControlEventTouchUpOutside]; @@ -859,7 +852,7 @@ - (void)addButtonForSegment:(NSUInteger)segment - (void)configureSegments { - for (DZNSaticButton *btn in [self buttons]) { + for (DZNStaticButton *btn in [self buttons]) { [self configureButtonForSegment:btn.tag]; } @@ -920,14 +913,14 @@ - (void)configureButtonTitle:(NSString *)title forSegment:(NSUInteger)segment - (void)configureButtonImage:(UIImage *)image forSegment:(NSUInteger)segment { - DZNSaticButton *button = [self buttonAtIndex:segment]; + DZNStaticButton *button = [self buttonAtIndex:segment]; [button setImage:image forState:UIControlStateNormal]; [self setAttributedTitle:nil forSegmentAtIndex:segment]; } -- (void)willSelectedButton:(DZNSaticButton *)sender +- (void)willSelectedButton:(DZNStaticButton *)sender { if (self.selectedSegmentIndex != sender.tag) { [self setSelectedSegmentIndex:sender.tag animated:YES]; @@ -938,7 +931,7 @@ - (void)willSelectedButton:(DZNSaticButton *)sender } } -- (void)didSelectButton:(DZNSaticButton *)sender +- (void)didSelectButton:(DZNStaticButton *)sender { sender.highlighted = NO; sender.selected = YES; @@ -984,7 +977,7 @@ + (NSNumberFormatter *)defaultFormatter @end -@implementation DZNSaticButton +@implementation DZNStaticButton - (void)setHighlighted:(BOOL)highlighted { // Let's not call super here, so there is no highlight state. From 61a88894efe909e360db1365d14deda72c97d15f Mon Sep 17 00:00:00 2001 From: Ignacio Romero Zurbuchen Date: Tue, 9 Feb 2016 11:01:21 -0800 Subject: [PATCH 5/8] Fixes mistake from previous commits, removing some implementation accidentally. Instead of integrating and creating a new array, it's simplified by filtering the subviews array. --- Source/DZNSegmentedControl.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/DZNSegmentedControl.m b/Source/DZNSegmentedControl.m index 830e47c..4bd08b7 100644 --- a/Source/DZNSegmentedControl.m +++ b/Source/DZNSegmentedControl.m @@ -191,7 +191,8 @@ - (NSUInteger)numberOfSegments - (NSArray *)buttons { - return self.items; + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@", [DZNStaticButton class]]; + return [self.subviews filteredArrayUsingPredicate:predicate]; } - (DZNStaticButton *)buttonAtIndex:(NSUInteger)segment From 89b747c5706968445c2b86c5d48743844f8540bc Mon Sep 17 00:00:00 2001 From: Ignacio Romero Zurbuchen Date: Tue, 9 Feb 2016 22:43:41 -0800 Subject: [PATCH 6/8] Allows not selecting any segment, hiding the selection indicator and deselecting any segment button. --- Examples/Sample.xcodeproj/project.pbxproj | 6 +- .../ScrollView-Example.storyboard | 12 +- .../TableView Example/TableViewController.m | 3 + Source/DZNSegmentedControl.h | 4 +- Source/DZNSegmentedControl.m | 139 +++++++++--------- 5 files changed, 79 insertions(+), 85 deletions(-) diff --git a/Examples/Sample.xcodeproj/project.pbxproj b/Examples/Sample.xcodeproj/project.pbxproj index 1f7b83d..7123d3a 100644 --- a/Examples/Sample.xcodeproj/project.pbxproj +++ b/Examples/Sample.xcodeproj/project.pbxproj @@ -15,7 +15,6 @@ 4FB285CA1A766D0300B573DE /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4FB285C91A766D0300B573DE /* Default-568h@2x.png */; }; 4FB285D01A7671A400B573DE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FB285611A75E94C00B573DE /* AppDelegate.m */; }; 4FB285D11A7671A400B573DE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FB285C31A766CEC00B573DE /* main.m */; }; - 4FB285D21A7671A400B573DE /* TableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FB285861A75E9F700B573DE /* TableViewController.m */; }; 4FB285D41A7671A400B573DE /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 336F7DD8CF855E383EFF085A /* libPods.a */; }; 4FB285D71A7671A400B573DE /* Storyboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4FB285C41A766CEC00B573DE /* Storyboard.storyboard */; }; 4FB285D81A7671A400B573DE /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4FB285C91A766D0300B573DE /* Default-568h@2x.png */; }; @@ -34,8 +33,8 @@ 4FEA1D801B7A5DF800E1DBDF /* CollectionView-Example.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4FEA1D7F1B7A5DF800E1DBDF /* CollectionView-Example.storyboard */; }; 4FEA1D861B7A67E700E1DBDF /* UICollectionView+SupplementaryElementScrolling.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FEA1D851B7A67E700E1DBDF /* UICollectionView+SupplementaryElementScrolling.m */; }; 4FEFACCB1B7989C700D905B8 /* images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4FEFACCA1B7989C700D905B8 /* images.xcassets */; }; - 4FEFACCC1B798CA800D905B8 /* TableView-Example.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4FB285841A75E9F700B573DE /* TableView-Example.storyboard */; }; C46F97D4245BDD7548E1F345 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 336F7DD8CF855E383EFF085A /* libPods.a */; }; + F59D40EC1C6AE665004E9AAC /* TableView-Example.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4FB285841A75E9F700B573DE /* TableView-Example.storyboard */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -332,7 +331,7 @@ 4FEFACCB1B7989C700D905B8 /* images.xcassets in Resources */, 4FB285C71A766CEC00B573DE /* Storyboard.storyboard in Resources */, 4FB285CA1A766D0300B573DE /* Default-568h@2x.png in Resources */, - 4FEFACCC1B798CA800D905B8 /* TableView-Example.storyboard in Resources */, + F59D40EC1C6AE665004E9AAC /* TableView-Example.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -470,7 +469,6 @@ files = ( 4FB285D01A7671A400B573DE /* AppDelegate.m in Sources */, 4FB285D11A7671A400B573DE /* main.m in Sources */, - 4FB285D21A7671A400B573DE /* TableViewController.m in Sources */, 4FB285E11A76730300B573DE /* ScrollViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Examples/Sample/ScrollView Example/ScrollView-Example.storyboard b/Examples/Sample/ScrollView Example/ScrollView-Example.storyboard index 26789e4..8ab9741 100644 --- a/Examples/Sample/ScrollView Example/ScrollView-Example.storyboard +++ b/Examples/Sample/ScrollView Example/ScrollView-Example.storyboard @@ -1,7 +1,8 @@ - + - + + @@ -9,7 +10,7 @@ - + @@ -60,9 +61,4 @@ - - - - - diff --git a/Examples/Sample/TableView Example/TableViewController.m b/Examples/Sample/TableView Example/TableViewController.m index c88d856..9abf840 100644 --- a/Examples/Sample/TableView Example/TableViewController.m +++ b/Examples/Sample/TableView Example/TableViewController.m @@ -161,6 +161,9 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath - (void)addSegment:(id)sender { + [self.control setSelectedSegmentIndex:DZNSegmentedControlNoSegment animated:YES]; + return; + NSUInteger newSegment = self.control.numberOfSegments; #if DEBUG_IMAGE diff --git a/Source/DZNSegmentedControl.h b/Source/DZNSegmentedControl.h index 7ef4654..f897261 100644 --- a/Source/DZNSegmentedControl.h +++ b/Source/DZNSegmentedControl.h @@ -26,7 +26,7 @@ enum { @property (nonatomic, weak) IBOutlet id delegate; /** The items displayed on the control. */ @property (nonatomic, retain) NSArray *items; -/** The index number identifying the selected segment (that is, the last segment touched). */ +/** The index number identifying the selected segment (that is, the last segment touched). Default is 0. */ @property (nonatomic) NSInteger selectedSegmentIndex; /** Returns the number of segments the receiver has. */ @property (nonatomic, readonly) NSUInteger numberOfSegments; @@ -37,7 +37,7 @@ enum { /** The height of the selection indicator. Default is 2pts. */ @property (nonatomic, readwrite) CGFloat selectionIndicatorHeight UI_APPEARANCE_SELECTOR; /** The duration of the indicator's animation. Default is 0.2 sec. */ -@property (nonatomic, readwrite) CGFloat animationDuration UI_APPEARANCE_SELECTOR; +@property (nonatomic, readwrite) NSTimeInterval animationDuration UI_APPEARANCE_SELECTOR; /** The font family to be used on labels. Default is system font (HelveticaNeue). Font size is managed by the class. */ @property (nonatomic, retain) UIFont *font UI_APPEARANCE_SELECTOR; /** The color of the hairline. Default is light gray. To hide the hairline, just set clipsToBounds to YES, like you would do it for UIToolBar & UINavigationBar. */ diff --git a/Source/DZNSegmentedControl.m b/Source/DZNSegmentedControl.m index 4bd08b7..b602c74 100644 --- a/Source/DZNSegmentedControl.m +++ b/Source/DZNSegmentedControl.m @@ -77,7 +77,7 @@ - (void)commonInit _initializing = YES; _showsCount = YES; - _selectedSegmentIndex = -1; + _selectedSegmentIndex = 0; _selectionIndicatorHeight = 2.0f; _animationDuration = 0.2; _autoAdjustSelectionIndicatorWidth = YES; @@ -121,10 +121,7 @@ - (void)layoutSubviews [self sizeToFit]; if ([self buttons].count == 0) { - _selectedSegmentIndex = -1; - } - else if (self.selectedSegmentIndex < 0) { - _selectedSegmentIndex = 0; + _selectedSegmentIndex = DZNSegmentedControlNoSegment; } [[self buttons] enumerateObjectsUsingBlock:^(UIButton *button, NSUInteger idx, BOOL *stop) { @@ -260,7 +257,6 @@ - (UIColor *)titleColorForState:(UIControlState)state if (!color) { switch (state) { case UIControlStateNormal: return [UIColor darkGrayColor]; - case UIControlStateHighlighted: return self.tintColor; case UIControlStateDisabled: return [UIColor lightGrayColor]; case UIControlStateSelected: return self.tintColor; default: return self.tintColor; @@ -292,6 +288,11 @@ - (CGRect)selectionIndicatorRect { DZNStaticButton *button = [self selectedButton]; + if (!button) { + // Let's then grab the first button, so the selection indicator is always aligned correctly. + button = [self buttonAtIndex:0]; + } + id item = self.items[button.tag]; if ([item isKindOfClass:[NSString class]]) { @@ -488,52 +489,19 @@ - (void)setTintColor:(UIColor *)color } } else { - [self setTitleColor:color forState:UIControlStateHighlighted]; [self setTitleColor:color forState:UIControlStateSelected]; } self.selectionIndicator.backgroundColor = color; } -- (void)setScrollOffset:(CGPoint)scrollOffset contentSize:(CGSize)contentSize +- (void)setHairlineColor:(UIColor *)color { - self.autoAdjustSelectionIndicatorWidth = NO; - self.bouncySelectionIndicator = NO; - - CGFloat offset = 0.0; - - // Horizontal scroll - if (self.scrollOffset.x != scrollOffset.x) { - offset = scrollOffset.x/(contentSize.width/self.numberOfSegments); - } - // Vertical scroll - else if (self.scrollOffset.y != scrollOffset.y) { - offset = scrollOffset.y/(contentSize.height/self.numberOfSegments); - } - // Skip - else { + if (self.initializing) { return; } - CGFloat buttonWidth = roundf(self.width/self.numberOfSegments); - - CGRect indicatorRect = self.selectionIndicator.frame; - indicatorRect.origin.x = (buttonWidth * offset); - self.selectionIndicator.frame = indicatorRect; - - NSUInteger index = (NSUInteger)offset; - - if (offset == truncf(offset) && self.selectedSegmentIndex != index) { - - [self unselectAllButtons]; - [self.buttons[index] setSelected:YES]; - - _selectedSegmentIndex = index; - - [self sendActionsForControlEvents:UIControlEventValueChanged]; - } - - _scrollOffset = scrollOffset; + self.hairline.backgroundColor = color; } - (void)setSelectedSegmentIndex:(NSInteger)segment @@ -550,29 +518,38 @@ - (void)setSelectedSegmentIndex:(NSInteger)segment animated:(BOOL)animated [self unselectAllButtons]; [self enableAllButtonsInteraction:YES]; - UIButton *targetButton = self.buttons[segment]; - targetButton.selected = YES; + _selectedSegmentIndex = segment; + + BOOL showSelectorIndicator = (segment >= 0 && segment < self.numberOfSegments); + + UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseInOut; + + UIButton *button = [self buttonAtIndex:segment]; + button.selected = YES; if (self.disableSelectedSegment) { - targetButton.userInteractionEnabled = NO; + button.userInteractionEnabled = NO; } - _selectedSegmentIndex = segment; - void (^animations)() = ^void(){ - self.selectionIndicator.frame = [self selectionIndicatorRect]; + if (showSelectorIndicator) { + self.selectionIndicator.frame = [self selectionIndicatorRect]; + self.selectionIndicator.alpha = 1.0f; + } + else { + self.selectionIndicator.alpha = 0.0f; + } }; if (animated) { - CGFloat duration = (self.selectedSegmentIndex < 0.0f) ? 0.0f : self.animationDuration; CGFloat damping = !self.bouncySelectionIndicator ? : 0.65f; CGFloat velocity = !self.bouncySelectionIndicator ? : 0.5f; - [UIView animateWithDuration:duration + [UIView animateWithDuration:self.animationDuration delay:0.0f usingSpringWithDamping:damping initialSpringVelocity:velocity - options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseInOut + options:options animations:animations completion:NULL]; } @@ -666,12 +643,10 @@ - (void)setAttributedTitle:(NSAttributedString *)attributedString forSegmentAtIn button.titleLabel.numberOfLines = (self.showsCount) ? 2 : 1; [button setAttributedTitle:attributedString forState:UIControlStateNormal]; - [button setAttributedTitle:attributedString forState:UIControlStateHighlighted]; [button setAttributedTitle:attributedString forState:UIControlStateSelected]; [button setAttributedTitle:attributedString forState:UIControlStateDisabled]; [self setTitleColor:[self titleColorForState:UIControlStateNormal] forState:UIControlStateNormal]; - [self setTitleColor:[self titleColorForState:UIControlStateHighlighted] forState:UIControlStateHighlighted]; [self setTitleColor:[self titleColorForState:UIControlStateDisabled] forState:UIControlStateDisabled]; [self setTitleColor:[self titleColorForState:UIControlStateSelected] forState:UIControlStateSelected]; @@ -796,13 +771,45 @@ - (void)setEnabled:(BOOL)enabled forSegmentAtIndex:(NSUInteger)segment button.enabled = enabled; } -- (void)setHairlineColor:(UIColor *)color +- (void)setScrollOffset:(CGPoint)scrollOffset contentSize:(CGSize)contentSize { - if (self.initializing) { + self.autoAdjustSelectionIndicatorWidth = NO; + self.bouncySelectionIndicator = NO; + + CGFloat offset = 0.0; + + // Horizontal scroll + if (self.scrollOffset.x != scrollOffset.x) { + offset = scrollOffset.x/(contentSize.width/self.numberOfSegments); + } + // Vertical scroll + else if (self.scrollOffset.y != scrollOffset.y) { + offset = scrollOffset.y/(contentSize.height/self.numberOfSegments); + } + // Skip + else { return; } - self.hairline.backgroundColor = color; + CGFloat buttonWidth = roundf(self.width/self.numberOfSegments); + + CGRect indicatorRect = self.selectionIndicator.frame; + indicatorRect.origin.x = (buttonWidth * offset); + self.selectionIndicator.frame = indicatorRect; + + NSUInteger index = (NSUInteger)offset; + + if (offset == truncf(offset) && self.selectedSegmentIndex != index) { + + [self unselectAllButtons]; + [self.buttons[index] setSelected:YES]; + + _selectedSegmentIndex = index; + + [self sendActionsForControlEvents:UIControlEventValueChanged]; + } + + _scrollOffset = scrollOffset; } - (void)setAdjustsButtonTopInset:(BOOL)adjustsButtonTopInset @@ -838,8 +845,7 @@ - (void)addButtonForSegment:(NSUInteger)segment { DZNStaticButton *button = [DZNStaticButton buttonWithType:UIButtonTypeCustom]; - [button addTarget:self action:@selector(willSelectedButton:) forControlEvents:UIControlEventTouchDown]; - [button addTarget:self action:@selector(didSelectButton:) forControlEvents:UIControlEventTouchDragOutside|UIControlEventTouchDragInside|UIControlEventTouchDragEnter|UIControlEventTouchDragExit|UIControlEventTouchCancel|UIControlEventTouchUpInside|UIControlEventTouchUpOutside]; + [button addTarget:self action:@selector(selectedButton:) forControlEvents:UIControlEventTouchDown]; button.backgroundColor = [UIColor clearColor]; button.opaque = YES; @@ -921,27 +927,18 @@ - (void)configureButtonImage:(UIImage *)image forSegment:(NSUInteger)segment [self setAttributedTitle:nil forSegmentAtIndex:segment]; } -- (void)willSelectedButton:(DZNStaticButton *)sender +- (void)selectedButton:(DZNStaticButton *)sender { - if (self.selectedSegmentIndex != sender.tag) { - [self setSelectedSegmentIndex:sender.tag animated:YES]; - [self sendActionsForControlEvents:UIControlEventValueChanged]; - } - else if (!self.disableSelectedSegment) { + [self setSelectedSegmentIndex:sender.tag animated:YES]; + + if (self.selectedSegmentIndex != sender.tag || !self.disableSelectedSegment) { [self sendActionsForControlEvents:UIControlEventValueChanged]; } } -- (void)didSelectButton:(DZNStaticButton *)sender -{ - sender.highlighted = NO; - sender.selected = YES; -} - - (void)unselectAllButtons { [self.buttons setValue:@NO forKey:@"selected"]; - [self.buttons setValue:@NO forKey:@"highlighted"]; } - (void)enableAllButtonsInteraction:(BOOL)enable From c24c5d590605a5a6cb78813f0d6dfda2a0d6377a Mon Sep 17 00:00:00 2001 From: Ignacio Romero Zurbuchen Date: Wed, 10 Feb 2016 12:28:56 -0800 Subject: [PATCH 7/8] Removes test implementation from sample project --- Examples/Sample/TableView Example/TableViewController.m | 3 --- 1 file changed, 3 deletions(-) diff --git a/Examples/Sample/TableView Example/TableViewController.m b/Examples/Sample/TableView Example/TableViewController.m index 9abf840..c88d856 100644 --- a/Examples/Sample/TableView Example/TableViewController.m +++ b/Examples/Sample/TableView Example/TableViewController.m @@ -161,9 +161,6 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath - (void)addSegment:(id)sender { - [self.control setSelectedSegmentIndex:DZNSegmentedControlNoSegment animated:YES]; - return; - NSUInteger newSegment = self.control.numberOfSegments; #if DEBUG_IMAGE From 70a4871e1b2977fc24136733a37022e07ee3941f Mon Sep 17 00:00:00 2001 From: Ignacio Romero Zurbuchen Date: Wed, 10 Feb 2016 12:41:07 -0800 Subject: [PATCH 8/8] Fixes issue causing not to forward actions to targets --- Source/DZNSegmentedControl.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/DZNSegmentedControl.m b/Source/DZNSegmentedControl.m index b602c74..7fc1767 100644 --- a/Source/DZNSegmentedControl.m +++ b/Source/DZNSegmentedControl.m @@ -929,9 +929,11 @@ - (void)configureButtonImage:(UIImage *)image forSegment:(NSUInteger)segment - (void)selectedButton:(DZNStaticButton *)sender { + NSInteger idx = self.selectedSegmentIndex; + [self setSelectedSegmentIndex:sender.tag animated:YES]; - if (self.selectedSegmentIndex != sender.tag || !self.disableSelectedSegment) { + if (idx != sender.tag || !self.disableSelectedSegment) { [self sendActionsForControlEvents:UIControlEventValueChanged]; } }