iOS 一个浮动按钮,可以任意设置父视图

前言

在开发过程中,我们偶尔在个别页面需要做一个浮动按钮。这个按钮要么加载在当前控制器中,要么加载在Window中。

为了进一步扩展,将按钮的父视图扩展为任意UIView.

对于加载在当前控制器的情况,我们需要考虑的是是否有navbar,tabbar,兼容iOS11 就需要考虑安全区域的问题。所以封装一个浮动按钮,需要暴露的接口为2个:

1
2
3
4
5
/**传入父View*/
@property(nonatomic,weak) UIView *parentView;
/**安全边距,主要是针对有Navbar 以及 tabbar的*/
@property(nonatomic,assign)UIEdgeInsets safeInsets;

实现

为UIButton添加收拾,然后增加判断即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
-(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上的,安全区域就是个判断问题。

1
2
3
4
5
button.safeInsets = UIEdgeInsetsMake(NAVH, 0, ELSareArea , 0);
[self.view addSubview:button];
button.parentView = self.view;

效果

浮动.gif

demo地址:LXFloatingButton