Для задания, я должен создать приложение, которое отвечает следующим критериям:IOS Objective C - Создание UIViews с LongPress/Использование нескольких жестов на тех же UIViews
- Simulate упругих столкновений равных масс шаров.
- Используйте корень в качестве арены для отскока шаров. a. Корневой режим реагирует на длительное нажатие, помещая новый шар. Новый шар может быть неподвижным или с начальной скоростью. b. На арене должно быть некоторое трение, чтобы замедлить любой движущийся мяч.
- Двойное нажатие мяч удаляет его
- Вы можете нажать, чтобы держать мяч, перетащить, чтобы изменить его, и вылить его путем перетаскивания и отпускания его быстро
- Мяч всегда должен находиться на арене, то есть, он отскакивает назад при достижении края.
- Мячи не должны пересекаться. То есть вы реализуете достаточно хорошую обработку столкновений.
Я считаю, что я адекватно реализован 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
Это исправлено. Теперь исправить ошибки, которые я сейчас получаю. Используя точки останова, кажется, что UIDynamicAnimator теперь вызывает у меня NSInvalidArgumentException с [__NSPlaceHolderArray initWithObjects: count:]: попытка вставить объект nil из объектов [1] Я не понимаю этого в этом контексте. –