0

我创建了一个类似于 Scrabble 的益智游戏。

这是布局:

1 2 3 4

5 6 7 8

9 10 11 12

13 14 15 16

我的问题是什么?

我的问题是当我从 1 和方向开始触摸到 12 时,如果触摸并缓慢拖动则没有问题,但是当快速拖动时,我只能到 1、6、12 或 1、7、12。缺少一个数字。

如何确保所有路径号都被选中?

我正在使用touch began,touch movedtouch ended检查坐标以找到正在触摸的数字。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];

UITouch *touch = [touches anyObject];
CGPoint currentTouchLocation = [touch locationInView:self.numberview];
if(!ispause && [time.text intValue] > 0){
    if(!isbegan && !isended){
        for(int i = 1; i <= 16; i++)
        {
            UIView *imageview = [self.numberview viewWithTag:i];
            if (CGRectContainsPoint(imageview.frame, currentTouchLocation))
            {
                isbegan = YES;
                isreverse = NO;
                if([[ischose objectAtIndex:i-1] boolValue] == 0)
                {
                    currentposition = imageview.tag;
                    positionvalue += pow(i, 3);
                    currentanswer += [self converter:[NSString stringWithFormat:@"%@", [allimagenumbers substringWithRange:NSMakeRange(i-1, 1)]]];
                    [ischose replaceObjectAtIndex:i-1 withObject:[NSNumber numberWithBool:YES]];
                    [self changeimage:@"selected"];
                }
                break;
            }
        }
    }
}
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesMoved:touches withEvent:event];

UITouch *touch = [touches anyObject];
CGPoint currentTouchLocation = [touch locationInView:self.numberview];

float gapX = image1.frame.size.width / 8;
float gapY = image1.frame.size.height / 8;

if(isbegan && !isended)
{
    if(currentTouchLocation.x >= 0 && currentTouchLocation.x <= self.numberview.frame.size.width && currentTouchLocation.y >= 0 && currentTouchLocation.y <= self.numberview.frame.size.height)
    {
        for(int i = 1; i <= 16; i++)
        {
            UIView *imageview = [self.numberview viewWithTag:i];
            if (CGRectContainsPoint(imageview.frame, currentTouchLocation))
            {
                if((currentTouchLocation.x >= imageview.frame.origin.x + gapX && currentTouchLocation.x < imageview.frame.origin.x + imageview.frame.size.width  - gapX) && (currentTouchLocation.y >= imageview.frame.origin.y  + gapY && currentTouchLocation.y < imageview.frame.origin.y + imageview.frame.size.height - gapY ))
                {
                    if([[ischose objectAtIndex:i-1] boolValue] == 0 && !isreverse)
                    {
                        currentposition = imageview.tag;
                        positionvalue += pow(i, 3);
                        currentanswer += [self converter:[NSString stringWithFormat:@"%@", [allimagenumbers substringWithRange:NSMakeRange(i-1, 1)]]];
                        [ischose replaceObjectAtIndex:i-1 withObject:[NSNumber numberWithBool:YES]];
                        [self changeimage:@"selected"];
                    }
                    else
                    {
                        if(currentposition != imageview.tag)
                        {
                            isreverse = YES;
                        }
                        else
                        {
                            isreverse = NO;
                        }
                    }
                    break;
                }
            }
        }
    }
    else
    {
        isended = YES;
        isoutofbound = YES;
        if(isbegan && isoutofbound)
            [self countinganswer];
    }
}
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesEnded:touches withEvent:event];
if(!isoutofbound)
{
    isended = YES;
    [self countinganswer];
}
else
    isoutofbound = NO;
}

-(void)changeimage:(NSString *)status{
if([status isEqualToString:@"default"])
{
    for(int i = 1; i <=16;i++)
    {
        UIImageView *imageview = (UIImageView*)[self.numberview viewWithTag:i];
        imageview.image = [UIImage imageNamed:[NSString stringWithFormat:@"stone%@", [allimagenumbers substringWithRange:NSMakeRange(i-1, 1)]]];
        [image1 setUserInteractionEnabled:YES];
    }
}
else if([status isEqualToString:@"correct"] || [status isEqualToString:@"selected"])
{
    for(int i = 1; i<= ischose.count; i++)
    {
        if([[ischose objectAtIndex:i-1] boolValue] == 1)
        {
            UIImageView *imageview = (UIImageView*)[self.numberview viewWithTag:i];
            imageview.image = [UIImage imageNamed:[NSString stringWithFormat:@"stone%@_correct", [allimagenumbers substringWithRange:NSMakeRange(i-1, 1)]]];
        }
    }
}
else if([status isEqualToString:@"wrong"] || [status isEqualToString:@"repeat"])
{
    for(int i = 1; i<= ischose.count; i++)
    {
        if([[ischose objectAtIndex:i-1] boolValue] == 1)
        {
            UIImageView *imageview = (UIImageView*)[self.numberview viewWithTag:i];
            imageview.image = [UIImage imageNamed:[NSString stringWithFormat:@"stone%@_wrong_repeat", [allimagenumbers substringWithRange:NSMakeRange(i-1, 1)]]];
        }
    }
}
}
4

