|
@@ -0,0 +1,213 @@
|
|
|
+//
|
|
|
+// HomeDragButton.m
|
|
|
+// KulexiuForStudent
|
|
|
+//
|
|
|
+// Created by 王智 on 2022/10/19.
|
|
|
+//
|
|
|
+
|
|
|
+#import "HomeDragButton.h"
|
|
|
+
|
|
|
+#define WIDTH (self.frame.size.width)
|
|
|
+#define HEIGHT (self.frame.size.height)
|
|
|
+
|
|
|
+@interface HomeDragButton ()<UIGestureRecognizerDelegate>
|
|
|
+
|
|
|
+@property (nonatomic, assign) UIInterfaceOrientation currentOrientation;
|
|
|
+
|
|
|
+@property (nonatomic, copy) HomeDragButtonDetail callback;
|
|
|
+
|
|
|
+@end
|
|
|
+
|
|
|
+@implementation HomeDragButton
|
|
|
+
|
|
|
+- (instancetype)initWithFrame:(CGRect)frame {
|
|
|
+ if (self = [super initWithFrame:frame]) {
|
|
|
+ self.backgroundColor = [UIColor clearColor];
|
|
|
+ [self addSubview:self.containerView];
|
|
|
+ self.containerView.frame = CGRectMake(0, 0, frame.size.width, frame.size.height);
|
|
|
+ UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(locationChange:)];
|
|
|
+ pan.delaysTouchesBegan = YES;
|
|
|
+ [self addGestureRecognizer:pan];
|
|
|
+ self.currentOrientation = UIInterfaceOrientationPortrait;
|
|
|
+ UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(click:)];
|
|
|
+ [self addGestureRecognizer:tap];
|
|
|
+ tap.delegate = self;
|
|
|
+ }
|
|
|
+ return self;
|
|
|
+}
|
|
|
+
|
|
|
+- (void)clickAction:(HomeDragButtonDetail)callback {
|
|
|
+ if (callback) {
|
|
|
+ self.callback = callback;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//点击事件
|
|
|
+-(void)click:(UITapGestureRecognizer*)tapGesture {
|
|
|
+ if (self.callback) {
|
|
|
+ self.callback();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#define KDEAISellDegreesToRadians(degrees) (degrees * M_PI / 180)
|
|
|
+- (void)statusBarOrientationChange:(NSNotification*)notification{
|
|
|
+ UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
|
|
|
+
|
|
|
+ [self setTransform:[self transformForOrientation:orientation]];
|
|
|
+ self.currentOrientation = orientation;
|
|
|
+
|
|
|
+ CGFloat screenWidth = KPortraitWidth;
|
|
|
+ CGFloat screenHeight = KPortraitHeight - kTabBarHeight;
|
|
|
+ if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) {
|
|
|
+ self.frame = CGRectMake(HomeDragButtonHeight+HomeDragButtonBottomSpace, screenWidth - HomeDragButtonWidth , HomeDragButtonWidth, HomeDragButtonHeight);
|
|
|
+ }else{
|
|
|
+ self.frame = CGRectMake(screenWidth - HomeDragButtonWidth, screenHeight - HomeDragButtonHeight - HomeDragButtonBottomSpace , HomeDragButtonWidth, HomeDragButtonHeight);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (CGAffineTransform)transformForOrientation:(UIInterfaceOrientation)orientation {
|
|
|
+
|
|
|
+ switch (orientation) {
|
|
|
+
|
|
|
+ case UIInterfaceOrientationLandscapeLeft:
|
|
|
+ return CGAffineTransformMakeRotation(-KDEAISellDegreesToRadians(90));
|
|
|
+
|
|
|
+ case UIInterfaceOrientationLandscapeRight:
|
|
|
+ return CGAffineTransformMakeRotation(KDEAISellDegreesToRadians(90));
|
|
|
+
|
|
|
+ case UIInterfaceOrientationPortraitUpsideDown:
|
|
|
+ return CGAffineTransformMakeRotation(KDEAISellDegreesToRadians(180));
|
|
|
+
|
|
|
+ case UIInterfaceOrientationPortrait:
|
|
|
+ default:
|
|
|
+ return CGAffineTransformMakeRotation(KDEAISellDegreesToRadians(0));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//改变位置
|
|
|
+//横屏之后的坐标系变为左下角坐标系,其中x轴向上,y轴向右,在这样的坐标系中计算即可
|
|
|
+-(void)locationChange:(UIPanGestureRecognizer*)pan {
|
|
|
+
|
|
|
+ if (self.currentOrientation == UIInterfaceOrientationLandscapeRight || self.currentOrientation == UIInterfaceOrientationLandscapeLeft) {//如果是横屏
|
|
|
+ [self springToBoundsOnLandscape:pan];
|
|
|
+
|
|
|
+ } else{ //如果是竖屏
|
|
|
+ [self springToBoundsOnPortrait:pan];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (void)springToBoundsOnPortrait:(UIPanGestureRecognizer*)panGesture {
|
|
|
+ CGFloat screenWidth = KPortraitWidth;
|
|
|
+ CGFloat screenHeight = KPortraitHeight - kTabBarHeight;
|
|
|
+
|
|
|
+ CGPoint panPoint = [panGesture locationInView:[[UIApplication sharedApplication] windows][0]];
|
|
|
+ if(panGesture.state == UIGestureRecognizerStateBegan) {
|
|
|
+
|
|
|
+ } else if (panGesture.state == UIGestureRecognizerStateChanged) {
|
|
|
+ self.center = CGPointMake(panPoint.x, panPoint.y);
|
|
|
+ } else if(panGesture.state == UIGestureRecognizerStateEnded || panGesture.state == UIGestureRecognizerStateCancelled) {
|
|
|
+ NSLog(@"ss");
|
|
|
+ if(panPoint.x <= screenWidth/2) {
|
|
|
+ if(panPoint.y >= screenHeight-HEIGHT/2-40 ) { //左下边界判断
|
|
|
+ [UIView animateWithDuration:0.2 animations:^{
|
|
|
+ self.center = CGPointMake(WIDTH/2, screenHeight-HEIGHT/2);
|
|
|
+ }];
|
|
|
+
|
|
|
+ } else if (panPoint.y < (HEIGHT/2 + STATUS_BAR_HEIGHT)) {
|
|
|
+ [UIView animateWithDuration:0.2 animations:^{
|
|
|
+ self.center = CGPointMake(WIDTH/2, HEIGHT/2 + STATUS_BAR_HEIGHT);
|
|
|
+
|
|
|
+ }];
|
|
|
+ } else {
|
|
|
+ [UIView animateWithDuration:0.2 animations:^{
|
|
|
+ self.center = CGPointMake(WIDTH/2, panPoint.y);
|
|
|
+ }];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(panPoint.x > screenWidth/2) {
|
|
|
+ if(panPoint.y <= (HEIGHT/2 + STATUS_BAR_HEIGHT)) {//向右越过上边界
|
|
|
+
|
|
|
+ [UIView animateWithDuration:0.2 animations:^{
|
|
|
+ self.center = CGPointMake(screenWidth-WIDTH/2, HEIGHT/2 + STATUS_BAR_HEIGHT);
|
|
|
+ }];
|
|
|
+
|
|
|
+ }
|
|
|
+ else if (panPoint.y > screenHeight-HEIGHT/2) { //右下边界
|
|
|
+ [UIView animateWithDuration:0.2 animations:^{
|
|
|
+ self.center = CGPointMake(screenWidth-WIDTH/2, screenHeight-HEIGHT/2);
|
|
|
+ }];
|
|
|
+
|
|
|
+ }else { //正常拖动
|
|
|
+ [UIView animateWithDuration:0.2 animations:^{
|
|
|
+ self.center = CGPointMake(screenWidth-WIDTH/2, panPoint.y);
|
|
|
+ }];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (void)springToBoundsOnLandscape:(UIPanGestureRecognizer*)panGesture {
|
|
|
+ CGFloat screenWidth = KPortraitWidth;
|
|
|
+ CGFloat screenHeight = KPortraitHeight - kTabBarHeight;
|
|
|
+
|
|
|
+ CGPoint panPoint = [panGesture locationInView:[[UIApplication sharedApplication] windows][0]];
|
|
|
+ panPoint = CGPointMake(screenHeight - panPoint.y, panPoint.x);
|
|
|
+
|
|
|
+ NSLog(@"screenWidth:%f, panPoint:%@", screenWidth, NSStringFromCGPoint(panPoint));
|
|
|
+
|
|
|
+ if(panGesture.state == UIGestureRecognizerStateBegan) {
|
|
|
+ } else if (panGesture.state == UIGestureRecognizerStateChanged) {
|
|
|
+ self.center = CGPointMake(panPoint.x, panPoint.y);
|
|
|
+ } else if(panGesture.state == UIGestureRecognizerStateEnded || panGesture.state == UIGestureRecognizerStateCancelled) {
|
|
|
+ if(panPoint.y <= screenWidth/2) {
|
|
|
+ if (panPoint.x <= HEIGHT/2 + STATUS_BAR_HEIGHT) {
|
|
|
+ [UIView animateWithDuration:0.2 animations:^{//左下角
|
|
|
+ self.center = CGPointMake(WIDTH/2, HEIGHT/2 + STATUS_BAR_HEIGHT);
|
|
|
+ }];
|
|
|
+ }else if (panPoint.x >= screenHeight - HEIGHT/2){//左上角
|
|
|
+ [UIView animateWithDuration:0.2 animations:^{
|
|
|
+ self.center = CGPointMake(screenHeight - HEIGHT/2, HEIGHT/2 + STATUS_BAR_HEIGHT);
|
|
|
+ }];
|
|
|
+ }else{
|
|
|
+ [UIView animateWithDuration:0.2 animations:^{
|
|
|
+ self.center = CGPointMake(panPoint.x, HEIGHT/2 + STATUS_BAR_HEIGHT);
|
|
|
+ }];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(panPoint.y > screenWidth/2)
|
|
|
+ {
|
|
|
+ if (panPoint.x <= HEIGHT/2) {//右下角
|
|
|
+ [UIView animateWithDuration:0.2 animations:^{
|
|
|
+ self.center = CGPointMake(HEIGHT/2, screenWidth - WIDTH/2);
|
|
|
+ }];
|
|
|
+ }else if (panPoint.x >= screenHeight - HEIGHT/2){//右上角
|
|
|
+ [UIView animateWithDuration:0.2 animations:^{
|
|
|
+ self.center = CGPointMake(screenHeight - HEIGHT/2, screenWidth - WIDTH/2);
|
|
|
+ }];
|
|
|
+ }else{
|
|
|
+ [UIView animateWithDuration:0.2 animations:^{
|
|
|
+ self.center = CGPointMake(panPoint.x , screenWidth - WIDTH/2);
|
|
|
+ }];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (UIImageView *)containerView {
|
|
|
+ if (!_containerView) {
|
|
|
+ _containerView = [[UIImageView alloc] init];
|
|
|
+ _containerView.backgroundColor = [UIColor clearColor];
|
|
|
+ _containerView.contentMode = UIViewContentModeScaleAspectFill;
|
|
|
+ }
|
|
|
+ return _containerView;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+// Only override drawRect: if you perform custom drawing.
|
|
|
+// An empty implementation adversely affects performance during animation.
|
|
|
+- (void)drawRect:(CGRect)rect {
|
|
|
+ // Drawing code
|
|
|
+}
|
|
|
+*/
|
|
|
+
|
|
|
+@end
|