UIControl侧重于事件交互,最大的特点是拥有addTarget:action:forControlEvents方法
自定义控件
实现效果如果:
1.SegmentControl
#import
enum SelectionIndicatorMode {
SelectionIndicatorResozesToStringWidth = 0,
};
@interface SegmentControl : UIControl
@property (strong, nonatomic) NSArray *sectionTitles;
@property (strong, nonatomic) UIFont *font;
@property (strong, nonatomic) UIColor *textColor;
@property (strong, nonatomic) UIColor *selectionIndicatorColor;
@property (nonatomic, readwrite) CGFloat height;
@property (nonatomic, readwrite) CGFloat selectionIndicatorHeight;
@property (strong, nonatomic) UIColor *backgroundColor;
@property (assign, nonatomic) NSInteger selectedIndex;
@property (nonatomic, readwrite) UIEdgeInsets segmentEdgeInset;
@property (nonatomic, strong) CALayer *selectedSegmentLayer;
@property (nonatomic, readwrite) CGFloat segmentWidth;
@property (nonatomic, copy) void(^indexChangeBlock)(NSUInteger index);
@property (assign, nonatomic) enum SelectionIndicatorMode selectionIndicatorMode;
- (id)initWithSectionTitles:(NSArray *)sectionTitles;
@end
#import "SegmentControl.h"
@implementation SegmentControl
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self _initDefaults];
}
return self;
}
- (id) initWithSectionTitles:(NSArray *)sectionTitles {
if (self = [super initWithFrame:CGRectZero]) {
self.sectionTitles = sectionTitles;
[self _initDefaults];
}
return self;
}
- (void)setFrame:(CGRect)frame {
[super setFrame:frame];
if (self.sectionTitles) {
[self _updateSegmentRects];
}
[self setNeedsDisplay];
}
// 初始化默认值
- (void)_initDefaults {
self.font = [UIFont fontWithName:@"STHeitiSC-Light" size:18.0f];
self.textColor = [UIColor blackColor];
self.backgroundColor = [UIColor whiteColor];
self.selectionIndicatorColor = [UIColor colorWithRed:52.0f/255.0f green:181.0f/255.0f blue:229.0f/255.0f alpha:1.0f];
self.selectedIndex = 0;
self.height = 60.0f;
self.selectionIndicatorHeight = 5.0f;
self.selectionIndicatorMode = SelectionIndicatorResozesToStringWidth;
self.selectedSegmentLayer = [CALayer layer];
}
- (void)drawRect:(CGRect)rect {
[self.backgroundColor set];
UIRectFill([self bounds]);
[self.textColor set];
[self.sectionTitles enumerateObjectsUsingBlock:^(id _Nonnull titleString, NSUInteger idx, BOOL * _Nonnull stop) {
CGFloat stringHeight = [titleString sizeWithFont:self.font].height;
CGFloat y = ((self.height - self.selectionIndicatorHeight) / 2) + (self.selectionIndicatorHeight - stringHeight /2);
CGRect rect = CGRectMake(self.segmentWidth * idx, y, self.segmentWidth, stringHeight);
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
[style setLineBreakMode:NSLineBreakByClipping];
[style setAlignment:NSTextAlignmentCenter];
NSDictionary *dis = [[NSDictionary alloc] initWithObjectsAndKeys:style,NSParagraphStyleAttributeName,self.font, NSFontAttributeName, nil];
[titleString drawInRect:rect withAttributes:dis];
self.selectedSegmentLayer.frame = [self frameForSelectionIndicator];
self.selectedSegmentLayer.backgroundColor = self.selectionIndicatorColor.CGColor;
[self.layer addSublayer:self.selectedSegmentLayer];
}];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self];
if (CGRectContainsPoint(self.bounds, touchLocation)) {
NSInteger segment = touchLocation.x / self.segmentWidth;
if (segment != self.selectedIndex) {
[self setSelectedIndex:segment animated:YES];
}
}
}
- (CGRect)frameForSelectionIndicator {
CGFloat stringWidth = [[self.sectionTitles objectAtIndex:self.selectedIndex] sizeWithFont:self.font].width;
CGFloat widthTillEndOfSelectedIndex = (self.segmentWidth * self.selectedIndex) + self.segmentWidth;
CGFloat widthTillBeforeSelectedIndex = (self.segmentWidth * self.selectedIndex);
CGFloat x = ((widthTillEndOfSelectedIndex - widthTillBeforeSelectedIndex) / 2) + (widthTillBeforeSelectedIndex - stringWidth /2);
return CGRectMake(x, 0.0, stringWidth, self.selectionIndicatorHeight);
}
- (void) _updateSegmentRects {
self.segmentWidth = self.frame.size.width / self.sectionTitles.count;
self.height = self.frame.size.height;
}
- (void)setSelectedIndex:(NSInteger)selectedIndex {
[self setSelectedIndex:selectedIndex animated:NO];
}
- (void)setSelectedIndex:(NSInteger)index animated:(BOOL)animated {
_selectedIndex = index;
if (animated) {
self.selectedSegmentLayer.actions = nil;
[CATransaction begin];
[CATransaction setAnimationDuration:0.15f];
[CATransaction setCompletionBlock:^{
if (self.superview) {
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
if (self.indexChangeBlock) {
self.indexChangeBlock(index);
}
}];
self.selectedSegmentLayer.frame = [self frameForSelectionIndicator];
[CATransaction commit];
} else {
NSMutableDictionary *newsActions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"position", [NSNull null], @"bounds", nil];
self.selectedSegmentLayer.actions = newsActions;
self.selectedSegmentLayer.frame = [self frameForSelectionIndicator];
if (self.superview) {
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
if (self.indexChangeBlock) {
self.indexChangeBlock(index);
}
}
}
@end
#import "ViewController.h"
#import "SegmentControl.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
SegmentControl *segment = [[SegmentControl alloc] initWithSectionTitles:@[@"电视剧", @"娱乐", @"新闻头条"]];
[segment setFrame:CGRectMake(10, 30, 300, 60)];
[segment addTarget:self action:@selector(tab:) forControlEvents:UIControlEventValueChanged];
[segment setTextColor:[UIColor blueColor]];
[segment setSelectionIndicatorColor:[UIColor redColor]];
[segment setSelectionIndicatorHeight:3.0f];
segment.height = 30;
[self.view addSubview:segment];
}
- (void) tab:(SegmentControl *)segment {
NSLog(@"%ld", segment.selectedIndex);
}
@end