iOS-仿小圆点效果

背景:

我不知道大伙们有没有遇到要做一个类似于小圆点的控件的需求,我在CocoaChina论坛上看别人说,这样的东西是会被拒审的,因为和系统的小圆点效果一样了。
管他呢,反正公司既然要求我做,那我做就是咯。


开发思路:

目前,我学习了两种方法。

一种较为简单,自定义一个UIImageView来实现。把UIImageView的交互打开,并且实现一个拖拽的手势,拖拽手势的方法里面实现对应效果即可。

另一种,稍微复杂一点点,直接用一个UIButton来实现就好。和上面一样,也是实现一个拖拽的手势,只是拖拽手势里面算法复杂点。

两种都有各自不同的特点,看大家喜欢哪种,我比较喜欢第二种,因为第二种逼格更高点。

除了上述两种方法,还有一种方法:就是直接把控件添加到window里面去。你会发现,上述两种方法,不过都是加在根控制器的view里面去的。试想,如果当前是UIViewController还好说,如果是NavigationController呢?如果是TabBarController呢?如果是NavigationController或者是TabBarController的话,那么这个控件就会被遮挡的。怎么办?加在window上就好啦。

不过,如果项目中没有太大的硬性需求,最好不要加载window上,怪怪的。


方法一:

//
//  ViewController.m
//  SuspendDemo
//
//  Created by HZhenF on 2017/9/12.
//  Copyright © 2017年 HZhenF. All rights reserved.
//

#import "ViewController.h"
#import "SuspendImgV.h"
#import "OneViewController.h"

#define kScreenWidth    [[UIScreen mainScreen] bounds].size.width
#define kScreenHeight   [[UIScreen mainScreen] bounds].size.height

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    SuspendImgV * v = [[SuspendImgV alloc] initWithFrame:CGRectMake(100, 100, kItemWidth, kItemHeight) topMargin:66 btomMargin:44];
    v.backgroundColor = [UIColor redColor];
    v.image = [UIImage imageNamed:@"lufei.jpg"];
    [self.view addSubview:v];

    UIView  * topV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 66)];
    topV.backgroundColor = [UIColor yellowColor];
    UIView  * centerV = [[UIView alloc] initWithFrame:CGRectMake(0, 66, kScreenWidth, kScreenHeight - 110)];
    centerV.backgroundColor = [UIColor lightGrayColor];
    UIView  * btomV = [[UIView alloc] initWithFrame:CGRectMake(0, kScreenHeight - 44, kScreenWidth, 44)];
    btomV.backgroundColor = [UIColor orangeColor];

    [self.view addSubview:topV];
    [self.view addSubview:centerV];
    [self.view addSubview:btomV];

    UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 300, 100, 100)];
    [btn setTitle:@"点我" forState:UIControlStateNormal];
    [btn addTarget:self action:@selector(btnAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];

    //将悬浮视图扔到最顶层
    [self.view bringSubviewToFront:v];
}

-(void)btnAction
{
    OneViewController *oneVC = [[OneViewController alloc] init];
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:oneVC];
    [self presentViewController:nav animated:YES completion:nil];
}

@end
//
//  SuspendImgV.h
//  SuspendDemo
//
//  Created by HZhenF on 2017/9/12.
//  Copyright © 2017年 HZhenF. All rights reserved.
//

#import <UIKit/UIKit.h>

#define kItemWidth 60
#define kItemHeight 60

@interface SuspendImgV : UIImageView

- (instancetype)initWithFrame:(CGRect)frame
                    topMargin:(CGFloat)top
                   btomMargin:(CGFloat)btom;

@end
//
//  SuspendImgV.m
//  SuspendDemo
//
//  Created by HZhenF on 2017/9/12.
//  Copyright © 2017年 HZhenF. All rights reserved.
//

#import "SuspendImgV.h"

typedef NS_ENUM(NSInteger, Position) {
    PositionLeft = 0,
    PositionRight = 1,
};

#define kHeight self.superview.frame.size.height
#define kWidth  self.superview.frame.size.width

@interface SuspendImgV ()

@property (nonatomic, assign) Position  position;
@property (nonatomic, assign) CGFloat   topMargin;
@property (nonatomic, assign) CGFloat   btomMargin;

@end

@implementation SuspendImgV

- (instancetype)initWithFrame:(CGRect)frame topMargin:(CGFloat)top btomMargin:(CGFloat)btom;
{
    if (self = [super init]) {
        self.frame = frame;
        self.userInteractionEnabled = YES;

        _topMargin = top;
        _btomMargin = btom;
        [self addGesture];
    }
    return self;
}

- (void)addGesture
{
    UIPanGestureRecognizer  * pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
    [self addGestureRecognizer:pan];
}

- (void)configFrameWithAnimation:(BOOL)aniamtion
{
    CGPoint p = self.frame.origin;

    CGRect  aimR = CGRectZero;
    if (self.center.x < kWidth/2) {
        aimR = CGRectMake(2, p.y, kItemWidth, kItemHeight);
        _position = PositionLeft;
    }else{
        aimR = CGRectMake(kWidth - kItemWidth - 2, p.y, kItemWidth, kItemHeight);
        _position = PositionRight;
    }

    if (aniamtion) {
        [UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            self.frame = aimR;
        } completion:nil];
    }else{
        self.frame = aimR;
    }
}

