2023-04-28 iOS 自定义SegmentControl

2023-04-27  本文已影响0人  nickNic
#import <UIKit/UIKit.h>


@protocol ZJFontSegmentControlDelegate <NSObject>
- (CGFloat)segmentControlTitleSizeForIndex:(NSInteger)index;
@end

@interface ZJFontSegmentControl : UIView

@property (nonatomic, assign) NSInteger selectedSegmentIndex;
@property (nonatomic, strong) UIColor *selectedBgColor;
@property (nonatomic, strong) UIColor *backBgColor;
@property (nonatomic, strong) UIColor *selectedTextColor;
@property (nonatomic, strong) UIColor *normalTextColor;
@property (nonatomic, copy)   void (^selectIndex)(NSInteger index);
@property (nonatomic, weak)   id<ZJFontSegmentControlDelegate> delegate;

- (instancetype)initWithFrame:(CGRect)frame Items:(NSArray<NSString *> *)items;

@end
#import "ZJFontSegmentControl.h"
#import "UIView+Extension.h"


@interface ZJNoHighlightButton : UIButton

@end
@implementation ZJNoHighlightButton
//重写该方法可以去除长按按钮时出现的高亮效果
- (void)setHighlighted:(BOOL)highlighted
{
  
}
@end

@interface ZJFontSegmentControl()

@property (nonatomic, strong) NSArray<NSString *> *items;
@property (nonatomic, strong) NSMutableArray<UIButton*> *segments;
@property (nonatomic, strong) UIView *segmentBackView;
@property (nonatomic, strong) UIButton *segSliderBtn;
@property (nonatomic, strong) UIButton *beforeBtn;
@property (nonatomic, assign) NSInteger defaultSegment;
@property (nonatomic, assign) BOOL canDrag;

@end
@implementation ZJFontSegmentControl


- (instancetype)initWithFrame:(CGRect)frame Items:(NSArray<NSString *> *)items {
  self = [super initWithFrame:frame];
  if (self) {
      self.userInteractionEnabled = true;
      self.backgroundColor = [UIColor clearColor];
      self.items = items;
      self.canDrag = true;
      self.selectedBgColor = [UIColor redColor];
      self.backBgColor = [UIColor yellowColor];
      self.selectedTextColor = [UIColor blueColor];
      self.normalTextColor = [UIColor greenColor];
  }
  return self;
}
#pragma mark-- set
- (void)setSelectedSegmentIndex:(NSInteger)selectedSegmentIndex {
  _defaultSegment = selectedSegmentIndex;
  [self setupUI];
}

- (void)setSelectedBgColor:(UIColor *)selectedBgColor {
  self.segSliderBtn.backgroundColor = selectedBgColor;
}

- (void)setBackBgColor:(UIColor *)backBgColor {
  self.segmentBackView.backgroundColor = backBgColor;
}

- (void)setSelectedTextColor:(UIColor *)selectedTextColor {
  _selectedTextColor = selectedTextColor;
}

- (void)setNormalTextColor:(UIColor *)normalTextColor{
  _normalTextColor = normalTextColor;
}

- (void)restSegmentsSelected {
  if (self.beforeBtn != self.segments[self.defaultSegment]) {
      [self.segments[self.defaultSegment] setSelected:true];
      [self.beforeBtn setSelected:false];
  }
  self.beforeBtn = self.segments[self.defaultSegment];
}

#pragma mark-- UI
- (void)setupUI {

  if (self.segments == nil) {
      //添加滑动手势
      UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGesture:)];
      [self addGestureRecognizer:panGesture];
      
      self.segments = [NSMutableArray array];
      CGFloat btnWidth = self.frame.size.width / self.items.count;
      CGFloat btnHeight = self.frame.size.height;
      //创建tab
      for (int i = 0; i < self.items.count; i++) {
          ZJNoHighlightButton *button = [ZJNoHighlightButton buttonWithType:UIButtonTypeCustom];
          button.frame = CGRectMake(btnWidth * i, 0, btnWidth, btnHeight);
          [button setTitle:[self.items objectAtIndex:i] forState:UIControlStateNormal];
          [button setTitleColor:self.normalTextColor forState:UIControlStateNormal];
          [button setTitleColor:self.selectedTextColor forState:UIControlStateSelected];
          button.titleLabel.font = [UIFont systemFontOfSize:[self sizeForIndex:i]];
          button.layer.cornerRadius = self.frame.size.height / 2;
          button.layer.masksToBounds = true;
          button.userInteractionEnabled = true;
          button.tag = i;
          [button addTarget:self action:@selector(tabAction:) forControlEvents:UIControlEventTouchUpInside];
          button.backgroundColor = [UIColor clearColor];
          [self.segmentBackView addSubview:button];
          [self.segments addObject:button];
      }
  }
  
  if (self.defaultSegment < self.segments.count) {
      self.segSliderBtn.frame = self.segments[self.defaultSegment].frame;
      [self restSegmentsSelected];
  } else {
      NSLog(@"选定段索引超出数组范围");
  }
}

