iOS Objective C - 使用LongPress创建UIViews /在相同的UIViews上使用多个手势

时间:2017-02-18 00:26:14

标签: ios objective-c iphone uigesturerecognizer

对于作业,我必须创建一个符合以下条件的应用程序:

  1. 模拟等质量球的弹性碰撞。
  2. 使用根视图作为竞技场弹跳球。 一个。根视图通过放置一个新球来响应长按。新球可以是静止的或具有初始速度。 湾竞技场应该有一些摩擦来减缓任何移动的球。
  3. 双击球将其删除
  4. 您可以按住一个球,拖动以重新定位,然后通过拖动并快速释放它来轻弹它
  5. 球应该始终位于竞技场内,即当它到达边缘时它会反弹。
  6. 球不应重叠。也就是说,您实现了相当好的碰撞处理。
  7. 我相信我已经充分实施了1,2,5,5和6.如果有人可以帮助我了解如何实施其余的,那就太棒了,但是现在我的主要问题如下:

    2a上。我希望能够通过长按屏幕来创建一个球。然后球应该出现在长按的位置。当只有一个球并且没有其他手势识别器时,我能够使这个工作。

    由于我实现了tapGestureRecognzier,因此长按识别器不再有效。我的应用程序运行,但只显示一个空白屏幕。似乎没有注册任何类型的触摸。没有球出现,但应用程序没有显示任何错误。

    所以,我认为手势识别器要么相互干扰,要么没有正确设置。

    我想要的是长按以创建一个球,然后每次长按都会在按下位置创建一个不同颜色的球。然后双击球将从屏幕上移除该球,使其不再与其他球相互作用。

    以下是我目前完成的代码:

    ViewController.h

     #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController <UICollisionBehaviorDelegate, UIGestureRecognizerDelegate>
    
    @end
    

    ViewController.m

    #import "ViewController.h"
    #import <QuartzCore/QuartzCore.h>
    
    @interface ViewController ()
    
    @property (nonatomic, strong) UILongPressGestureRecognizer *longPressRecog;
    @property (nonatomic, strong) UITapGestureRecognizer *tapRecog;
    @property (nonatomic, strong) UIDynamicAnimator *anim;
    @property (nonatomic, strong) UIView *orangeBall, *blueBall, *redBall, *greenBall, *blackBall;
    @property (nonatomic) CGPoint ballCenter;
    @property (nonatomic) int numOfBalls;
    
    -(void)physics;
    -(void)createBall;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        //Init Variables
        _numOfBalls = 0;
    
        // Prepare to handle Long Press to create ball object
        UILongPressGestureRecognizer *longPressRecog = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
        self.longPressRecog.minimumPressDuration = 1.0f;
        [longPressRecog setDelegate:self];
    
        [self.view addGestureRecognizer:longPressRecog];
    
        // Handle Double Tap to delete ball
        UITapGestureRecognizer *tapRecog = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)];
        [tapRecog setNumberOfTapsRequired:2];
        [tapRecog setDelegate:self];
        [self.orangeBall addGestureRecognizer:tapRecog];
        [self.blueBall addGestureRecognizer:tapRecog];
        //[self.redBall addGestureRecognizer:tapRecog];
        //[self.greenBall addGestureRecognizer:tapRecog];
        //[self.blackBall addGestureRecognizer:tapRecog];
    }
    
    // Handles Long Presses and creates a ball within the view
    - (void)longPress:(UILongPressGestureRecognizer *)sender {
        if ([sender isEqual:self.longPressRecog]) {
            if (sender.state == UIGestureRecognizerStateBegan) {
                [self createBall];
            }
        }
    }
    
    // Set Ball Attributes
    - (void)setOrangeBall {
        // Load ball view to screen
        self.orangeBall = [[UIView alloc] initWithFrame:CGRectMake(100.0, 100.0, 50.0, 50.0)];
        self.orangeBall.layer.cornerRadius = 25.0;
        self.orangeBall.backgroundColor = [UIColor orangeColor];
        self.orangeBall.layer.borderColor = [UIColor orangeColor].CGColor;
        self.orangeBall.layer.borderWidth = 0.0;
        //self.ballCenter = position;
        [self.view addSubview:self.orangeBall];
    
    }
    
    - (void)setBlueBall {
        // Load ball view to screen
        self.blueBall = [[UIView alloc] initWithFrame:CGRectMake(100.0, 100.0, 50.0, 50.0)];
        self.blueBall.layer.cornerRadius = 25.0;
        self.blueBall.backgroundColor = [UIColor blueColor];
        self.blueBall.layer.borderColor = [UIColor blueColor].CGColor;
        self.blueBall.layer.borderWidth = 0.0;
        //self.ballCenter = position;
        [self.view addSubview:self.blueBall];
    }
    
    
    // Create Balls
    - (void)createBall {
        if (_numOfBalls == 0) {
            [self setOrangeBall];
            _numOfBalls += 1;
        } else if (_numOfBalls == 1) {
            [self setBlueBall];
            _numOfBalls += 1;
        }
    
        // Begin animations
        self.anim = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
    
        // Init Gravity
        [self physics];
    }
    
    // Delete Balls
    - (void)deleteBall {
        [self.view removeFromSuperview];
    }
    
    // Gravity
    - (void)physics {
        // Collision Behavior -- Defines boundaries of view within which the ball must stay. If the ball hits a boundary, it will bounce off it.
        UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.orangeBall, self.blueBall, self.redBall, self.greenBall, self.blackBall]];
        collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
    
        [collisionBehavior addBoundaryWithIdentifier:@"TopOfView"
                                           fromPoint:CGPointMake(0., -self.view.bounds.size.height)
                                             toPoint:CGPointMake(self.view.bounds.size.width, -self.view.bounds.size.height)];
        [collisionBehavior addBoundaryWithIdentifier:@"BottomOfView"
                                           fromPoint:CGPointMake(0., self.view.bounds.size.height)
                                             toPoint:CGPointMake(self.view.bounds.size.width, self.view.bounds.size.height)];
        [collisionBehavior addBoundaryWithIdentifier:@"LeftOfView"
                                           fromPoint:CGPointMake(0., -self.view.bounds.size.height)
                                             toPoint:CGPointMake(0., self.view.bounds.size.height)];
        [collisionBehavior addBoundaryWithIdentifier:@"RightOfView"
                                           fromPoint:CGPointMake(self.view.bounds.size.width, -self.view.bounds.size.height)
                                             toPoint:CGPointMake(self.view.bounds.size.width, self.view.bounds.size.height)];
    
        collisionBehavior.collisionMode = UICollisionBehaviorModeEverything;
        collisionBehavior.collisionDelegate = self;
        [self.anim addBehavior:collisionBehavior];
    
    
        // Ball's physical atributes -- Determines how ball behaves such as its elasticity, amount of friction, collision behavior, etc.
        UIDynamicItemBehavior *ballPhysics = [[UIDynamicItemBehavior alloc] initWithItems:@[self.orangeBall, self.blueBall, self.redBall, self.greenBall, self.blackBall]];
        ballPhysics.elasticity = 0.80;
        ballPhysics.resistance = 0.50;
        ballPhysics.friction = 0.50;
        ballPhysics.allowsRotation = NO;
        [self.anim addBehavior:ballPhysics];
    }
    
    -(void)tapped:(UITapGestureRecognizer *)recognizer {
        [self deleteBall];
    }
    
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    
    @end
    

1 个答案:

答案 0 :(得分:1)

当前问题是您使用本地范围声明{{}}

longPressRecog

但是针对类级别对象进行测试,这是一个不同的对象:

UILongPressGestureRecognizer *longPressRecog = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];

此测试失败。

您可以通过实例化类级别对象而不是本地范围的对象来解决此问题:

if ([sender isEqual:self.longPressRecog])

这会让您发现代码存在其他问题,但您可以看到手势识别器本身没有问题。