前言
在开发过程中,我们偶尔在个别页面需要做一个浮动按钮。这个按钮要么加载在当前控制器中,要么加载在Window
中。
为了进一步扩展,将按钮的父视图扩展为任意UIView
.
对于加载在当前控制器的情况,我们需要考虑的是是否有navbar
,tabbar
,兼容iOS11
就需要考虑安全区域的问题。所以封装一个浮动按钮,需要暴露的接口为2个:
/**传入父View*/
@property(nonatomic,weak) UIView *parentView;
/**安全边距,主要是针对有Navbar 以及 tabbar的*/
@property(nonatomic,assign)UIEdgeInsets safeInsets;
实现
为UIButton添加收拾,然后增加判断即可。
-(void)initilize{
self.safeInsets = UIEdgeInsetsMake(0, 0, 0, 0);
//添加手势
UIPanGestureRecognizer * panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(doMoveAction:)];
[self addGestureRecognizer:panGestureRecognizer];
}
-(void)setParentView:(UIView *)parentView{
_parentView = parentView;
}
#pragma mark - 手势方法
- (void)doMoveAction:(UIPanGestureRecognizer *)recognizer
{
//1、手势在self.view坐标系中移动的位置
CGPoint translation = [recognizer translationInView:self.parentView];
CGPoint newCenter = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
//2、限制屏幕范围:
//上边界的限制
newCenter.y = MAX(recognizer.view.frame.size.height/2 + self.safeInsets.top, newCenter.y);
//下边界的限制
newCenter.y = MIN(self.parentView.height - self.safeInsets.bottom- recognizer.view.frame.size.height/2, newCenter.y);
//左边界的限制
newCenter.x = MAX(recognizer.view.frame.size.width/2, newCenter.x);
//右边界的限制
newCenter.x = MIN(self.parentView.width - recognizer.view.frame.size.width/2,newCenter.x);
//设置中心点范围
recognizer.view.center = newCenter;
//3、将手势坐标点归0、否则会累加
[recognizer setTranslation:CGPointZero inView:self.parentView];
}
示例
示例里,添加到当前控制器里有显示navbar
,隐藏navbar
, 显示到Window
上的,有显示在自定义View
上的,安全区域就是个判断问题。
button.safeInsets = UIEdgeInsetsMake(NAVH, 0, ELSareArea , 0);
[self.view addSubview:button];
button.parentView = self.view;
效果
![](https://img.haomeiwen.com/i1694376/94f6f456553d1aa3.gif)
demo地址:LXFloatingButton
网友评论
其实没有必要写parentView这个属性 使用button.superView可以有一样的效果
//右边界的限制
newCenter.x = MAX(recognizer.view.frame.size.width/2, newCenter.x);
//左边界的限制
newCenter.x = MIN(self.parentView.width - recognizer.view.frame.size.width/2,newCenter.x);