1

我在我的应用程序中使用 UIDynamics。我的应用程序有两个正方形。一个是固定的,另一个可以移动(通过应用平移手势)。当我试图碰撞它们时,它们不会碰撞。委托方法永远不会被调用。这是我的代码,我希望有人能指出问题所在。

    UIDynamicAnimator* animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
  UICollisionBehavior* collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.square1, self.square2]];
    collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
    [self.square1 addGestureRecognizer:pan];
    [collisionBehavior setCollisionMode:UICollisionBehaviorModeEverything];
    [animator addBehavior:collisionBehavior];
    collisionBehavior.collisionDelegate = self;
4

4 回答 4

1

当函数因 ARC 而结束时,您的 UIDynamicAnimator* 动画器将被销毁。这就是为什么您看不到任何动画的原因。让它成为一个实例变量,你会没事的。

于 2014-02-06T11:01:14.033 回答
1
  1. 将 animator 设为属性或实例变量。否则将在视图加载后被清除。
  2. 确保实现 UICollisionBehaviorDelegate 协议和相应的方法

这是我基于您的代码的作品实现。

界面:

#import <UIKit/UIKit.h>

@interface DynamicViewController : UIViewController<UICollisionBehaviorDelegate>

@property (strong, nonatomic) UIDynamicAnimator *animator;

@property (strong, nonatomic) UIPushBehavior *pushBehavior;

@end

执行:

@synthesize pushBehavior = _pushBehavior;
@synthesize animator = _animator;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIView *square1 = [[UIView alloc] initWithFrame:CGRectMake(100, 30, 30, 30)];
    square1.center = CGPointMake(150, 150);
    square1.backgroundColor = [UIColor greenColor];
    UIView *square2 = [[UIView alloc] initWithFrame:CGRectMake(100, 300, 30, 30)];
    square2.center = CGPointMake(250, 350);
    square2.backgroundColor = [UIColor redColor];
    [self.view addSubview:square1];
    [self.view addSubview:square2];

    _animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

    UICollisionBehavior* collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[square1, square2]];
    collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
    [collisionBehavior setCollisionMode:UICollisionBehaviorModeEverything];
    collisionBehavior.collisionDelegate = self;
    [_animator addBehavior:collisionBehavior];

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
    [square1 addGestureRecognizer:pan];
}

#pragma mark push behavior
- (void)handlePan:(UIPanGestureRecognizer *)gesture
{
    if(gesture.state == UIGestureRecognizerStateBegan){
        if (_pushBehavior) {
            [_animator removeBehavior:_pushBehavior];
        }
        _pushBehavior = [[UIPushBehavior alloc] initWithItems:@[gesture.view] mode:UIPushBehaviorModeContinuous];
        [_animator addBehavior:_pushBehavior];
    }

    CGPoint offset =[gesture translationInView:self.view];
    _pushBehavior.pushDirection = CGVectorMake(offset.x,offset.y);
    _pushBehavior.magnitude = sqrtf(offset.x * offset.x + offset.y * offset.y) / 50;
    if (gesture.state == UIGestureRecognizerStateEnded) {
        [_animator removeBehavior:_pushBehavior];
        _pushBehavior = nil;
    }
}

#pragma mark Colision delegate
- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p;
{
    NSLog(@"Colision Began");
}
- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2;
{
  NSLog(@"Colision End");
}
于 2014-01-28T07:28:33.153 回答
0

我认为 UIDynamics 存在一些错误(但不是 100% 肯定让我知道我是否错了)。在为 UIDynamicAnimator 和 UIGravityBehavior 创建实例变量之前,我无法进行动态工作。尝试将实例变量添加到类扩展中的 .m 文件中,如下所示:

UIDynamicAnimator* animator;
UICollisionBehavior* collisionBehavior;

并将前两行代码更改为:

animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.square1, self.square2]];

它应该有帮助。

于 2013-12-25T13:26:44.850 回答
0

您必须使用“addBoundaryWithIdentifier”为碰撞类指定边界,并从碰撞中移除非移动项目

于 2014-03-08T09:07:03.533 回答