建一个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...