2017-02-18 73 views
0

對於一個任務,我必須創建一個符合下列條件的應用程序:iOS的Objective C的 - 創建UIViews與長按/在同一UIViews使用多個手勢

  1. 模擬等於質量球的彈性碰撞。
  2. 使用根視圖作爲舞臺來彈跳球。 a。根視圖通過放置新球響應長按。新球可以靜止或以初始速度運動。 b。競技場應該有一定的摩擦來減緩任何移動的球。
  3. 雙攻球刪除它
  4. 您可以按持有一球,拖動重新定位,並通過拖動並迅速將其釋放
  5. 一個球應該永遠是賽場之內,即輕彈它,它反彈當達到邊緣時返回。
  6. 球不應該重疊。也就是說,你實現了一個相當好的碰撞處理。

我相信我已經充分實現了1,2b,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

眼前的問題是,你是宣佈longPressRecog與本地範圍:

012對類級對象,它是一個不同的對象
UILongPressGestureRecognizer *longPressRecog = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)]; 

但是測試:

if ([sender isEqual:self.longPressRecog]) 

此測試失敗。

您可以通過實例化你的職業等級的對象,而不是在本地解決這個範圍的一個:

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

這將導致你找到的其他問題與您的代碼,但是你可以看到,有沒有問題手勢識別器本身。

+0

修復了這個問題。現在要解決我現在正在獲取的錯誤。使用斷點,似乎UIDynamicAnimator現在使我有一個NSInvalidArgumentException與[__NSPlaceHolderArray initWithObjects:count:]:試圖從對象插入零對象[1] 我不明白在這種情況下。 –