- (UIView *)segmentBackView {
  if (!_segmentBackView) {
      UIView *segmentBackView = [[UIView alloc]initWithFrame:self.bounds];
      segmentBackView.backgroundColor = self.backBgColor;
      segmentBackView.layer.cornerRadius = self.frame.size.height / 2;
      segmentBackView.layer.masksToBounds = true;
      [self addSubview:segmentBackView];
      _segmentBackView = segmentBackView;
  }
  return _segmentBackView;
}

- (UIButton *)segSliderBtn {
  if (!_segSliderBtn) {
      UIButton *segSliderBtn = [UIButton buttonWithType:UIButtonTypeCustom];
      segSliderBtn.layer.cornerRadius = self.frame.size.height / 2;
      segSliderBtn.layer.masksToBounds = true;
      segSliderBtn.backgroundColor = self.selectedBgColor;
      [segSliderBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
      [self.segmentBackView addSubview:segSliderBtn];
      self.segSliderBtn = segSliderBtn;
  }
  return _segSliderBtn;
}

#pragma mark-- Actions
- (void)panGesture:(UIPanGestureRecognizer *)geture {
  @weakify(self);
  CGPoint pointA = [geture locationInView:self.segmentBackView];
  if (geture.state == UIGestureRecognizerStateBegan) {
      if (!CGRectContainsPoint(self.segSliderBtn.frame, pointA)) {
          self.canDrag = false;
          return;
      }
  }
  
  if (geture.state == UIGestureRecognizerStateChanged) {
      if (self.canDrag == false) {
          return;
      }
      //改变滑动button的位置
      for (int i = 0; i < self.items.count; i++ ) {
          UIButton *button = self.segments[i];
          if (pointA.x > button.minX && pointA.x < button.maxX) {
              [UIView animateWithDuration:0.1 animations:^{
                  @strongify(self);
                  self.segSliderBtn.center = self.segments[i].center;
                  self.defaultSegment = i;
                  [self restSegmentsSelected];
              }];
              break;
          }
      }
  }
  
  [geture setTranslation:CGPointZero inView:self.segmentBackView];
  
  if (geture.state == UIGestureRecognizerStateEnded ) {
      self.canDrag = true;
      if (self.selectIndex) {
          self.selectIndex(self.defaultSegment);
      }
  }
}

- (void)tabAction:(UIButton *)sender {
  @weakify(self);
  if (sender.tag == self.defaultSegment) {
      return;
  }
  
  UIButton *button = self.segments[sender.tag];
  [UIView animateWithDuration:0.2 animations:^{
      @strongify(self);
      self.segSliderBtn.center = button.center;
  }];
  self.defaultSegment = sender.tag;
  [self restSegmentsSelected];

  if (self.selectIndex) {
      self.selectIndex(self.defaultSegment);
  }
}

- (CGFloat)sizeForIndex:(NSInteger)index {
  if ([self.delegate respondsToSelector:@selector(segmentControlTitleSizeForIndex:)]) {
      return [self.delegate segmentControlTitleSizeForIndex:index];
  }
  return 15.0;
}

@end

下面为等边等距
#define Width_Space      10.0f      // 2个按钮之间的横间距
#pragma mark-- UI
- (void)setupUI {

  if (self.segments == nil) {
      //添加滑动手势
      UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGesture:)];
      [self addGestureRecognizer:panGesture];
      
      self.segments = [NSMutableArray array];
      CGFloat btnWidth = ((self.frame.size.width  - Width_Space  * (self.items.count + 1 )) / self.items.count);
      CGFloat btnHeight = self.frame.size.height;
      //创建tab
      for (int i = 0; i < self.items.count; i++) {
          ZJNoHighlightButton *button = [ZJNoHighlightButton buttonWithType:UIButtonTypeCustom];
          button.frame = CGRectMake(i * (btnWidth + Width_Space) + Width_Space, 0, btnWidth, btnHeight);
          [button setTitle:[self.items objectAtIndex:i] forState:UIControlStateNormal];
          [button setTitleColor:self.normalTextColor forState:UIControlStateNormal];
          [button setTitleColor:self.selectedTextColor forState:UIControlStateSelected];
          button.titleLabel.font = [UIFont systemFontOfSize:[self sizeForIndex:i]];
          button.layer.cornerRadius = self.frame.size.height / 2;
          button.layer.masksToBounds = true;
          button.userInteractionEnabled = true;
          button.tag = i;
          [button addTarget:self action:@selector(tabAction:) forControlEvents:UIControlEventTouchUpInside];
          button.backgroundColor = [UIColor clearColor];
          [self.segmentBtnBackView addSubview:button];
          [self.segments addObject:button];
      }
  }
  
  if (self.defaultSegment < self.segments.count) {
      self.segSliderBtn.frame = self.segments[self.defaultSegment].frame;
      [self restSegmentsSelected];
  } else {
      NSLog(@"选定段索引超出数组范围");
  }
}

上一篇 下一篇

猜你喜欢

热点阅读