在研究“如何在移动的 UIImageView 上检测触摸事件?”时 我遇到了几个答案,并尝试将它们实施到我的应用程序中。我遇到的任何事情似乎都不起作用。我将解释我正在尝试做什么,然后发布我的代码。任何想法,建议,评论或答案都表示赞赏!
我的应用程序有几张卡片从左到右在屏幕上浮动。这些卡片有各种颜色,游戏的目标是将卡片向下拖动到颜色相似的对应容器中。如果用户没有足够快地触摸和拖动卡片,卡片将简单地从屏幕上飘出并且会丢失积分。正确容器中包含的卡片越多,得分就越高。
我使用核心动画编写了代码,让我的卡片从左到右浮动。这行得通。但是,当尝试触摸卡片并将其拖向容器时,它没有正确检测到我正在触摸卡片的 UIImageView。
为了测试我是否正确实现了移动卡片的代码,我还编写了一些代码允许移动非移动卡片。在这种情况下,我的触摸被检测到并相应地采取行动。
为什么我只能与固定卡片互动?在研究了很多之后,似乎代码:
options:UIViewAnimationOptionAllowUserInteraction
是让我的移动 UIImages 被检测到的关键因素。但是我试过这似乎没有任何效果。
我可能做错的另一件事是没有正确使用正确的表示层。我已经在我的项目中添加了这样的代码,而且我也只适用于非移动对象:
UITouch *t = [touches anyObject];
UIView *myTouchedView = [t view];
CGPoint thePoint = [t locationInView:self.view];
if([_card.layer.presentationLayer hitTest:thePoint])
{
NSLog(@"You touched a Card!");
}
else{
NSLog(@"backgound touched");
}
在尝试了这些类型的事情之后,我陷入了困境。这是我的代码,可以更全面地理解这一点:
#import "RBViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface RBViewController ()
@property (nonatomic, strong) UIImageView *card;
@end
@implementation RBViewController
- (void)viewDidLoad
{
srand(time (NULL)); // will be used for random colors, drift speeds, and locations of cards
[super viewDidLoad];
[self setOutFirstCardSet]; // this sends out 4 floating cards across the screen
// the following creates a non-moving image that I can move.
_card = [[UIImageView alloc] initWithFrame:CGRectMake(400,400,100,100)];
_card.image = [UIImage imageNamed:@"goodguyPINK.png"];
_card.userInteractionEnabled = YES;
[self.view addSubview:_card];
}
以下方法从屏幕左侧的随机位置发出卡片,并使用核心动画使卡片在屏幕上漂移。请注意卡片的颜色和漂移的速度也会随机生成。
-(void) setOutFirstCardSet
{
for(int i=1; i < 5; i++) // sends out 4 shapes
{
CGRect cardFramei;
int startingLocation = rand() % 325;
CGRect cardOrigini = CGRectMake(-100,startingLocation + 37, 92, 87);
cardFramei.size = CGSizeMake(92, 87);
CGPoint origini;
origini.y = startingLocation + 37;
origini.x = 1200;
cardFramei.origin = origini;
_card.userInteractionEnabled = YES;
_card = [[UIImageView alloc] initWithFrame:cardOrigini];
int randomColor = rand() % 7;
if(randomColor == 0)
{
_card.image = [UIImage imageNamed:@"goodguy.png"];
}
else if (randomColor == 1)
{
_card.image = [UIImage imageNamed:@"goodguyPINK.png"];
}
else if (randomColor == 2)
{
_card.image = [UIImage imageNamed:@"goodGuyPURPLE.png"];
}
else if (randomColor == 3)
{
_card.image = [UIImage imageNamed:@"goodGuyORANGE.png"];
}
else if (randomColor == 4)
{
_card.image = [UIImage imageNamed:@"goodGuyLightPINK.png"];
}
else if (randomColor == 5)
{
_card.image = [UIImage imageNamed:@"goodGuyBLUE.png"];
}
else if (randomColor == 6)
{
_card.image = [UIImage imageNamed:@"goodGuyGREEN.png"];
}
_card.userInteractionEnabled = YES; // this is also written in my viewDidLoad method
[[_card.layer presentationLayer] hitTest:origini]; // not really sure what this does
[self.view addSubview:_card];
int randomSpeed = rand() % 20;
int randomDelay = rand() % 2;
[UIView animateWithDuration:randomSpeed + 10
delay: randomDelay + 4
options:UIViewAnimationOptionAllowUserInteraction // here is the method that I thought would allow me to interact with the moving cards. Not sure why I can't
animations: ^{
_card.frame = cardFramei;
}
completion:NULL];
}
}
请注意,以下方法是我放置 CALayer 并点击测试信息的地方。我不确定我是否正确执行此操作。
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *t = [touches anyObject];
UIView *myTouchedView = [t view];
CGPoint thePoint = [t locationInView:self.view];
thePoint = [self.view.layer convertPoint:thePoint toLayer:self.view.layer.superlayer];
CALayer *theLayer = [self.view.layer hitTest:thePoint];
if([_card.layer.presentationLayer hitTest:thePoint])
{
NSLog(@"You touched a Shape!"); // This only logs when I touch a non-moving shape
}
else{
NSLog(@"backgound touched"); // this logs when I touch the background or an moving shape.
}
if(myTouchedView == _card)
{
NSLog(@"Touched a card");
_boolHasCard = YES;
}
else
{
NSLog(@"Didn't touch a card");
_boolHasCard = NO;
}
}
我希望以下方法适用于移动形状。它仅适用于非移动形状。许多答案说要触摸询问该卡来自哪个班级。截至目前,我所有的卡片都属于同一类(viewController 类)。当试图让卡片成为他们自己的类时,我无法让该视图出现在我的主后台控制器上。我必须有来自不同类别的各种卡片才能使用它,还是我可以让它在不需要这样做的情况下工作?
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
if([touch view]==self.card)
{
CGPoint location = [touch locationInView:self.view];
self.card.center=location;
}
}
如果用户开始移动卡片然后抬起卡片,则下一个方法会重置卡片的移动。
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if(_boolHasCard == YES)
{
[UIView animateWithDuration:3
delay: 0
options:UIViewAnimationOptionAllowUserInteraction
animations: ^{
CGRect newCardOrigin = CGRectMake(1200,_card.center.y - 92/2, 92, 87);
_card.frame = newCardOrigin;
}
completion:NULL];
}
}
@end