IOS5.0+,简单的IOS7扁平风格分栏按钮FlatSegmentedControl

最终效果图:

项目中多处用到SegmentedControl,系统自带控件在不同IOS系统中风格不一样。在code4app上找到一个PPFlatSegmentedControl能实现很不错的效果,但是由于用到了NSAttributedString等IOS6.0才支持的方法,不能兼容5.0。想了下其实实现带两个按钮的分栏控件还是很简单的,干脆自己写一个吧。

思路:

1.初始化时需要用户传入左右按钮的Title,以及控件frame。

2.界面实现上继承自UIView,重写drawRect方法:1.画整个控件背景;2.画选中按钮背景;3.画按钮Title。

3.加Tap手势,点击时判断点击位置,是位于左按钮还是右按钮来回调delegate中方法。

4.为了用户交互更好,希望在点击但还没有释放时,给选中按钮加一层半透明的遮罩。需要重写touchBegan、touchEnded和touchCancelled方法。

代码如下:

//
//  FlatSegmentedControl.h
//  TestDemo
//
//  Created by differ on 14-4-25.
//  Copyright (c) 2014年 xiayun. All rights reserved.
//

#import <UIKit/UIKit.h>

typedef enum {
    LeftButtonSelected = 0,
    RightButtonSelected
} SelectedButtonSide;

@protocol FlatSegmentedControlDelegate <NSObject>

- (void)buttonPressed:(SelectedButtonSide)selectedSide;

@end

@interface FlatSegmentedControl : UIView
{
@private
    NSString *_leftTitle;
    NSString *_rightTitle;
    
    SelectedButtonSide _selectedSide;
    BOOL _isTouching;
    SelectedButtonSide _touchingSide;
}

- (id)initWithFrame:(CGRect)frame leftTitle:(NSString *)leftTitle rightTitle:(NSString *)rightTitle;

@property(nonatomic,assign) id<FlatSegmentedControlDelegate> delegate;

@end

//
//  FlatSegmentedControl.m
//  TestDemo
//
//  Created by differ on 14-4-25.
//  Copyright (c) 2014年 xiayun. All rights reserved.
//

#import "FlatSegmentedControl.h"


@implementation FlatSegmentedControl

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        _selectedSide = LeftButtonSelected;
    }
    return self;
}

- (id)initWithFrame:(CGRect)frame leftTitle:(NSString *)leftTitle rightTitle:(NSString *)rightTitle
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        _selectedSide = LeftButtonSelected;
        _leftTitle = leftTitle;
        _rightTitle = rightTitle;
        
        // 加点击手势
        UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
        [self addGestureRecognizer:tapGesture];
    }
    
    return self;
}

#pragma mark - actions
- (void)handleTap:(UITapGestureRecognizer *)tapGesture
{
    CGPoint touchPoint = [tapGesture locationInView:self];
    CGRect leftRect = CGRectMake(0, 0, self.frame.size.width/2, self.frame.size.height);
    if (CGRectContainsPoint(leftRect, touchPoint)) {
        // 按左按钮
        _selectedSide = LeftButtonSelected;
        [self setNeedsDisplay];
    } else {
        // 按右按钮
        _selectedSide = RightButtonSelected;
        [self setNeedsDisplay];
        
    }
    
    if ([self.delegate respondsToSelector:@selector(buttonPressed:)]) {
        [self.delegate buttonPressed:_selectedSide];
    }
}

#pragma mark - drawing
- (void)drawRect:(CGRect)rect
{
    // 取当前画笔
    CGContextClearRect(UIGraphicsGetCurrentContext(),rect);
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    // 画背景
    CGRect rectangle = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    CGContextAddRect(context, rectangle);
    CGContextSetFillColorWithColor(context, COLOR(247, 247, 247).CGColor);
    CGContextFillPath(context);
    
    // 画圆角矩形
    CGContextSetStrokeColorWithColor(context, COLOR(57, 151, 243).CGColor);
    CGContextSetLineWidth(context, 1);
    [self CGContextAddRoundRect:context rect:CGRectMake(1, 1, self.frame.size.width-2, self.frame.size.height-2) radius:5.0f];
    
    // 填充选中按钮背景
    if (_selectedSide == LeftButtonSelected) {
        [self CGContextFillLeftHalfRoundRect:context rect:CGRectMake(1, 1, self.frame.size.width/2+1, self.frame.size.height-2) radius:5.0f isMask:NO];
    } else {
        [self CGContextFillRightHalfRoundRect:context rect:CGRectMake(self.frame.size.width/2-1, 1, self.frame.size.width/2+1, self.frame.size.height-2) radius:5.0f isMask:NO];
    }
    
    // 画触摸遮罩
    if (_isTouching && _touchingSide != _selectedSide) {
        if (_touchingSide == LeftButtonSelected) {
            [self CGContextFillLeftHalfRoundRect:context rect:CGRectMake(1, 1, self.frame.size.width/2+1, self.frame.size.height-2) radius:5.0f isMask:YES];
        } else {
            [self CGContextFillRightHalfRoundRect:context rect:CGRectMake(self.frame.size.width/2-1, 1, self.frame.size.width/2+1, self.frame.size.height-2) radius:5.0f isMask:YES];
        }
    }
    
    // 画左标题
    if (_selectedSide == LeftButtonSelected) {
        CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
    } else {
        CGContextSetFillColorWithColor(context, COLOR(57, 151, 243).CGColor);
    }
    [_leftTitle drawInRect:CGRectMake(0, (self.frame.size.height-16)/2, self.frame.size.width/2, self.frame.size.height) withFont:[UIFont systemFontOfSize:14.0f] lineBreakMode:NSLineBreakByClipping alignment:NSTextAlignmentCenter];
    
    // 画右标题
    if (_selectedSide == RightButtonSelected) {
        CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
    } else {
        CGContextSetFillColorWithColor(context, COLOR(57, 151, 243).CGColor);
    }
    [_rightTitle drawInRect:CGRectMake(self.frame.size.width/2, (self.frame.size.height-16)/2, self.frame.size.width/2, self.frame.size.height) withFont:[UIFont systemFontOfSize:14.0f] lineBreakMode:NSLineBreakByClipping alignment:NSTextAlignmentCenter];
}

