最近有个需求需要用到一个左右切换的控件,就像下图一样:
最先想到的是自定义一个view,然后在上面加手势活着重写- (void)touchesBegan:(NSSet )touches withEvent:(UIEvent )event,通过手势活着点击的位置:
UITouch * touch = touches.anyObject;
CGPoint location = [touch locationInView:theView];
然后判断点击位置是在左边还是在右边,作不同处理。当然这时左右两边的半圆就要注意用x,y联合判断,基本数学问题,不赘述。这样的好处是用一个view,设置cornerRadius就可以实现图像效果,左右颜色的话可以通过设置现成的背景,点击替换背景。
可是总觉得不太舒服,于是想用两个button拼成这么一个自定义的控件。问题来了,用2个button设置了cornerRadius之后就会变成这个样子:
中间拼不起来。于是我想到能不能做一个只有2个角是圆角的按钮呢?问题是抛出来了,可是怎么做呢?还是去看看国外大牛怎么做的,通过google找到了解决方案。看这里,我是直接看了其中Stuart的回答,然后用在我这发现非常完美。
// Create the path (with only the top-left corner rounded)
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds
byRoundingCorners:UIRectCornerTopLeft | UIRectCornerBottomLeft
cornerRadii:CGSizeMake(10.0, 10.0)];
// Create the shape layer and set its path
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = imageView.bounds;
maskLayer.path = maskPath.CGPath;
// Set the newly created shape layer as the mask for the image view's layer
imageView.layer.mask = maskLayer;
他的思路是先画沿着view的rect画一条带圆角的贝塞尔曲线,当然如果不用+ (UIBezierPath *)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii方法的自己也可画,也不麻烦,了解基本的Quartz 2D就可以。在这个方法中提供了corners参数:
typedef NS_OPTIONS(NSUInteger, UIRectCorner) {
UIRectCornerTopLeft = 1 << 0,
UIRectCornerTopRight = 1 << 1,
UIRectCornerBottomLeft = 1 << 2,
UIRectCornerBottomRight = 1 << 3,
UIRectCornerAllCorners = ~0UL
};
这样我们就可以自己选择哪几个角需要圆角,这里我的两个button分别需要左上左下和右上右下,用 | 链接即可。
然后创建一个CAShapeLayer对象
The shape layer draws a cubic Bezier spline in its coordinate space.
CAShapeLayer 继承自CALayer,在其坐标空间内沿给定路径画线作为边界。最后将其设为你所用到的view的mask。
用上述方法我就可以做两个button,一个只有左边两个角是圆角,另一个只有右边两个是圆角,将它们拼在一起再加上相应的逻辑就可以完成我们所需的自定义控件。
个人觉得第二种实现方法比点击判断位置要好看。