2 回答 2

0

更新:

与您聊天时,您似乎已经解决了您的问题(UIImageView未检测到对您的一个对象的滑动)。看起来解决方案是一个独特的问题(即堆栈溢出语言中的高度“本地化”),与您的代码相关联,以创建您使用gap变量构建的缩小尺寸的“命中区域”。看起来该解决方案与touchesMovediOS API 或 iOS 系统性能没有任何关联。无论如何,我很高兴你解决了这个问题。

我在下面的原始答案基于发布的原始源代码,该代码对 16 个UIImageView对象中的每一个都重复了相同的逻辑。我只是在演示如何使用 aUIArray来显着简化该逻辑。我也使用UIPanGestureRecognizer,我认为它统一了代码,并且<UIKit/UIGestureRecognizerSubclass.h>可以取消手势,以防用户的手势“越界”。


原答案:

我假设您只是想在用户将手指拖过数字时构建一个图像数字数组。所以 ARC 代码可能看起来像:

//  NumberGameViewController.m

#import "NumberGameViewController.h"
#import <UIKit/UIGestureRecognizerSubclass.h>

@interface NumberGameViewController ()
{
    NSArray *images;
    NSMutableArray *results;
}
@end

@implementation NumberGameViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // if you build an array of your images, the logic to determine which image you're over is much easier

    images = @[self.image1, self.image2, self.image3, self.image4, self.image5, self.image6, self.image7, self.image8, self.image9, self.image10, self.image11, self.image12, self.image13, self.image14, self.image15, self.image16];

    // I know you used `touchesMoved` and the like, but I think gesture recognizers are a little easier

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
    [self.numberview addGestureRecognizer:pan];
}

- (NSInteger)determineImageNumber:(CGPoint)point
{
    for (NSInteger i = 0; i < [images count]; i++)
    {
        UIImageView *imageview = images[i];

        // I'm just going to see if the user's finger was over the number in question.
        // If you wanted more restrictive logic (e.g. 3/4ths of the frame), just adjust
        // adjust the frame variable here. 

        CGRect frame = imageview.frame;
        if (CGRectContainsPoint(frame, point))
            return i;
    }

    return -1;
}

- (void)handlePan:(UIGestureRecognizer *)gesture
{
    CGPoint location = [gesture locationInView:self.numberview];
    NSInteger imageNumber = [self determineImageNumber:location];
    static NSInteger lastImageNumber;

    if (gesture.state == UIGestureRecognizerStateBegan)
    {
        results = [[NSMutableArray alloc] init];
        if (imageNumber >= 0)
        {
            [results addObject:@(imageNumber)];
        }
    }
    else if (gesture.state == UIGestureRecognizerStateChanged)
    {
        if (imageNumber >= 0)
        {
            if (imageNumber != lastImageNumber)
            {
                // If you want to do some visual adjustment of the image you're over, do it
                // here.

                // add the image to our array of results

                [results addObject:@(imageNumber)];

                // if you want to do some additional validation (e.g. do you have 16 points,
                // has the user hit the same number twice, etc.), do that here
            }
        }

        // by the way, let's check to see if we're still within the numberview subview, and if
        // not, let's cancel the gesture

        if (!CGRectContainsPoint(self.numberview.bounds, location))
        {
            gesture.state = UIGestureRecognizerStateCancelled;
            return;
        }
    }
    else if ((gesture.state == UIGestureRecognizerStateEnded) || (gesture.state == UIGestureRecognizerStateCancelled) || (gesture.state == UIGestureRecognizerStateFailed))
    {
        // At this point you'd do any final validation of the user's response, to see if they
        // succeeded or not. I'm just displaying the results in the console

        NSLog(@"%@", results);
    }

    if (imageNumber >= 0)
        lastImageNumber = imageNumber;
}

@end
于 2012-11-19T08:20:00.257 回答
0
float gapX = image1.frame.size.width / 8;
float gapY = image1.frame.size.height / 8;

这是问题所在,所有图像之间都有一个间隙,所以当快速拖动时,它将是图像的外部

于 2012-11-20T03:46:31.173 回答