// 画圆角矩形
- (void) CGContextAddRoundRect:(CGContextRef)context rect:(CGRect)rect radius:(CGFloat)radius
{
    float x1=rect.origin.x;
    float y1=rect.origin.y;
    float x2=x1+rect.size.width;
    float y2=y1;
    float x3=x2;
    float y3=y1+rect.size.height;
    float x4=x1;
    float y4=y3;
    CGContextMoveToPoint(context, x1, y1+radius);
    CGContextAddArcToPoint(context, x1, y1, x1+radius, y1, radius);
    CGContextAddArcToPoint(context, x2, y2, x2, y2+radius, radius);
    CGContextAddArcToPoint(context, x3, y3, x3-radius, y3, radius);
    CGContextAddArcToPoint(context, x4, y4, x4, y4-radius, radius);
    CGContextClosePath(context);
    
    CGContextDrawPath(context, kCGPathStroke);
}

// 填充左半边圆角矩形
- (void)CGContextFillLeftHalfRoundRect:(CGContextRef)context rect:(CGRect)rect radius:(CGFloat)radius isMask:(BOOL)isMask
{
    float x1=rect.origin.x;
    float y1=rect.origin.y;
    
    float x2=x1+rect.size.width;
    float y2=y1;
    
    float x3=x2;
    float y3=y1+rect.size.height;
    
    float x4=x1;
    float y4=y3;
    
    CGContextMoveToPoint(context, x1, y1+radius);
    CGContextAddArcToPoint(context, x1, y1, x1+radius, y1, radius);
    CGContextAddLineToPoint(context, x2, y2);
    CGContextAddLineToPoint(context, x3, y3);
    CGContextAddArcToPoint(context, x4, y4, x4, y4-radius, radius);
    CGContextClosePath(context);
    
    if (isMask) {
        CGContextSetFillColorWithColor(context, [UIColor colorWithRed:57/255.0 green:151/255.0 blue:243/255.0 alpha:.5].CGColor);
    } else {
        CGContextSetFillColorWithColor(context, COLOR(57, 151, 243).CGColor);
    }
    CGContextFillPath(context);
}

// 填充右半边圆角矩形
- (void)CGContextFillRightHalfRoundRect:(CGContextRef)context rect:(CGRect)rect radius:(CGFloat)radius isMask:(BOOL)isMask
{
    float x1=rect.origin.x;
    float y1=rect.origin.y;
    
    float x2=x1+rect.size.width;
    float y2=y1;
    
    float x3=x2;
    float y3=y1+rect.size.height;
    
    float x4=x1;
    float y4=y3;
    
    CGContextMoveToPoint(context, x1, y1);
    CGContextAddArcToPoint(context, x2, y2, x2, y2+radius, radius);
    CGContextAddArcToPoint(context, x3, y3, x3-radius, y3, radius);
    CGContextAddLineToPoint(context, x4, y4);
    CGContextClosePath(context);
    
    if (isMask) {
        CGContextSetFillColorWithColor(context, [UIColor colorWithRed:57/255.0 green:151/255.0 blue:243/255.0 alpha:.1].CGColor);
    } else {
        CGContextSetFillColorWithColor(context, COLOR(57, 151, 243).CGColor);
    }
    CGContextFillPath(context);
}

#pragma mark - Touches
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];
    
    UITouch *touch = [touches anyObject];
    CGPoint touchPoint = [touch locationInView:self];
    
    _isTouching = YES;
    CGRect leftRect = CGRectMake(0, 0, self.frame.size.width/2, self.frame.size.height);
    if (CGRectContainsPoint(leftRect, touchPoint)) {
        // 按左按钮
        _touchingSide = LeftButtonSelected;
    } else {
        // 按右按钮
        _touchingSide = RightButtonSelected;
    }
    [self setNeedsDisplay];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];
    
    _isTouching = NO;
    [self setNeedsDisplay];
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesCancelled:touches withEvent:event];
    _isTouching = NO;
    [self setNeedsDisplay];
}

@end

使用:

FlatSegmentedControl *view = [[FlatSegmentedControl alloc] initWithFrame:CGRectMake(30, 30, 170, 30) leftTitle:@"分组1" rightTitle:@"分组2"];
view.delegate = self;

因为在项目中都是显示在导航栏上,所以按钮背景,字体,字体颜色,选中背景,都直接写在代码中。如果要扩展到其他项目应用,最好把这些都抽出来做成属性。

总结,CoreGraphics绘图Api使用简单,功能强大。在某些需要性能优化的地方,如TableViewCell可以发挥奇效。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值