UI基础--动力特效,支持加速度(封装好)

建一个UIView的类别:

#import <UIKit/UIKit.h>

@interface UIView (Dynamic)<UIDynamicItem>
@end


#import "UIView+Dynamic.h"

@implementation UIView (Dynamic)
-(UIDynamicItemCollisionBoundsType)collisionBoundsType{
    return UIDynamicItemCollisionBoundsTypeEllipse;
}
@end

创建一个View继承UIView

.h

#import <UIKit/UIKit.h>
#import "UIView+Dynamic.h"
#import <CoreMotion/CoreMotion.h>

@interface MyView : UIView<UICollisionBehaviorDelegate,UIAccelerometerDelegate>

@property(nonatomic,strong)UIDynamicAnimator *animator;
@property (nonatomic,strong)NSMutableArray *views;
@property (nonatomic,strong)NSMutableArray<UISnapBehavior*> *snaps;
@property(nonatomic,strong)UIGravityBehavior *grb;
@property(nonatomic,strong)UIImageView* imgV;
@property(nonatomic,strong)CMMotionManager *motionManager;

@end

.m

#import "MyView.h"


#define SCREEN_WIDTH (int)[UIScreen mainScreen].bounds.size.width
#define SCREEN_HEIGHT (int)[UIScreen mainScreen].bounds.size.height

@implementation MyView

-(instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    
    if (self) {
        [self creatSubViews];
    }
    return  self;
}

- (void)creatSubViews{
    
    self.views=[NSMutableArray array];
    self.snaps=[NSMutableArray array];
    self.imgV=[[UIImageView alloc]initWithFrame:self.bounds];
    [self addSubview:self.imgV];
    for (int i = 0; i<30; i++) {
        UILabel *view = [[UILabel alloc]initWithFrame:CGRectMake(arc4random()%(SCREEN_WIDTH-30),arc4random()%(SCREEN_HEIGHT-30), 30, 30)];
        view.backgroundColor = [UIColor colorWithRed:(arc4random()%255)/255.0 green:(arc4random()%255)/255.0 blue:(arc4random()%255)/255.0 alpha:1];
        view.text=[NSString stringWithFormat:@"%d",i];
        view.layer.cornerRadius = 15;
        view.textAlignment = NSTextAlignmentCenter;
        view.font = [UIFont systemFontOfSize:22];
        [view setClipsToBounds:YES];
        UISnapBehavior *snap = [[UISnapBehavior alloc]initWithItem:view snapToPoint:CGPointMake(160, 280)];
        [self.snaps addObject:snap];
        [self.views addObject:view];
        [self addSubview:view];
    }
    self.animator = [[UIDynamicAnimator alloc]initWithReferenceView:self];
    UICollisionBehavior *clb =[[UICollisionBehavior alloc]initWithItems:self.views];
    UIDynamicItemBehavior * itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:self.views];
    itemBehavior.elasticity = 0.8;
    [_animator addBehavior:itemBehavior];
    [clb addBoundaryWithIdentifier:@"boundTop" fromPoint:CGPointMake(0, 0) toPoint:CGPointMake(SCREEN_WIDTH, 0)];
    [clb addBoundaryWithIdentifier:@"line"fromPoint:CGPointMake(0, 100) toPoint:CGPointMake(SCREEN_WIDTH-100, 100)];
    UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 100, SCREEN_WIDTH-100, 2)];
    lineView.backgroundColor = [UIColor redColor];
    [self addSubview:lineView];
    [clb addBoundaryWithIdentifier:@"boundLeft" fromPoint:CGPointMake(0, 0) toPoint:CGPointMake(0, SCREEN_HEIGHT)];
    [clb addBoundaryWithIdentifier:@"boundBottom" fromPoint:CGPointMake(0, SCREEN_HEIGHT) toPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT)];
    [clb addBoundaryWithIdentifier:@"boundRight" fromPoint:CGPointMake(SCREEN_WIDTH, 0) toPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT)];
    clb.collisionDelegate = self;
    UIGravityBehavior *grb = [[UIGravityBehavior alloc]initWithItems:self.views];
    grb.magnitude = 1;
    [self.animator addBehavior:grb];
    self.grb=grb;
    [self.animator addBehavior:clb];
    
    
    self.motionManager = [[CMMotionManager alloc] init];
    self.motionManager.accelerometerUpdateInterval = 1/30.0;
    [self.motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMAccelerometerData * _Nullable accelerometerData, NSError * _Nullable error) {
        
        double size =1-fabs(accelerometerData.acceleration.z);
        self.grb.magnitude=9.8*size;
        double angle = atan2(-1*accelerometerData.acceleration.y, accelerometerData.acceleration.x);
        self.grb.angle =angle;    }];

    
}

-(void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(nonnull id<UIDynamicItem>)item1 withItem:(nonnull id<UIDynamicItem>)item2 atPoint:(CGPoint)p{
    NSInteger i = [self.views indexOfObject:item1];
    NSInteger j = [self.views indexOfObject:item2];
    if ([self.animator.behaviors containsObject:self.snaps[i]]) {
        [self.animator removeBehavior:self.snaps[i]];
    }
    if ([self.animator.behaviors containsObject:self.snaps[j]]) {
        [self.animator removeBehavior:self.snaps[i]];
    }
    
}



@end

在你需要的地方调用

#import "ViewController.h"
#import "MyView.h"

#define SCREEN_WIDTH (int)[UIScreen mainScreen].bounds.size.width
#define SCREEN_HEIGHT (int)[UIScreen mainScreen].bounds.size.height

@interface ViewController ()

@property (nonatomic, strong) MyView *myView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    self.myView = [[MyView alloc]initWithFrame:self.view.bounds];
    [self.view addSubview:_myView];
    
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    for (int i =0; i<self.myView.snaps.count; i++) {
        if ([self.myView.animator.behaviors containsObject:self.myView.snaps[i]]) {
            [self.myView.animator removeBehavior:self.myView.snaps[i]];
        }
        self.myView.snaps[i]= [[UISnapBehavior alloc]initWithItem:self.myView.views[i] snapToPoint:CGPointMake(arc4random()%(SCREEN_WIDTH-30), arc4random()%(SCREEN_HEIGHT-30))];
        [self.myView.animator addBehavior:self.myView.snaps[i]];
    }
    
}

-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self.myView.snaps enumerateObjectsUsingBlock:^(UISnapBehavior * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [self.myView.animator removeBehavior:obj];
    }];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

OK...

原文地址:https://www.cnblogs.com/LzwBlog/p/5844514.html