- (void)panAction:(UIPanGestureRecognizer *)pan
{
    if (pan.state == UIGestureRecognizerStateEnded
             || pan.state == UIGestureRecognizerStateCancelled){
        //结束
        [self configFrameWithAnimation:YES];
    }
    else {
        //移动
        //当然也可以相对于key window,只是self.superView的宽高和window不一致时,需要注意计算时的偏移量
        CGPoint p = [pan locationInView:self.superview];
        p.y = MAX(p.y, _topMargin + kItemHeight/2);
        p.y = MIN(kHeight - _btomMargin - kItemHeight/2, p.y);
        [UIView animateWithDuration:0.15 animations:^{
            self.center = p;
        }];
    }
}

@end

方法二:

//
//  ViewController.m
//  SmallPoint
//
//  Created by HZhenF on 2017/9/18.
//  Copyright © 2017年 GZHYTechnology. All rights reserved.
//

#import "ViewController.h"

// 屏幕高度
#define susScreenH [UIScreen mainScreen].bounds.size.height
// 屏幕宽度
#define susScreenW [UIScreen mainScreen].bounds.size.width
//悬浮按钮宽高
#define kSuspendBtnWidth 100 * susScreenW / 375

@interface ViewController ()


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];


    CGFloat X = 0;
    CGFloat Y = 100;
    CGFloat W = 100;
    CGFloat H = 100;
    UIButton *btnOne = [[UIButton alloc] initWithFrame:CGRectMake(X, Y, W, H)];
    [btnOne setImage:[UIImage imageNamed:@"girl"] forState:UIControlStateNormal];
    [self.view addSubview:btnOne];

    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
    [btnOne addGestureRecognizer:panGesture];

}


/**
 拖拽事件

 @param recognizer 当前拖拽的手势
 */
-(void)panAction:(UIPanGestureRecognizer *)recognizer
{
    //移动状态
    UIGestureRecognizerState recState =  recognizer.state;

    switch (recState) {
        case UIGestureRecognizerStateBegan:

            break;
        case UIGestureRecognizerStateChanged:
        {
            UIViewController *viewVC = self;
            CGPoint translation = [recognizer translationInView:viewVC.navigationController.view];
            recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x, recognizer.view.center.y + translation.y);
        }
            break;
        case UIGestureRecognizerStateEnded:
        {
            CGPoint stopPoint = CGPointMake(0, susScreenH / 2.0);

            if (recognizer.view.center.x < susScreenW / 2.0)
            {
                if (recognizer.view.center.y <= susScreenH/2.0) {
                    //左上
                    if (recognizer.view.center.x  >= recognizer.view.center.y) {
                        stopPoint = CGPointMake(recognizer.view.center.x, kSuspendBtnWidth/2.0);
                    }else{
                        stopPoint = CGPointMake(kSuspendBtnWidth/2.0, recognizer.view.center.y);
                    }
                }
                else{
                    //左下
                    if (recognizer.view.center.x  >= susScreenH - recognizer.view.center.y) {
                        stopPoint = CGPointMake(recognizer.view.center.x, susScreenH - kSuspendBtnWidth/2.0);
                    }else{
                        stopPoint = CGPointMake(kSuspendBtnWidth/2.0, recognizer.view.center.y);
                    }
                }
            }
            else{
                if (recognizer.view.center.y <= susScreenH/2.0) {
                    //右上
                    if (susScreenW - recognizer.view.center.x  >= recognizer.view.center.y) {
                        stopPoint = CGPointMake(recognizer.view.center.x, kSuspendBtnWidth/2.0);
                    }else{
                        stopPoint = CGPointMake(susScreenW - kSuspendBtnWidth/2.0, recognizer.view.center.y);
                    }
                }else{
                    //右下
                    if (susScreenW - recognizer.view.center.x  >= susScreenH - recognizer.view.center.y) {
                        stopPoint = CGPointMake(recognizer.view.center.x, susScreenH - kSuspendBtnWidth/2.0);
                    }else{
                        stopPoint = CGPointMake(susScreenW - kSuspendBtnWidth/2.0,recognizer.view.center.y);
                    }
                }
            }

            if (stopPoint.x - kSuspendBtnWidth/2.0 <= 0) {
                stopPoint = CGPointMake(kSuspendBtnWidth/2.0, stopPoint.y);
            }

            if (stopPoint.x + kSuspendBtnWidth/2.0 >= susScreenW) {
                stopPoint = CGPointMake(susScreenW - kSuspendBtnWidth/2.0, stopPoint.y);
            }

            if (stopPoint.y - kSuspendBtnWidth/2.0 <= 0) {
                stopPoint = CGPointMake(stopPoint.x, kSuspendBtnWidth/2.0);
            }

            if (stopPoint.y + kSuspendBtnWidth/2.0 >= susScreenH) {
                stopPoint = CGPointMake(stopPoint.x, susScreenH - kSuspendBtnWidth/2.0);
            }

            [UIView animateWithDuration:0.5 animations:^{
                recognizer.view.center = stopPoint;
            }];
        }
            break;

        default:
            break;
    }

    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}


@end

这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值