| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- //
- // AKSegmentedControl.m
- //
- // Copyright (c) 2013 Ali Karagoz (http://alikaragoz.net)
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- #import "AKSegmentedControl.h"
- // Default separator width.
- static CGFloat const kAKButtonSeparatorWidth = 1.0;
- @interface AKSegmentedControl ()
- @property (nonatomic, strong) NSMutableArray *separatorsArray;
- @property (nonatomic, strong) UIImageView *backgroundImageView;
- // Init
- - (void)commonInitializer;
- @end
- @implementation AKSegmentedControl
- #pragma mark - Init and Dealloc
- - (id)initWithFrame:(CGRect)frame {
- self = [super initWithFrame:frame];
- if (!self) return nil;
-
- [self commonInitializer];
-
- return self;
- }
- - (id)initWithCoder:(NSCoder *)aDecoder {
- self = [super initWithCoder:aDecoder];
- if (!self) return nil;
-
- [self commonInitializer];
-
- return self;
- }
- - (void)commonInitializer {
- _separatorsArray = [NSMutableArray array];
- self.selectedIndexes = [NSIndexSet indexSet];
- self.contentEdgeInsets = UIEdgeInsetsZero;
- self.segmentedControlMode = AKSegmentedControlModeSticky;
- self.buttonsArray = [[NSArray alloc] init];
-
- [self addSubview:self.backgroundImageView];
- }
- #pragma mark - Layout
- - (void)layoutSubviews {
- [super layoutSubviews];
- CGRect contentRect = UIEdgeInsetsInsetRect(self.bounds, _contentEdgeInsets);
-
- NSUInteger buttonsCount = _buttonsArray.count;
- NSUInteger separtorsNumber = buttonsCount - 1;
- CGFloat separatorWidth = (_separatorImage != nil) ? _separatorImage.size.width : kAKButtonSeparatorWidth;
- CGFloat buttonWidth = floorf((CGRectGetWidth(contentRect) - (separtorsNumber * separatorWidth)) / buttonsCount);
- CGFloat buttonHeight = CGRectGetHeight(contentRect);
- CGSize buttonSize = CGSizeMake(buttonWidth, buttonHeight);
-
- __block CGFloat offsetX = CGRectGetMinX(contentRect);
- __block CGFloat offsetY = CGRectGetMinY(contentRect);
- __block CGFloat spaceLeft = CGRectGetWidth(contentRect) - (buttonsCount * buttonSize.width) - (separtorsNumber * separatorWidth);
- __block CGFloat dButtonWidth = 0;
- __block NSUInteger increment = 0;
-
- [_buttonsArray enumerateObjectsUsingBlock:^(UIButton *button, NSUInteger idx, BOOL *stop) {
- if (![button isKindOfClass:UIButton.class]) {
- return;
- }
-
- dButtonWidth = buttonSize.width;
-
- if (spaceLeft != 0) {
- dButtonWidth++;
- spaceLeft--;
- }
-
- if (increment != 0) {
- offsetX += separatorWidth;
- }
-
- button.frame = CGRectMake(offsetX, offsetY, dButtonWidth, buttonSize.height);
-
- if (increment < separtorsNumber) {
- UIImageView *separatorImageView = _separatorsArray[increment];
- [separatorImageView setFrame:CGRectMake(CGRectGetMaxX(button.frame),
- offsetY,
- separatorWidth,
- CGRectGetHeight(self.bounds) - _contentEdgeInsets.top - _contentEdgeInsets.bottom)];
- }
-
- increment++;
- offsetX = CGRectGetMaxX(button.frame);
- }];
-
- [_backgroundImageView setFrame:self.bounds];
- }
- #pragma mark - Button Actions
- - (void)segmentButtonPressed:(id)sender {
- UIButton *button = (UIButton *)sender;
-
- if (![button isKindOfClass:UIButton.class]) {
- return;
- }
-
- NSUInteger selectedIndex = button.tag;
- NSIndexSet *set = _selectedIndexes;
-
- if (_segmentedControlMode == AKSegmentedControlModeMultipleSelectionable) {
- NSMutableIndexSet *mutableSet = [set mutableCopy];
- if ([_selectedIndexes containsIndex:selectedIndex]) {
- [mutableSet removeIndex:selectedIndex];
- }
-
- else {
- [mutableSet addIndex:selectedIndex];
- }
-
- [self setSelectedIndexes:[mutableSet copy]];
- }
-
- else {
- [self setSelectedIndex:selectedIndex];
- }
-
- BOOL willSendAction = (![_selectedIndexes isEqualToIndexSet:set] || _segmentedControlMode == AKSegmentedControlModeButton);
-
- if (willSendAction) {
- [self sendActionsForControlEvents:UIControlEventValueChanged];
- }
-
- }
- #pragma mark - Setters
- - (void)setBackgroundImage:(UIImage *)backgroundImage {
- _backgroundImage = backgroundImage;
- [_backgroundImageView setImage:_backgroundImage];
- }
- - (void)setButtonsArray:(NSArray *)buttonsArray {
- [_buttonsArray makeObjectsPerformSelector:@selector(removeFromSuperview)];
- [_separatorsArray removeAllObjects];
-
- _buttonsArray = buttonsArray;
-
- [_buttonsArray enumerateObjectsUsingBlock:^(UIButton *button, NSUInteger idx, BOOL *stop) {
- [self addSubview:button];
- [button addTarget:self action:@selector(segmentButtonPressed:) forControlEvents:UIControlEventTouchDown];
- [button setTag:idx];
- }];
-
- [self rebuildSeparators];
- [self updateButtons];
- }
- - (void)setSeparatorImage:(UIImage *)separatorImage {
- _separatorImage = separatorImage;
- [self rebuildSeparators];
- }
- - (void)setSegmentedControlMode:(AKSegmentedControlMode)segmentedControlMode {
- _segmentedControlMode = segmentedControlMode;
- [self updateButtons];
- }
- - (void)setSelectedIndex:(NSUInteger)index {
- _selectedIndexes = [NSIndexSet indexSetWithIndex:index];
- [self updateButtons];
- }
- - (void)setSelectedIndexes:(NSIndexSet *)indexSet byExpandingSelection:(BOOL)expandSelection {
-
- if (_segmentedControlMode != AKSegmentedControlModeMultipleSelectionable) {
- return;
- }
-
- if (!expandSelection) {
- _selectedIndexes = [NSIndexSet indexSet];
- }
-
- NSMutableIndexSet *mutableIndexSet = [_selectedIndexes mutableCopy];
- [mutableIndexSet addIndexes:indexSet];
- [self setSelectedIndexes:mutableIndexSet];
- }
- - (void)setSelectedIndexes:(NSIndexSet *)selectedIndexes {
- _selectedIndexes = [selectedIndexes copy];
- [self updateButtons];
- }
- #pragma mark - Rearranging
- - (void)rebuildSeparators {
- [_separatorsArray makeObjectsPerformSelector:@selector(removeFromSuperview)];
-
- NSUInteger separatorsNumber = [_buttonsArray count] - 1;
-
- [_separatorsArray removeAllObjects];
- [_buttonsArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
- if (idx < separatorsNumber) {
- UIImageView *separatorImageView = [[UIImageView alloc] initWithImage:_separatorImage];
- [self addSubview:separatorImageView];
- [_separatorsArray addObject:separatorImageView];
- }
- }];
- }
- - (UIImageView *)backgroundImageView {
- if (_backgroundImageView == nil) {
- _backgroundImageView = [[UIImageView alloc] initWithFrame:self.bounds];
- [_backgroundImageView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
- }
-
- return _backgroundImageView;
- }
- - (void)updateButtons {
-
- if ([_buttonsArray count] == 0) {
- return;
- }
-
- [_buttonsArray makeObjectsPerformSelector:@selector(setSelected:) withObject:nil];
-
- [_selectedIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
-
- if (_segmentedControlMode != AKSegmentedControlModeButton) {
- if (idx >= [_buttonsArray count]) return;
-
- UIButton *button = _buttonsArray[idx];
- button.selected = YES;
- }
- }];
- }
- -(void)initButtonWithTitleandImage:(NSArray *)buttonTitleandImage{
-
- UIImage *backgroundImage = [[UIImage imageNamed:@"segmented-bg"] resizableImageWithCapInsets:UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0)];
- [self setBackgroundImage:backgroundImage];
- [self setContentEdgeInsets:UIEdgeInsetsMake(2.0, 2.0, 3.0, 2.0)];
- [self setAutoresizingMask:UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleBottomMargin];
-
- [self setSeparatorImage:[UIImage imageNamed:@"segmented-separator"]];
-
- NSMutableArray *buttonArr = [[NSMutableArray alloc]init];
- UIImage *buttonBackgroundImagePressedLeft = [[UIImage imageNamed:@"segmented-bg-pressed-left"]
- resizableImageWithCapInsets:UIEdgeInsetsMake(0.0, 4.0, 0.0, 1.0)];
- // UIImage *buttonBackgroundImagePressedCenter = [[UIImage imageNamed:@"segmented-bg-pressed-center"]
- // resizableImageWithCapInsets:UIEdgeInsetsMake(0.0, 4.0, 0.0, 1.0)];
- // UIImage *buttonBackgroundImagePressedRight = [[UIImage imageNamed:@"segmented-bg-pressed-right"]
- // resizableImageWithCapInsets:UIEdgeInsetsMake(0.0, 1.0, 0.0, 4.0)];
-
- for (NSDictionary *dict in buttonTitleandImage) {
- UIButton *button = [[UIButton alloc] init];
- UIImage *button1ImageNormal = [UIImage imageNamed:dict[@"image"]];
- [button setImageEdgeInsets:UIEdgeInsetsMake(0.0, 0.0, 0.0, 5.0)];
- [button setBackgroundImage:buttonBackgroundImagePressedLeft forState:UIControlStateHighlighted];
- [button setBackgroundImage:buttonBackgroundImagePressedLeft forState:UIControlStateSelected];
- [button setBackgroundImage:buttonBackgroundImagePressedLeft forState:(UIControlStateHighlighted|UIControlStateSelected)];
- button.titleLabel.font = [UIFont fontWithName:dict[@"font"] size:14];
- [button setImage:button1ImageNormal forState:UIControlStateNormal];
- [button setImage:button1ImageNormal forState:UIControlStateSelected];
- [button setImage:button1ImageNormal forState:UIControlStateHighlighted];
- [button setImage:button1ImageNormal forState:(UIControlStateHighlighted|UIControlStateSelected)];
- [button setTitle:dict[@"title"] forState:normal];
- [button setTitleColor:[UIColor colorWithRed:((float)38/255) green:(float)82/255 blue:((float)67/255) alpha:1] forState:normal];
- [buttonArr addObject:button];
- }
- self.buttonsArray = buttonArr;
- }
- @end
|