关闭

[置顶] iOS动力学UIDynamic讲解(二)

标签: ios7UIDynamicbox2d动力学运动仿真
520人阅读 评论(0) 收藏 举报

       之前我们接触了UIDynamic中的重力行为和碰撞行为,都比较好理解。今天我们来看另外两个行为:吸附行为(捕捉行为)UISnapBehavior 附着行为UIAttachmentBehavior

       从一个简单的Demo开始

       先看看效果图

这个项目展示的是两个视图View通过一根线连接起来的运动模拟,正方形物体可以随意摆动和旋转,触摸屏幕可带动两个物体一起运动,这是个很好的将吸附行为附着行为结合的例子

下面来看具体代码:

@implementation ViewController
{
    
    UIDynamicAnimator     *_animator;    //物理仿真器
    UIGravityBehavior     *_gravity;     //重力行为
    UICollisionBehavior   *_collision;   //碰撞行为
    UISnapBehavior        *_snap;        //吸附(捕捉)行为
    UIAttachmentBehavior  *_attach;      //附着行为
    
    UIView              *_view1;
    UIView              *_view2;
    
    BackView            *_backView;    //用来作为仿真器视图容器范围
    CADisplayLink       *_link;
}


- (void)viewDidLoad
{
    
    [super viewDidLoad];
    
    
    _backView = [[BackView alloc] initWithFrame:self.view.bounds];
    _view1 = [[UIView alloc] initWithFrame:CGRectMake(100, 50, 50, 50)];
    _view2 = [[UIView alloc] initWithFrame:CGRectMake(100, 150, 50, 50)];
    
    
    _backView.backgroundColor = [UIColor whiteColor];
    _view1.backgroundColor = [UIColor blueColor];
    _view1.layer.cornerRadius = 25.0;
    _view2.backgroundColor = [[UIColor greenColor] colorWithAlphaComponent:0.5];


    [self.view addSubview:_backView];
    [_backView addSubview:_view1];
    [_backView addSubview:_view2];

    

    //初始化仿真器
    _animator = [[UIDynamicAnimator alloc] initWithReferenceView:_backView];
    
    //添加重力行为
    _gravity = [[UIGravityBehavior alloc] initWithItems:nil];
    [_gravity addItem:_view2];
    
    // 添加碰撞行为
    _collision = [[UICollisionBehavior alloc] initWithItems:nil];
    _collision.translatesReferenceBoundsIntoBoundary = YES;
    [_collision addItem:_view1];
    [_collision addItem:_view2];

    //添加吸附行为(捕捉行为),意思是让物体吸附到某一点上
    _snap = [[UISnapBehavior alloc] initWithItem:_view1 snapToPoint:CGPointMake(125, 125)];
    _snap.damping = 1.0;

    //添加附着行为,让_view2视图附着在_view1周围(两物体附着的距离取决于它们的初始位置的距离)
    _attach = [[UIAttachmentBehavior alloc] initWithItem:_view1 attachedToItem:_view2];
    _attach.damping = 0.1;    //弹力
    _attach.frequency = 1.0;  //频率
    
    
    [_animator addBehavior:_gravity];
    [_animator addBehavior:_collision];
    [_animator addBehavior:_snap];
    [_animator addBehavior:_attach];
    
    //添加runloop便于绘制直线
    _link = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)];
    [_link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
    
}


//此方法会在程序绘制每帧时调用一次,再调用backView的drawRect方法绘制线条

-(void)update
{
    _backView.point1 = _view1.center;
    _backView.point2 = _view2.center;
    [_backView setNeedsDisplay];
}


//屏幕触摸事件,利用吸附行为让圆形物体跟随用户手指移动

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    
    CGPoint pt = [[touches anyObject] locationInView:self.view];
  

   //要先移除原来的吸附行为, 不然物体无法运动

    [_animator removeBehavior:_snap];
    _snap = [[UISnapBehavior alloc] initWithItem:_view1 snapToPoint:pt];
    _snap.damping = 1.0;
    [_animator addBehavior:_snap];

}


-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    
    CGPoint pt = [[touches anyObject] locationInView:self.view];
    [_animator removeBehavior:_snap];
    _snap = [[UISnapBehavior alloc] initWithItem:_view1 snapToPoint:pt];
    _snap.damping = 1.0;
    [_animator addBehavior:_snap];
    
}


_backView内代码:

@property(nonatomic, assign) CGPoint point1;
@property(nonatomic, assign) CGPoint point2;

-(void)drawRect:(CGRect)rect
{
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGContextSetStrokeColorWithColor(context, [UIColor purpleColor].CGColor);
    CGContextSetLineWidth(context, 4.0);
    
    CGContextMoveToPoint(context, _point1.x, _point1.y);
    CGContextAddLineToPoint(context, _point2.x, _point2.y);
    
    CGContextStrokePath(context);
 
}







0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:10840次
    • 积分:156
    • 等级:
    • 排名:千里之外
    • 原创:4篇
    • 转载:0篇
    • 译文:0篇
    • 评论:3条
    文章分类
    文章存档
    最新评论