前言
项目中有类似微信视频通话最小化后,悬浮一个小窗口的功能,同时需要这个窗口可拖动。下面是窗口可拖动实现过程。
代码
新建FloatView
继承自UIView
或UIWindow
,我这里的视频小窗口采用UIWindow实现,所以继承自UIWindow
//.h代码
@interface FloatWindow : UIWindow
@property (nonatomic, nullable, copy) void(^floatWindwDidClickBlock)(FloatWindow *window);
@end
//.m代码
static CGFloat kMargin = 10.f;
#define is_iPhoneXSerious @available(iOS 11.0, *) && UIApplication.sharedApplication.keyWindow.safeAreaInsets.bottom > 0.0
@implementation FloatWindow
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];
[self addGestureRecognizer:tapGesture];
}
return self;
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
self.center = [touches.anyObject locationInView:[UIApplication sharedApplication].delegate.window];
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self endTouch:[touches.anyObject locationInView:[UIApplication sharedApplication].delegate.window]];
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self endTouch:[touches.anyObject locationInView:[UIApplication sharedApplication].delegate.window]];
}
- (void)endTouch:(CGPoint)point {
CGRect frame = self.frame;
CGFloat screenWidth = UIScreen.mainScreen.bounds.size.width;
CGFloat screenHeight = UIScreen.mainScreen.bounds.size.height;
if (point.x > screenWidth / 2.f) {
frame.origin.x = screenWidth - frame.size.width - kMargin;
} else {
frame.origin.x = kMargin;
}
CGFloat maxY = screenHeight - frame.size.height - (is_iPhoneXSerious ? 34:0);
CGFloat minY = is_iPhoneXSerious ? 44:20;
if (frame.origin.y > maxY) {
frame.origin.y = maxY;
} else if (frame.origin.y < minY) {
frame.origin.y = minY;
}
[UIView animateWithDuration:0.3 animations:^{
self.frame = frame;
}];
}
#pragma mark - tap gesture
- (void)tap:(UITapGestureRecognizer *)gesture {
if (self.floatWindwDidClickBlock) {
self.floatWindwDidClickBlock(self);
}
}
注意点
如果只是单纯实现一个可拖动的视图的话,请继承
UIView
而不是UIWindow
,然后调用initWithFrame
方法初始化View,在View上可以根据项目添加自定义的控件元素,最后将视图addSubview到所需界面上即可。
如果要实现一个可拖动的UIWindow的话,可以继承UIWindow
。
另外,后续会在此基础上写一篇文章记录微信视频通话最小化后浮窗功能实现过程。