iOS自定义button抖动效果并实现右上角删除按钮
程序员文章站
2023-12-03 14:41:46
遇到过这种需求要做成类似与苹果删除软件时的动态效果。
1.长按抖动;
2.抖动时出现一个x;
3.点击x,删除button;
4.抖动时,点击按钮,停止抖动;...
遇到过这种需求要做成类似与苹果删除软件时的动态效果。
1.长按抖动;
2.抖动时出现一个x;
3.点击x,删除button;
4.抖动时,点击按钮,停止抖动;
下面是我的设计思路:
1.继承uibutton;
2.给button在右上角添加一个按钮;
3.给button添加长按手势;
4.给button添加遮盖,抖动时可以拦截点击事件;
有更好的做法,还请斧正。
// .m文件 #import "dzdeletebutton.h" #import "uiview+extension.h" // 这个只是为了方便取宽高的一个分类,代码就不贴了 @interface dzdeletebutton () // 是否抖动 @property (nonatomic, assign, getter=isshaking) bool shaking; // 右上角的按钮, @property (nonatomic, weak) uiimageview *iconbtn; // 遮盖,在抖动时出现 @property (nonatomic, weak) uiview *coverview; @end @implementation dzdeletebutton - (uiimageview *)iconbtn { if (!_iconbtn) { uiimageview *iconbtn = [[uiimageview alloc] initwithimage:[uiimage imagenamed:@"delete"]]; iconbtn.userinteractionenabled = yes; iconbtn.hidden = yes; _iconbtn = iconbtn; uitapgesturerecognizer *tap = [[uitapgesturerecognizer alloc] initwithtarget:self action:@selector(iconclick)]; [iconbtn addgesturerecognizer:tap]; [self addsubview:iconbtn]; } return _iconbtn; } - (uiview *)coverview { if (!_coverview) { uiview *view = [[uiview alloc] init]; view.backgroundcolor = [uicolor clearcolor]; view.hidden = yes; uitapgesturerecognizer *tap = [[uitapgesturerecognizer alloc] initwithtarget:self action:@selector(coverclick)]; [view addgesturerecognizer:tap]; [self addsubview:view]; _coverview = view; } return _coverview; } - (instancetype)initwithframe:(cgrect)frame { self = [super initwithframe:frame]; if (self) { [self addlongpressgesturerecognizer]; } return self; } - (instancetype)init { self = [super init]; if (self) { [self addlongpressgesturerecognizer]; } return self; } - (instancetype)initwithcoder:(nscoder *)coder { self = [super initwithcoder:coder]; if (self) { [self addlongpressgesturerecognizer]; } return self; } // 添加长按手势 - (void)addlongpressgesturerecognizer { uilongpressgesturerecognizer *longpress = [[uilongpressgesturerecognizer alloc] initwithtarget:self action:@selector(longclick)]; [self addgesturerecognizer:longpress]; } - (void)delete { [self.iconbtn.superview removefromsuperview]; } // 是否执行动画 - (void)setshaking:(bool)shaking { if (shaking) { [self shakinganimation]; self.coverview.hidden = no; self.iconbtn.hidden = no; } else { [self.layer removeallanimations]; self.coverview.hidden = yes; self.iconbtn.hidden = yes; } } #pragma mark - 抖动动画 #define angle2radian(angle) ((angle) / 180.0 * m_pi) - (void)shakinganimation { cakeyframeanimation *anim = [cakeyframeanimation animation]; anim.keypath = @"transform.rotation"; anim.values = @[@(angle2radian(-5)), @(angle2radian(5)), @(angle2radian(-5))]; anim.duration = 0.25; // 动画次数设置为最大 anim.repeatcount = maxfloat; // 保持动画执行完毕后的状态 anim.removedoncompletion = no; anim.fillmode = kcafillmodeforwards; [self.layer addanimation:anim forkey:@"shake"]; } - (void)longclick { if (self.shaking) return; self.shaking = yes; } // 点击右上角按钮 - (void)iconclick { [self removefromsuperview]; // 设计一个代理,为了在自己被删除后做一些事情(例如,对页面进行布局) if ([self.delegate respondstoselector:@selector(deletebuttonremoveself:)]) { [self.delegate deletebuttonremoveself:self]; } } - (void)coverclick { self.shaking = no; } - (void)layoutsubviews { [super layoutsubviews]; // 调整位置 self.imageview.x = 0; self.imageview.y = 0; self.imageview.width = self.width; self.imageview.height = self.width; self.titlelabel.x = 0; self.titlelabel.width = self.width; if (self.width >= self.height) { self.titlelabel.height = 20; self.titlelabel.y = self.height - self.titlelabel.height; } else { self.titlelabel.y = self.imageview.height; self.titlelabel.height = self.height - self.titlelabel.y; } self.titlelabel.textalignment = nstextalignmentcenter; self.iconbtn.size = cgsizemake(self.width * 0.3, self.width * 0.3); self.iconbtn.x = self.width - self.iconbtn.width; self.iconbtn.y = 0; self.coverview.frame = self.bounds; [self bringsubviewtofront:self.iconbtn]; } @end
// .h文件 只有一个代理 #import <uikit/uikit.h> @class dzdeletebutton; @protocol dzdeletebuttondelegate <nsobject> @optional - (void)deletebuttonremoveself:(dzdeletebutton *)button; @end @interface dzdeletebutton : uibutton @property (nonatomic, weak) id<dzdeletebuttondelegate> delegate; @end
上面效果图在vc中的代码
- (void)viewdidload { [super viewdidload]; dzdeletebutton *button = [[dzdeletebutton alloc] init]; [button setimage:[uiimage imagenamed:@"bj"] forstate:uicontrolstatenormal]; [button settitle:@"百思" forstate:uicontrolstatenormal]; button.delegate = self; button.frame = cgrectmake(20, 20, 60, 80); [button settitlecolor:[uicolor redcolor] forstate:uicontrolstatenormal]; [button addtarget:self action:@selector(btnclick) forcontrolevents:uicontroleventtouchupinside]; [self.view addsubview:button]; } - (void)btnclick { nslog(@"点击button"); } - (void)deletebuttonremoveself:(dzdeletebutton *)button { nslog(@"已经删除,要做什么事"); }
以上就是本文的全部内容,希望对大家的学习有所帮助。