2017-02-18 19 views
0

Для задания, я должен создать приложение, которое отвечает следующим критериям:IOS Objective C - Создание UIViews с LongPress/Использование нескольких жестов на тех же UIViews

  1. Simulate упругих столкновений равных масс шаров.
  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 с локальным объемом:

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:]: попытка вставить объект nil из объектов [1] Я не понимаю этого в этом контексте. –