《仿QQ未读消息粘性按钮》
2016-06-10 16:36
302 查看
思路
控件结构封装思路
细节注意
使用方法
1.控件结构
继承自UIButton, 对系统的按钮进行进一步的分装,主要是由一个圆形的UIView - smallCircle、
按钮本身和
一个CAShapeLayer图层构成。
2.封装思路
根据btn的frame,创建一个大小相同的圆形UIView-samillCircle, 并且将其添加到btn的父控件上。给按钮本身添加拖动手势和点击事件,在拖动手势监听时获取btn手势的偏移量,根据偏移量改变按钮本身的center坐标,使得btn跟随手势拖动而移动。
根据btn和smallCircle的center计算出两个圆的中心点的间距d, 根据间距改变smallCircle的半径(随着d越大,半径越小), 并且根据手势拖动描绘shapeLayer图层(根据手势坐标计算不规则图层的路径,这里用到UIBezierPath曲线路径), 通过对两个圆形区域的控制点A、B、C、D、O、P点描绘path路径,最后将路径赋值给图层,达到每次手势拖动不规则图层都会展示不同的矩形效果。
当间距达到最大间距kMaxDistance时,隐藏smallCircle,并且销毁不规则矩形。当手指抬起,判断间距d是否小于最大间距,若小于最大间距,则位置还原,若大于最大间距,则显示消失动画之后移除btn,调用delegate的
viscousButtonDismissed方法处理事件。同时,在点击btn时也可以展示btn消失动画以及代理事件,可以通过实现代理对按钮的事件进行后续逻辑功能处理。
3.细节注意
这里不能用绘图方法drawRect去代替图层shapeLayer的实现,因为如果采用绘图,绘图内容只要超过当前控件就不会显示,但是当前形变必须显示在控件之外。
如采用代码创建该按钮的实例进行使用,由于我们是在初始化方法initWithFrame和awakeFromNib中去调用setUp方法进行内容的初始化,包括对小圆smallCircle的创建和添加。但是这样一来,代码创建就会出现获取不到superView的问题,导致self.superView addSubview: samllCircle无效,和xib创建不同的是因为程序外部是在初始化之后才添加到父控件上,而xib是由内到外一层一层的添加控件,在当前按钮创建出来之前父控件已经存在。因此我们发现苹果提供一个
didMoveToSuperview方法,改方法会在父控件addSubView完成之后调用,故我们将添加小圆的步骤在该方法中执行。
/** * @brief 在父控件addSubview后调用 */ - (void)didMoveToSuperview { [super didMoveToSuperview]; // 设置小圆的位置和尺寸 self.smallCircle.center = self.center; self.smallCircle.bounds = CGRectMake(0, 0, self.bounds.size.height, self.bounds.size.height); self.smallCircle.layer.cornerRadius = self.bounds.size.height / 2; }
为防止xib中引用的self按钮会会默认使用自动布局,使用代码关闭自动布局,使得按钮和xib引用达到相同的效果。
// 取消父控件xib的自动布局 self.superview.translatesAutoresizingMaskIntoConstraints = NO;
4.使用方法
xib使用拖动一个UIButton控件到父控件上,将MRViscousButton文件中的MRViscousButton.h和MRViscousButton.m文件复制到项目中,更改UIButton的class为MRViscousButton即可。
代码创建
MRViscousButton *btn = [[MRViscousButton alloc] initWithFrame:CGRectMake(100, 150, 30, 30)]; // 设置代理 btn.delegate = self; [btn setTitle:@"24" forState:UIControlStateNormal]; [btn setBackgroundColor:[UIColor redColor]]; [self.view addSubview:btn]; // 设置动画图片 NSMutableArray *arrM = [NSMutableArray array]; for (int i = 1; i < 9; i++) { UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%d", i]]; [arrM addObject:image]; } btn.images = arrM; # pragma mark - <MRViscousButtonDelegate> - (void)viscousButtonDismissed:(MRViscousButton *)btn { NSLog(@"%@ - 代理回调方法", btn); }
效果图
Demo地址: github
相关文章推荐
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- QQ商业化,如何实现从0到1的破局?
- 十年生死两茫茫,Linux QQ 突然复活!
- VB实现的《QQ美女找茬游戏》作弊器实例
- flex 控件的重要属性
- 路由器端QQ封堵方案
- 学习Winform文本类控件(Label、Button、TextBox)
- Delphi控件ListView的属性及使用方法详解
- QQ输入法自动删除其它输入法的解决方法
- 让普通QQ号也能克隆QQ好友
- 基于ASP实现QQ在线查询功能
- web下载的ActiveX控件自动更新
- WinForm实现按名称递归查找控件的方法
- VBS取QQ或TM自动登录代码并防止关闭的脚本
- C#中父窗口和子窗口之间控件互操作实例
- Android ListView弹性效果的实现方法
- Android编程之Button控件用法实例分析
- Android控件之CheckBox、RadioButton用法实例分析
- 在Android开发中使用自定义组合控件的例子