diff --git a/HMSegmentedControl/HMSegmentedControl.h b/HMSegmentedControl/HMSegmentedControl.h index ab8a34ec..aede2b80 100755 --- a/HMSegmentedControl/HMSegmentedControl.h +++ b/HMSegmentedControl/HMSegmentedControl.h @@ -250,6 +250,24 @@ typedef NS_ENUM(NSInteger, HMSegmentedControlImagePosition) { @property (nonatomic, readwrite) UIEdgeInsets enlargeEdgeInset; +/** + Inset left and right edges of between segments. + + Default is UIEdgeInsetsMake(0, 0, 0, 0) + */ +@property (nonatomic, readwrite) UIEdgeInsets segmentMarginInset; +/** + Color for the title background + */ +@property (nonatomic, strong) UIColor *titleBackgroundColor; +/** + Radius for the title background:0~1.0 + */ +@property (nonatomic) CGFloat titleBackgroundRadius; +/** + Height for the segment item + */ +@property (nonatomic) CGFloat segmentHeight; /** Default is YES. Set to NO to disable animation during user selection. */ diff --git a/HMSegmentedControl/HMSegmentedControl.m b/HMSegmentedControl/HMSegmentedControl.m index 51e26e4e..a6dabbbf 100755 --- a/HMSegmentedControl/HMSegmentedControl.m +++ b/HMSegmentedControl/HMSegmentedControl.m @@ -117,17 +117,17 @@ - (instancetype)initWithSectionImages:(NSArray *)sectionImages sectio } - (instancetype)initWithSectionImages:(NSArray *)sectionImages sectionSelectedImages:(NSArray *)sectionSelectedImages titlesForSections:(NSArray *)sectiontitles { - self = [super initWithFrame:CGRectZero]; + self = [super initWithFrame:CGRectZero]; if (self) { [self commonInit]; - - if (sectionImages.count != sectiontitles.count) { - [NSException raise:NSRangeException format:@"***%s: Images bounds (%ld) Don't match Title bounds (%ld)", sel_getName(_cmd), (unsigned long)sectionImages.count, (unsigned long)sectiontitles.count]; + + if (sectionImages.count != sectiontitles.count) { + [NSException raise:NSRangeException format:@"***%s: Images bounds (%ld) Don't match Title bounds (%ld)", sel_getName(_cmd), (unsigned long)sectionImages.count, (unsigned long)sectiontitles.count]; } - + self.sectionImages = sectionImages; self.sectionSelectedImages = sectionSelectedImages; - self.sectionTitles = sectiontitles; + self.sectionTitles = sectiontitles; self.type = HMSegmentedControlTypeTextImages; } return self; @@ -207,11 +207,11 @@ - (void)setSectionImages:(NSArray *)sectionImages { } - (void)setSelectionIndicatorLocation:(HMSegmentedControlSelectionIndicatorLocation)selectionIndicatorLocation { - _selectionIndicatorLocation = selectionIndicatorLocation; - - if (selectionIndicatorLocation == HMSegmentedControlSelectionIndicatorLocationNone) { - self.selectionIndicatorHeight = 0.0f; - } + _selectionIndicatorLocation = selectionIndicatorLocation; + + if (selectionIndicatorLocation == HMSegmentedControlSelectionIndicatorLocationNone) { + self.selectionIndicatorHeight = 0.0f; + } } - (void)setSelectionIndicatorBoxOpacity:(CGFloat)selectionIndicatorBoxOpacity { @@ -313,6 +313,10 @@ - (void)drawRect:(CGRect)rect { if (self.accessibilityElements==nil) self.accessibilityElements = [NSMutableArray arrayWithCapacity:0]; + if (self.segmentWidthsArray.count == 0 && self.sectionTitles.count == 0 && self.sectionImages.count == 0) { + return; + } + if (self.type == HMSegmentedControlTypeText) { [self removeTitleBackgroundLayers]; [self.sectionTitles enumerateObjectsUsingBlock:^(id titleString, NSUInteger idx, BOOL *stop) { @@ -321,7 +325,7 @@ - (void)drawRect:(CGRect)rect { CGFloat stringHeight = 0; CGSize size = [self measureTitleAtIndex:idx]; stringWidth = size.width; - stringHeight = size.height; + stringHeight = self.segmentHeight > 0 ? self.segmentHeight:size.height; CGRect rectDiv = CGRectZero; CGRect fullRect = CGRectZero; @@ -342,7 +346,7 @@ - (void)drawRect:(CGRect)rect { for (NSNumber *width in self.segmentWidthsArray) { if (idx == i) break; - xOffset = xOffset + [width floatValue]; + xOffset = xOffset + [width floatValue] + self.segmentMarginInset.left + self.segmentMarginInset.right; i++; } @@ -363,6 +367,8 @@ - (void)drawRect:(CGRect)rect { } titleLayer.string = [self attributedTitleAtIndex:idx]; titleLayer.contentsScale = [[UIScreen mainScreen] scale]; + titleLayer.backgroundColor = self.titleBackgroundColor.CGColor; + titleLayer.cornerRadius = CGRectGetHeight(rect) * self.titleBackgroundRadius; [self.scrollView.layer addSublayer:titleLayer]; @@ -465,11 +471,11 @@ - (void)drawRect:(CGRect)rect { }]; } else if (self.type == HMSegmentedControlTypeTextImages){ [self removeTitleBackgroundLayers]; - [self.sectionImages enumerateObjectsUsingBlock:^(id iconImage, NSUInteger idx, BOOL *stop) { + [self.sectionImages enumerateObjectsUsingBlock:^(id iconImage, NSUInteger idx, BOOL *stop) { UIImage *icon = iconImage; CGFloat imageWidth = icon.size.width; CGFloat imageHeight = icon.size.height; - + CGSize stringSize = [self measureTitleAtIndex:idx]; CGFloat stringHeight = stringSize.height; CGFloat stringWidth = stringSize.width; @@ -554,7 +560,7 @@ - (void)drawRect:(CGRect)rect { } CALayer *imageLayer = [CALayer layer]; imageLayer.frame = imageRect; - + if (self.selectedSegmentIndex == idx) { if (self.sectionSelectedImages) { UIImage *highlightIcon = [self.sectionSelectedImages objectAtIndex:idx]; @@ -567,7 +573,7 @@ - (void)drawRect:(CGRect)rect { } [self.scrollView.layer addSublayer:imageLayer]; - titleLayer.contentsScale = [[UIScreen mainScreen] scale]; + titleLayer.contentsScale = [[UIScreen mainScreen] scale]; [self.scrollView.layer addSublayer:titleLayer]; if ([self.accessibilityElements count]<=idx) { @@ -594,10 +600,10 @@ - (void)drawRect:(CGRect)rect { else element.accessibilityTraits = UIAccessibilityTraitButton; } - + [self addBackgroundAndBorderLayerWithRect:imageRect]; }]; - } + } // Add the selection indicators if (self.selectedSegmentIndex != HMSegmentedControlNoSegment) { @@ -714,11 +720,11 @@ - (CGRect)frameForSelectionIndicator { CGFloat imageWidth = sectionImage.size.width; sectionWidth = imageWidth; } else if (self.type == HMSegmentedControlTypeTextImages) { - CGFloat stringWidth = [self measureTitleAtIndex:self.selectedSegmentIndex].width; - UIImage *sectionImage = [self.sectionImages objectAtIndex:self.selectedSegmentIndex]; - CGFloat imageWidth = sectionImage.size.width; + CGFloat stringWidth = [self measureTitleAtIndex:self.selectedSegmentIndex].width; + UIImage *sectionImage = [self.sectionImages objectAtIndex:self.selectedSegmentIndex]; + CGFloat imageWidth = sectionImage.size.width; sectionWidth = MAX(stringWidth, imageWidth); - } + } if (self.selectionStyle == HMSegmentedControlSelectionStyleArrow) { CGFloat widthToEndOfSelectedSegment = (self.segmentWidth * self.selectedSegmentIndex) + self.segmentWidth; @@ -767,7 +773,7 @@ - (CGRect)frameForFillerSelectionIndicator { if (self.selectedSegmentIndex == i) { break; } - selectedSegmentOffset = selectedSegmentOffset + [width floatValue]; + selectedSegmentOffset = selectedSegmentOffset + [width floatValue] + self.segmentMarginInset.left + self.segmentMarginInset.right; i++; } @@ -856,7 +862,7 @@ - (void)updateSegmentsRects { } self.scrollView.scrollEnabled = self.isUserDraggable; - self.scrollView.contentSize = CGSizeMake([self totalSegmentedControlWidth], self.frame.size.height); + self.scrollView.contentSize = CGSizeMake([self totalSegmentedControlWidth] + (self.segmentMarginInset.left + self.segmentMarginInset.right)*[self sectionCount], self.frame.size.height); } - (NSUInteger)sectionCount { @@ -899,12 +905,18 @@ - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { // To know which segment the user touched, we need to loop over the widths and substract it from the x position. CGFloat widthLeft = (touchLocation.x + self.scrollView.contentOffset.x); for (NSNumber *width in self.segmentWidthsArray) { - widthLeft = widthLeft - [width floatValue]; + CGFloat fullWidth = (self.segmentMarginInset.left + self.segmentMarginInset.right + [width floatValue]); + if(widthLeft < self.segmentMarginInset.left || + (widthLeft > self.segmentMarginInset.left + [width floatValue] && widthLeft < fullWidth)) { + segment = self.selectedSegmentIndex; + break; + } + + widthLeft = widthLeft - fullWidth ; // When we don't have any width left to substract, we have the segment index. if (widthLeft <= 0) break; - segment++; } } @@ -961,12 +973,14 @@ - (void)scrollTo:(NSUInteger)index animated:(BOOL)animated { i++; } - rectForSelectedIndex = CGRectMake(offsetter, - 0, - [[self.segmentWidthsArray objectAtIndex:index] floatValue], - self.frame.size.height); - - selectedSegmentOffset = (CGRectGetWidth(self.frame) / 2) - ([[self.segmentWidthsArray objectAtIndex:index] floatValue] / 2); + if (self.segmentWidthsArray.count > index) { + rectForSelectedIndex = CGRectMake(offsetter, + 0, + [[self.segmentWidthsArray objectAtIndex:index] floatValue], + self.frame.size.height); + + selectedSegmentOffset = (CGRectGetWidth(self.frame) / 2) - ([[self.segmentWidthsArray objectAtIndex:index] floatValue] / 2); + } } diff --git a/HMSegmentedControlExample/AppDelegate.m b/HMSegmentedControlExample/AppDelegate.m index f6a43f20..023d6ac4 100644 --- a/HMSegmentedControlExample/AppDelegate.m +++ b/HMSegmentedControlExample/AppDelegate.m @@ -14,7 +14,7 @@ @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - self.viewController = [[ExampleViewController alloc] init]; + self.viewController = [[ViewController alloc] init]; self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; return YES; diff --git a/HMSegmentedControlExample/ViewController.m b/HMSegmentedControlExample/ViewController.m index faab2f72..e6590ce4 100644 --- a/HMSegmentedControlExample/ViewController.m +++ b/HMSegmentedControlExample/ViewController.m @@ -29,10 +29,30 @@ - (void)viewDidLoad { // Minimum code required to use the segmented control with the default styling. HMSegmentedControl *segmentedControl = [[HMSegmentedControl alloc] initWithSectionTitles:@[@"Trending", @"News", @"Library"]]; segmentedControl.frame = CGRectMake(0, 60, viewWidth, 40); - segmentedControl.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth; +// segmentedControl.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth; + segmentedControl.type = HMSegmentedControlTypeText; + segmentedControl.segmentEdgeInset = UIEdgeInsetsMake(0, 16, 0, 16); + segmentedControl.segmentWidthStyle = HMSegmentedControlSegmentWidthStyleDynamic; + segmentedControl.borderType = HMSegmentedControlBorderTypeNone; + segmentedControl.selectionIndicatorLocation = HMSegmentedControlSelectionIndicatorLocationNone; + segmentedControl.selectionStyle = HMSegmentedControlSelectionStyleBox;; + segmentedControl.selectionIndicatorBoxColor = [UIColor colorWithRed:0.882 green:0 blue:1 alpha:1]; [segmentedControl addTarget:self action:@selector(segmentedControlChangedValue:) forControlEvents:UIControlEventValueChanged]; + segmentedControl.titleBackgroundColor = [[UIColor yellowColor] colorWithAlphaComponent:0.3]; + segmentedControl.titleBackgroundRadius = 0.5; + segmentedControl.segmentMarginInset = UIEdgeInsetsMake(0, 0, 0, 8); + segmentedControl.segmentHeight = 40; + [segmentedControl setTitleFormatter:^NSAttributedString * _Nonnull(HMSegmentedControl * _Nonnull segmentedControl, NSString * _Nonnull title, NSUInteger index, BOOL selected) { + return [[NSAttributedString alloc] initWithString:title attributes:@{ + NSFontAttributeName: [UIFont systemFontOfSize:14], + NSForegroundColorAttributeName: [UIColor purpleColor], + NSBaselineOffsetAttributeName:@(-10) + }]; + }]; [self.view addSubview:segmentedControl]; + CALayer *layer = [segmentedControl valueForKey:@"selectionIndicatorBoxLayer"]; + layer.cornerRadius = 20; // Segmented control with scrolling HMSegmentedControl *segmentedControl1 = [[HMSegmentedControl alloc] initWithSectionTitles:@[@"One", @"Two", @"Three", @"Four", @"Five", @"Six", @"Seven", @"Eight"]]; @@ -154,11 +174,11 @@ - (void)setApperanceForLabel:(UILabel *)label { } - (void)segmentedControlChangedValue:(HMSegmentedControl *)segmentedControl { - NSLog(@"Selected index %tu (via UIControlEventValueChanged)", segmentedControl.selectedSegmentIndex); + NSLog(@"Selected index %tu (via UIControlEventValueChanged)", segmentedControl.selectedSegmentIndex); } - (void)uisegmentedControlChangedValue:(UISegmentedControl *)segmentedControl { - NSLog(@"Selected index %tu", segmentedControl.selectedSegmentIndex); + NSLog(@"Selected index %tu", segmentedControl.selectedSegmentIndex); } #pragma mark - UIScrollViewDelegate