iOSはviewにドラッグ機能を追加
3278 ワード
前言
現在の生放送アプリには、サスペンションウィンドウ機能があり、サスペンションウィンドウはドラッグ&ドロップでき、リバウンドアニメーションがあり、UIDIewの分類実装を設計し、侵入性を低減することができます.
主なコードと構想
構想
コード#コード#
#import "UIView+dragable.h"
#import
#define ScreenWidth [[UIScreen mainScreen] bounds].size.width
#define ScreenHeight [[UIScreen mainScreen] bounds].size.height
static const char *ActionHandlerPanGestureKey;
@implementation UIView (dragable)
- (void)addDragableActionWithEnd:(void (^)(CGRect endFrame))endBlock; {
//
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanAction:)];
[self addGestureRecognizer:panGestureRecognizer];
// block
objc_setAssociatedObject(self, ActionHandlerPanGestureKey, endBlock, OBJC_ASSOCIATION_COPY);
}
@end
- (void)handlePanAction:(UIPanGestureRecognizer *)sender {
CGPoint point = [sender translationInView:[sender.view superview]];
CGFloat senderHalfViewWidth = sender.view.frame.size.width / 2;
CGFloat senderHalfViewHeight = sender.view.frame.size.height / 2;
__block CGPoint viewCenter = CGPointMake(sender.view.center.x + point.x, sender.view.center.y + point.y);
//
if (sender.state == UIGestureRecognizerStateEnded) {
[UIView animateWithDuration:0.4 animations:^{
if ((sender.view.center.x + point.x - senderHalfViewWidth) <= 12) {
viewCenter.x = senderHalfViewWidth + 12;
}
if ((sender.view.center.x + point.x + senderHalfViewWidth) >= (ScreenWidth - 12)) {
viewCenter.x = ScreenWidth - senderHalfViewWidth - 12;
}
if ((sender.view.center.y + point.y - senderHalfViewHeight) <= 12) {
viewCenter.y = senderHalfViewHeight + 12;
}
if ((sender.view.center.y + point.y + senderHalfViewHeight) >= (ScreenHeight - 12)) {
viewCenter.y = ScreenHeight - senderHalfViewHeight - 12;
}
sender.view.center = viewCenter;
} completion:^(BOOL finished) {
void (^endBlock)(CGRect endFrame) = objc_getAssociatedObject(self, ActionHandlerPanGestureKey);
if (endBlock) {
endBlock(sender.view.frame);
}
}];
[sender setTranslation:CGPointMake(0, 0) inView:[sender.view superview]];
} else {
// UIGestureRecognizerStateBegan || UIGestureRecognizerStateChanged
viewCenter.x = sender.view.center.x + point.x;
viewCenter.y = sender.view.center.y + point.y;
sender.view.center = viewCenter;
[sender setTranslation:CGPointMake(0, 0) inView:[sender.view superview]];
}
}
UIGestureRecognizerState
の状態はUIGestureRecognizerStateEnded
であり、ドラッグが終了すると、ドラッグビューの位置がスクリーン境界を超えているかどうかを判断する必要があり、境界を超えている場合は境界内に戻る必要がある.