iOS 开发中经常需要用到一些控件,但是系统给的又不能完全满足开发需求.这时就需要用到自定义的控件了,我写了常用的自定义按钮,供参考,废话不多说,上代码(因篇幅问题,故代码没有全贴,只贴了部分核心,文末附有Demo 地址,内有详细注释,)
未命名.2019-08-26 18_52_37.gif
第一个:带画边框小动画的按钮,原理很简单,就是用贝塞尔曲线给按钮画个边框,再结合CABasicAnimation给个动画
self.progressLayer = [CAShapeLayer layer];
self.progressLayer.strokeColor = self.strokeColor? self.strokeColor.CGColor:[UIColor redColor].CGColor;
self.progressLayer.fillColor = [UIColor clearColor].CGColor;
self.progressLayer.lineWidth = 1;
self.progressLayer.path = self.bezierPath.CGPath;
self.animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
self.animation.delegate = self;
self.animation.fromValue = @(0);
self.animation.toValue = @(1);
self.animation.duration = 5;
[self.progressLayer addAnimation:self.animation forKey:@""];
第二种:自定义 Slider 原理也很简单,在一个View 上画一条线,然后加载一个圆形 View,在圆形 View 上添加滑动手势
-(void)pan:(UIPanGestureRecognizer *)pan{
CGPoint point = [pan translationInView:self.sliderView];
//已经滑过的线的位置
self.selectedLine.frame = CGRectMake(0, (self.frame.size.height-2)/2, self.sliderView.frame.origin.x, 2);
//返回的是相对于最原始的手指的偏移量
[pan setTranslation:CGPointZero inView:self.sliderView];
//滑块的位置
if (self.sliderView.frame.origin.x>self.frame.size.width) {
self.sliderView.frame = CGRectMake(self.frame.size.width-SLIDERFRAME, (self.frame.size.height-SLIDERFRAME)/2, SLIDERFRAME, SLIDERFRAME);
}else if (self.sliderView.frame.origin.x< 0){
self.sliderView.frame = CGRectMake(0, (self.frame.size.height-SLIDERFRAME)/2, SLIDERFRAME, SLIDERFRAME);
}else{
self.sliderView.transform = CGAffineTransformTranslate(self.sliderView.transform, point.x, 0);
}
//当滑块停止的时候 返回滑块的位置
if (pan.state == UIGestureRecognizerStateEnded) {
if (self.location) {
NSLog(@"%f",SCOPE); self.location(SCOPE*self.sliderView.frame.origin.x);
}
}
}
第三种:添加一个全屏随意拖动的按钮(视频播放小窗口功能类似),原理也是给 View 上添加手势,但是这个和 Slider 上的滑动不一样,这个需要考虑到按钮不能移出到屏幕外的情况,并且这个滑动是在全屏,不是在创建的 View 上,所以方法略有不同
//拖动手势的方法
-(void)pan:(UIPanGestureRecognizer *)pan{
//获取到的是手指移动后,在相对坐标中的偏移量
CGPoint point = [pan translationInView:pan.view];
//返回的是相对于最原始的手指的偏移量
[pan setTranslation:CGPointZero inView:self];
//获取当前view 相对的中心点
CGPoint center = CGPointMake(self.center.x+point.x, self.center.y+point.y);
//下面这段代码是为了不让控件脱出屏幕外
if (center.x-self.frame.size.width/2<0) {
center.x = self.frame.size.width/2;
}else if (center.x+self.frame.size.width/2>=SCR_WIDTH){
center.x = SCR_WIDTH-self.frame.size.width/2;
}
if (center.y-self.frame.size.height/2<0) {
center.y = self.frame.size.height/2;
}else if (center.y+self.frame.size.height/2>=SCR_HEIGHT){
center.y = SCR_HEIGHT-self.frame.size.height/2;
}
//通过 block 返回视图的中心点,在显示页面上重新设置中心点
self.location(center.x, center.y);
//此方法也可以实现随意拖动,但是是否脱出屏幕外控制不了(有大神解决了这问题,麻烦告诉一下谢谢)
// self.transform = CGAffineTransformTranslate(self.transform, point.x, point.y);
}
第四种:是一个区间滑动的滑块,这个和 Slider 一样,不过这个需要考虑两个圆形滑块的位置,不能重叠,不能交叉
//左边滑块的滑动方法
-(void)leftPan:(UIPanGestureRecognizer*)leftPan{
CGPoint point = [leftPan translationInView:self.leftView];
[leftPan setTranslation:CGPointZero inView:self.leftView];
//判断左边滑块向左不能超出线的位置 向右不能超过右边滑块的位置
if (self.leftView.frame.origin.x+self.leftView.frame.size.width>self.rightView.frame.origin.x){//向右
self.leftView.frame = CGRectMake(self.rightView.frame.origin.x-SLIDERFRAME, (self.frame.size.height-SLIDERFRAME)/2, SLIDERFRAME, SLIDERFRAME);
}else if (self.leftView.frame.origin.x<0){//向左
self.leftView.frame = CGRectMake(0, (self.frame.size.height-SLIDERFRAME)/2, SLIDERFRAME, SLIDERFRAME);
}else{//正常滑动
self.leftView.transform = CGAffineTransformTranslate(self.leftView.transform, point.x, 0);
}
//当滑块停止滑动的时候,返回区间值
if (leftPan.state == UIGestureRecognizerStateEnded) {
[self sliderStop];
}
}
//右边滑块的滑动方法
-(void)rightPan:(UIPanGestureRecognizer *)rightPan{
CGPoint point = [rightPan translationInView:rightPan.view];
[rightPan setTranslation:CGPointZero inView:rightPan.view];
//判断右边滑块向右不能超出线的位置,向左不能超过左边滑块的位置
if (self.rightView.frame.origin.x+SLIDERFRAME>self.frame.size.width) {//向左
self.rightView.frame = CGRectMake(self.frame.size.width-SLIDERFRAME, (self.frame.size.height-SLIDERFRAME)/2, SLIDERFRAME, SLIDERFRAME);
}else if (self.rightView.frame.origin.x-self.leftView.frame.size.width<self.leftView.frame.origin.x){//向右
self.rightView.frame = CGRectMake(self.leftView.frame.origin.x+SLIDERFRAME, (self.frame.size.height-SLIDERFRAME)/2, SLIDERFRAME, SLIDERFRAME);
}else{//正常滑动
self.rightView.transform = CGAffineTransformTranslate(self.rightView.transform, point.x, 0);
}
//当滑块停止的时候返回区间值
if (rightPan.state == UIGestureRecognizerStateEnded) {
[self sliderStop];
}
}
-(void)sliderStop{
//当两个滑块a贴近的时候,返回右边滑块的百分比值
if (self.rightView.frame.origin.x-self.leftView.frame.origin.x<=25) {
CGFloat right =self.percentage*self.rightView.frame.origin.x;
self.myBlock(right, right);
}else{//当两个滑块分开的时候,分别返回滑块的百分比值
CGFloat left = self.percentage*self.leftView.frame.origin.x;
CGFloat right =self.percentage*self.rightView.frame.origin.x;
if (self.myBlock) {
self.myBlock(left, right);
}
}
}
Demo 地址:https://github.com/xiaoxie0217/CustomButton.git
持续更新中……
网友评论