2.0~2.6 重力,碰撞,弹跳等 Creating Dynamic and Interactive User Interfaces

2.0. IntroductionCreating Dynamic and Interactive User Interfaces

重力,碰撞,弹跳等


2.1. Adding Gravity to Your UI Components

给UI增加重力


#import "ViewController.h"


@interface ViewController ()

@property (nonatomic,strong) UIView *squareView;

@property (nonatomic,strong) UIDynamicAnimator *animator;

@end


@implementation ViewController


- (void)viewDidLoad

{

    [superviewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

}


- (void)didReceiveMemoryWarning

{

    [superdidReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


- (void)viewDidAppear:(BOOL)animated{ [superviewDidAppear:animated];

    /* Create our little square view and add it to self.view */

    self.squareView = [[UIViewalloc] initWithFrame:

                      CGRectMake(0.0f,0.0f, 100.0f,100.0f)];

    self.squareView.backgroundColor = [UIColorgreenColor];

    self.squareView.center =self.view.center;

    [self.viewaddSubview:self.squareView];

    /* Create the animator and the gravity */

    self.animator = [[UIDynamicAnimatoralloc]

                    initWithReferenceView:self.view];

    UIGravityBehavior *gravity = [[UIGravityBehavioralloc]

                                 initWithItems:@[self.squareView]];

    [self.animatoraddBehavior:gravity];

}


@end

运行之后,绿色方块从屏幕中央向下掉出屏幕


2.2. Detecting and Reacting to Collisions Between UI Components

碰撞检测



#import "ViewController.h"


NSString *const kBottomBoundary =@"bottomBoundary";


@interface ViewController ()<UICollisionBehaviorDelegate>

@property (nonatomic,strong) NSMutableArray *squareViews;

@property (nonatomic,strong) UIDynamicAnimator *animator;

@end


@implementation ViewController


- (void)viewDidLoad

{

    [superviewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

}


- (void)didReceiveMemoryWarning

{

    [superdidReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


- (void)viewDidAppear:(BOOL)animated{

    [superviewDidAppear:animated];

    /* Create the views */

   NSUInteger const NumberOfViews =15;

   self.squareViews = [[NSMutableArrayalloc] initWithCapacity:NumberOfViews];

   NSArray *colors = @[[UIColor redColor], [UIColor greenColor],[UIColor blueColor]];

   CGPoint currentCenterPoint = self.view.center;

   CGSize eachViewSize = CGSizeMake(30.0f, 30.0f);

    

   for (NSUInteger counter =0; counter < NumberOfViews; counter++){

//        for (int colomn = 0; colomn < 15; colomn++) {

//            currentCenterPoint.x = (eachViewSize.width+10)*colomn;

           UIView *newView =

            [[UIViewalloc] initWithFrame:

            CGRectMake(0.0f,0.0f, eachViewSize.width, eachViewSize.height)];

            newView.backgroundColor = colors[counter % colors.count];

            newView.center = currentCenterPoint;

            currentCenterPoint.y -= eachViewSize.height +10.0f;

            [self.viewaddSubview:newView];

            [self.squareViewsaddObject:newView];

            

//        }

    }

    self.animator = [[UIDynamicAnimatoralloc]

                    initWithReferenceView:self.view];

    /* Create gravity */

    UIGravityBehavior *gravity = [[UIGravityBehavioralloc]

                                 initWithItems:self.squareViews];

 

    [self.animatoraddBehavior:gravity];

    

#if 0

    //碰撞检测

    /* Create collision detection */

    UICollisionBehavior *collision = [[UICollisionBehavior alloc]

                                      initWithItems:self.squareViews];

    collision.translatesReferenceBoundsIntoBoundary =YES;

    [self.animator addBehavior:collision];

#elif 0

    //在离底部100的地方设为边界

    /* Create collision detection */

    UICollisionBehavior *collision = [[UICollisionBehavior alloc]

                                      initWithItems:self.squareViews];

    [collision

     addBoundaryWithIdentifier:@"bottomBoundary"

     fromPoint:CGPointMake(0.0f,self.view.bounds.size.height - 100.0f)

     toPoint:CGPointMake(self.view.bounds.size.width,

                        self.view.bounds.size.height - 100.0f)];

    [self.animator addBehavior:collision];

#elif 1

    /* Create collision detection */

    UICollisionBehavior *collision = [[UICollisionBehavioralloc]

                                     initWithItems:self.squareViews];

    [collision

     addBoundaryWithIdentifier:kBottomBoundary

     fromPoint:CGPointMake(0.0f,self.view.bounds.size.height - 100.0f)

     toPoint:CGPointMake(self.view.bounds.size.width,

                        self.view.bounds.size.height -100.0f)];

    collision.collisionDelegate =self;

    collision.collisionMode =UICollisionBehaviorModeEverything;

//    typedef NS_OPTIONS(NSUInteger, UICollisionBehaviorMode) {

//        UICollisionBehaviorModeItems        = 1 << 0,//只检测方块之间的碰撞,结果都溜出屏幕

//        UICollisionBehaviorModeBoundaries   = 1 << 1,//只检测边界碰撞,结果所有方块都一下子到边界了

//        UICollisionBehaviorModeEverything   = NSUIntegerMax  //检测所有,结果方块在边界处叠起来了

//    } NS_ENUM_AVAILABLE_IOS(7_0);

    [self.animatoraddBehavior:collision];

#endif

}

- (void)collisionBehavior:(UICollisionBehavior*)paramBehavior

      beganContactForItem:(id <UIDynamicItem>)paramItem

   withBoundaryIdentifier:(id <NSCopying>)paramIdentifier

                  atPoint:(CGPoint)paramPoint{

   NSString *identifier = (NSString *)paramIdentifier;

   if ([identifier isEqualToString:kBottomBoundary]){

        [UIViewanimateWithDuration:1.0fanimations:^{

           UIView *view = (UIView *)paramItem;

            view.backgroundColor = [UIColorredColor];

            view.alpha =0.0f;

            view.transform =CGAffineTransformMakeScale(2.0f,2.0f);

        }completion:^(BOOL finished) {

           UIView *view = (UIView *)paramItem;

            [paramBehaviorremoveItem:paramItem];

            [viewremoveFromSuperview];

        }];

    }

}


@end


初始时,15个方块掉下来叠在一起,然后最下面一个变淡消失,上面的所有方块往下掉一格。到后面方块柱倒下,所有方块很快消失



2.3. Animating Your UI Components with a Push


#import "ViewController2_3.h"


@interface ViewController2_3 ()

@property (nonatomic,strong) UIView *squareView;

@property (nonatomic,strong) UIDynamicAnimator *animator;

@property (nonatomic,strong) UIPushBehavior *pushBehavior;


@end


@implementation ViewController2_3


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

   self = [superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil];

   if (self) {

        // Custom initialization

    }

    return self;

}


- (void)viewDidLoad

{

    [superviewDidLoad];

// Do any additional setup after loading the view.

}


- (void)didReceiveMemoryWarning

{

    [superdidReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


- (void)viewDidAppear:(BOOL)animated{

    [superviewDidAppear:animated];

    [selfcreateGestureRecognizer];

    [selfcreateSmallSquareView];

    [selfcreateAnimatorAndBehaviors];

}


- (void) createGestureRecognizer{

   UITapGestureRecognizer *tapGestureRecognizer =

    [[UITapGestureRecognizeralloc] initWithTarget:self

                                           action:@selector(handleTap:)];

    [self.viewaddGestureRecognizer:tapGestureRecognizer];

}


- (void) createSmallSquareView{self.squareView =

    [[UIViewalloc] initWithFrame:

     CGRectMake(0.0f,0.0f, 80.0f,80.0f)];

    self.squareView.backgroundColor = [UIColorgreenColor];

    self.squareView.center =self.view.center;

    [self.viewaddSubview:self.squareView];

}


- (void) createAnimatorAndBehaviors{

    self.animator = [[UIDynamicAnimatoralloc]

                    initWithReferenceView:self.view];

    /* Create collision detection */

    UICollisionBehavior *collision = [[UICollisionBehavioralloc]

                                     initWithItems:@[self.squareView]];

    collision.translatesReferenceBoundsIntoBoundary =YES;

    self.pushBehavior = [[UIPushBehavioralloc]

                        initWithItems:@[self.squareView]

                         mode:UIPushBehaviorModeContinuous];

    [self.animatoraddBehavior:collision];

    [self.animatoraddBehavior:self.pushBehavior];

}


- (void) handleTap:(UITapGestureRecognizer *)paramTap{

    /* Get the angle between the center of the square view

     and the tap point */

   CGPoint tapPoint = [paramTap locationInView:self.view];

   CGPoint squareViewCenterPoint = self.squareView.center;

    /* Calculate the angle between the center point of the square view and

     the tap point to find out the angle of the push

     Formula for detecting the angle between two points is:

     arc tangent 2((p1.x - p2.x), (p1.y - p2.y)) */

   CGFloat deltaX = tapPoint.x - squareViewCenterPoint.x;

   CGFloat deltaY = tapPoint.y - squareViewCenterPoint.y;

   CGFloat angle = atan2(deltaY, deltaX);

    [self.pushBehaviorsetAngle:angle];

    /* Use the distance between the tap point and the center of our square

     view to calculate the magnitude of the push

     Distance formula is:

     square root of ((p1.x - p2.x)^2 + (p1.y - p2.y)^2) */

   CGFloat distanceBetweenPoints =

   sqrt(pow(tapPoint.x - squareViewCenterPoint.x,2.0) +

        pow(tapPoint.y - squareViewCenterPoint.y,2.0));

    [self.pushBehaviorsetMagnitude:distanceBetweenPoints / 200.0f];

}


@end



点一点任何地方会对方块产生一个拉力


2.4. Attaching Multiple Dynamic Items to Each Other


#import "ViewController2_4.h"


@interface ViewController2_4 ()

@property (nonatomic,strong) UIView *squareView;

@property (nonatomic,strong) UIView *squareViewAnchorView;

@property (nonatomic,strong) UIView *anchorView;

@property (nonatomic,strong) UIDynamicAnimator *animator;

@property (nonatomic,strong) UIAttachmentBehavior *attachmentBehavior;


@end


@implementation ViewController2_4


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

   self = [superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil];

   if (self) {

        // Custom initialization

    }

    return self;

}


- (void)viewDidLoad

{

    [superviewDidLoad];

// Do any additional setup after loading the view.

}


- (void)didReceiveMemoryWarning

{

    [superdidReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


- (void)viewDidAppear:(BOOL)animated{

    [superviewDidAppear:animated];

    [selfcreateGestureRecognizer];

    [selfcreateSmallSquareView];

    [selfcreateAnchorView];

    [selfcreateAnimatorAndBehaviors];

}


- (void) createSmallSquareView{self.squareView =

    [[UIViewalloc] initWithFrame:

     CGRectMake(0.0f,0.0f, 80.0f,80.0f)];

    self.squareView.backgroundColor = [UIColorgreenColor];

    self.squareView.center =self.view.center;

    self.squareViewAnchorView = [[UIViewalloc] initWithFrame:

                                CGRectMake(60.0f,0.0f, 20.0f,20.0f)];

    self.squareViewAnchorView.backgroundColor = [UIColorbrownColor];

    [self.squareViewaddSubview:self.squareViewAnchorView];

    [self.viewaddSubview:self.squareView];

}


- (void) createAnchorView{

    self.anchorView = [[UIViewalloc] initWithFrame:

                      CGRectMake(120.0f,120.0f, 20.0f,20.0f)];

    self.anchorView.backgroundColor = [UIColorredColor];

    [self.viewaddSubview:self.anchorView];

}


- (void) createGestureRecognizer{

   UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizeralloc] initWithTarget:selfaction:@selector(handlePan:)];

    [self.viewaddGestureRecognizer:panGestureRecognizer];

}

- (void) createAnimatorAndBehaviors{

    self.animator = [[UIDynamicAnimatoralloc]

                    initWithReferenceView:self.view];

    /* Create collision detection */

    UICollisionBehavior *collision = [[UICollisionBehavioralloc]

                                     initWithItems:@[self.squareView]];

    collision.translatesReferenceBoundsIntoBoundary =YES;

    self.attachmentBehavior = [[UIAttachmentBehavioralloc]

                              initWithItem:self.squareView

//                               point:self.squareViewAnchorView.center

                              attachedToAnchor:self.anchorView.center];

    [self.animatoraddBehavior:collision];

    [self.animatoraddBehavior:self.attachmentBehavior];

}


- (void) handlePan:(UIPanGestureRecognizer *)paramPan{

   CGPoint tapPoint = [paramPan locationInView:self.view];

    [self.attachmentBehaviorsetAnchorPoint:tapPoint];

   self.anchorView.center = tapPoint;

}


@end



红色的小方块跟着鼠标走,绿色方块跟着红色方块


2.5. Adding a Dynamic Snap Effect to Your UI Components



#import "ViewController2_5.h"


@interface ViewController2_5 ()

@property (nonatomic,strong) UIView *squareView;

@property (nonatomic,strong) UIDynamicAnimator *animator;

@property (nonatomic,strong) UISnapBehavior *snapBehavior;


@end


@implementation ViewController2_5


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

   self = [superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil];

   if (self) {

        // Custom initialization

    }

    return self;

}


- (void)viewDidLoad

{

    [superviewDidLoad];

// Do any additional setup after loading the view.

}


- (void)didReceiveMemoryWarning

{

    [superdidReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


- (void)viewDidAppear:(BOOL)animated{

    [superviewDidAppear:animated];

    [selfcreateGestureRecognizer];

    [selfcreateSmallSquareView];

    [selfcreateAnimatorAndBehaviors];

}


- (void) createGestureRecognizer{

    UITapGestureRecognizer *tap = [[UITapGestureRecognizeralloc]

                                  initWithTarget:self

                                  action:@selector(handleTap:)];

    [self.viewaddGestureRecognizer:tap];

}

- (void) createSmallSquareView{self.squareView =

    [[UIViewalloc] initWithFrame:

     CGRectMake(0.0f,0.0f, 80.0f,80.0f)];

    self.squareView.backgroundColor = [UIColorgreenColor];

    self.squareView.center =self.view.center;

    [self.viewaddSubview:self.squareView];

}


- (void) createAnimatorAndBehaviors{self.animator = [[UIDynamicAnimatoralloc]

                                                     initWithReferenceView:self.view];

    /* Create collision detection */

    UICollisionBehavior *collision = [[UICollisionBehavioralloc]

                                     initWithItems:@[self.squareView]];

    collision.translatesReferenceBoundsIntoBoundary =YES;

    [self.animatoraddBehavior:collision];

    /* For now, snap the square view to its current center */

    self.snapBehavior = [[UISnapBehavioralloc]

                        initWithItem:self.squareView

                        snapToPoint:self.squareView.center];

    self.snapBehavior.damping = 0.5f; /* Medium oscillation */

    [self.animatoraddBehavior:self.snapBehavior];

}


- (void) handleTap:(UITapGestureRecognizer *)paramTap{

    /* Get the angle between the center of the square view

     and the tap point */

   CGPoint tapPoint = [paramTap locationInView:self.view];

   if (self.snapBehavior !=nil){

        [self.animatorremoveBehavior:self.snapBehavior];

    }

    self.snapBehavior = [[UISnapBehavioralloc] initWithItem:self.squareView

                                                snapToPoint:tapPoint];

    self.snapBehavior.damping = 1.5f; /* Medium oscillation */

    [self.animatoraddBehavior:self.snapBehavior];

}


@end


你点到哪里,它就以一种很“酷”的方式移到你点的地方,下图是移动过程中的一帧



2.6. Assigning Characteristics to Your Dynamic Effects

#import "ViewController2_6.h"


@interface ViewController2_6 ()

@property (nonatomic,strong) UIDynamicAnimator *animator;

@end


@implementation ViewController2_6


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

   self = [superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil];

   if (self) {

        // Custom initialization

    }

    return self;

}


- (void)viewDidLoad

{

    [superviewDidLoad];

// Do any additional setup after loading the view.

    [selftestDynamicItem];

}


- (void)didReceiveMemoryWarning

{

    [superdidReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


- (UIView *) newViewWithCenter:(CGPoint)paramCenter

               backgroundColor:(UIColor *)paramBackgroundColor{

   UIView *newView =

    [[UIViewalloc] initWithFrame:

     CGRectMake(0.0f,0.0f, 50.0f,50.0f)];

    newView.backgroundColor = paramBackgroundColor;

    newView.center = paramCenter;

   return newView;

}


-(void)testDynamicItem

{

   UIView *topView = [selfnewViewWithCenter:CGPointMake(100.0f,0.0f)

                             backgroundColor:[UIColorgreenColor]];

   UIView *bottomView = [selfnewViewWithCenter:CGPointMake(100.0f,50.0f)

                                backgroundColor:[UIColorredColor]];

    [self.viewaddSubview:topView];

    [self.viewaddSubview:bottomView];

    

    self.animator = [[UIDynamicAnimatoralloc]

                    initWithReferenceView:self.view];

    /* Create gravity */

    UIGravityBehavior *gravity = [[UIGravityBehavioralloc]

                                 initWithItems:@[topView, bottomView]];

    [self.animatoraddBehavior:gravity];

    

    /* Create collision detection */

    UICollisionBehavior *collision = [[UICollisionBehavioralloc]

                                     initWithItems:@[topView, bottomView]];

    collision.translatesReferenceBoundsIntoBoundary =YES;

    [self.animatoraddBehavior:collision];

    

    /* Now specify the elasticity of the items */

    UIDynamicItemBehavior *moreElasticItem = [[UIDynamicItemBehavioralloc]

                                             initWithItems:@[bottomView]];

    moreElasticItem.elasticity =1.0f;

    [self.animatoraddBehavior:moreElasticItem];


    UIDynamicItemBehavior *lessElasticItem = [[UIDynamicItemBehavioralloc]

                                             initWithItems:@[topView]];

    lessElasticItem.elasticity =0.5f;

    [self.animatoraddBehavior:lessElasticItem];

}


@end




绿色比较没弹性,很快就停下来了,红色弹性很好,弹了很久



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值