使按钮在屏幕上移动并记录手指手势的准确性

时间:2017-12-06 01:53:46

标签: ios objective-c button

我正在尝试创建一个应用程序,用户必须在屏幕上拖动手指。每次用户到达点时,它都会移动到下一个点(总共有5个等距点,具有特定坐标)。

手指描绘的路径的长度记录在每两个点之间,存储到数组中并且最终平均值,以评估用户的准确性(将他自己的路径与理想的最短路径进行比较)。

     
-(IBAction)button1Clicked:(UIButton *)sender {
    CGRect buttonFrame = sender.frame;

    int dotX = arc4random() % (int)(1000 - buttonFrame.size.width);
    int dotY = arc4random() % (int)(self.view.frame.size.height - buttonFrame.size.height);

    buttonFrame.origin.x = dotX;
    buttonFrame.origin.y = dotY;
    [sender setFrame:buttonFrame];
    NSLog(@"x = %f, y = %f", self.button1.frame.origin.x, self.button1.frame.origin.y);
}

我尝试使用存储在数组中的几个按钮以编程方式添加按钮,但也直接从故事板中添加按钮,我仍然没有想出哪个是应用程序执行它的意思的最佳方式

我的编码知识仍然很差,我只是设法创建一个带点状按钮的应用程序,必须点击(内部触摸)才能在屏幕上移动,当用户按下时它会移动到iPad屏幕上的随机点。相反,希望按钮在特定路径上移动一段时间,直到代码停止运行并且结果被平均(我可能需要将一些代码放在“for”循环中),并且手势应该触摸拖动内部而不是触地。 如果有人能帮助我给我一些提示,那就太好了!

1 个答案:

答案 0 :(得分:2)

我认为你应该只需要添加一个按钮。创建一个NSMutableDictionary数组,其中包含您希望用户导航到的每个点的值,包括x和y坐标,此坐标与最后一个坐标之间的最小距离,以及此坐标与最后一个坐标之间的实际距离坐标。以下设置应该适合您,但未经测试:

存储您的坐标集: 存储坐标集的方式取决于您拥有的坐标集数量以及每个坐标集合的坐标数量。如果你只有几组坐标,你就可以像我这里一样在代码中编写它们。如果你有很多坐标集,你很可能想要创建一个你将存储在你的包中的文件,并在需要的地方访问它,有很多与此过程相关的SO问题。

#import "ViewController.h"

@interface ViewController (){
    NSMutableArray *values;
    NSInteger buttonCount;
    __weak IBOutlet UIButton *button;
    BOOL hasStarted;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    UIGestureRecognizer *gestureRecognizer = [[UIGestureRecognizer alloc] init];
    [gestureRecognizer setEnabled:YES];
    [gestureRecognizer setDelegate:self];
    [self.view addGestureRecognizer:gestureRecognizer];

    button.hidden = true;

    buttonCount = 0;
    values = [[NSMutableArray alloc]init];
    [self generateValuesArrayWithCoordiantes];
}

-(void)generateValuesArrayWithCoordiantes{
    // for every number between 0 and 20, create an nsdictionary with your desired values for x and y
    CGPoint lastCoord = CGPointZero;
    // you need to have your set of coordinates stored somewhere, so that they can put into the button values dictionary
    // here is an array of dictionary, with an x and y number for each array value, you will require 20 rows, one for each set of coords

    NSArray *coords = @[@{@"x":@317, @"y":@100},
                        @{@"x":@200, @"y":@250},
                        @{@"x":@120, @"y":@400},
                        @{@"x":@80, @"y":@380}];

    for (int i = 0; i<20; i++) {
        NSMutableDictionary *buttonValues = [[NSMutableDictionary alloc]init];

        // get the required coords from your coords array
        NSDictionary *currentCoord = [coords objectAtIndex:i];
        [buttonValues setValue:[currentCoord valueForKey:@"x"] forKey:@"x"];
        [buttonValues setValue:[currentCoord valueForKey:@"y"] forKey:@"y"];

        // set the distance travelled to 0. this will be updated as your view detects touches moved
        [buttonValues setValue:[NSNumber numberWithInt:0] forKey:@"distanceTravelled"];

        if (i>0) {
            // calculate the minimum distance required to get from this point to the previous point. not required for the first point
            CGFloat minDistance = [self distanceBetween:CGPointMake([[currentCoord valueForKey:@"x"]floatValue], [[currentCoord valueForKey:@"y"]floatValue]) and:lastCoord];
            [buttonValues setValue:[NSNumber numberWithFloat:minDistance] forKey:@"minDistance"];
        }
        lastCoord = CGPointMake([[currentCoord valueForKey:@"x"]floatValue], [[currentCoord valueForKey:@"y"]floatValue]);
        [values addObject:buttonValues];
    }
}


-(IBAction)button1Clicked:(UIButton *)sender {
    if (!hasStarted) {
        NSLog(@"It Has Begun");
        hasStarted = true;
    }
    buttonCount = buttonCount + 1;
    if (buttonCount == 20){
        // The button has been clicked 20 times, compare the minDistance of the dictionaries, to the actualDistance of the dictionaries
        NSLog(@"We are done");
        return;
    }
    //get the last frame of the button
    CGRect lastFrame = sender.frame;

    NSMutableDictionary *nextButtonValues = [values objectAtIndex:buttonCount];

    CGRect nextFrame = CGRectMake([[nextButtonValues valueForKey:@"x"]floatValue], [[nextButtonValues valueForKey:@"y"]floatValue], lastFrame.size.width, lastFrame.size.height);

    [sender setFrame:nextFrame];
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    button.hidden = false;
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    // get this and last touch location and the distance moved between them
    UITouch *touch = [touches anyObject];
    CGPoint touchLocation = [touch locationInView:self.view];
    CGPoint lastLocation = [touch previousLocationInView:self.view];
    CGFloat distanceMoved = [self distanceBetween:touchLocation and:lastLocation];

    //NSLog(@"MOVED %.2f", distanceMoved);

    // get the current course from values, and update the distanceTravelled to include the distance moved
    NSMutableDictionary *currentCourse = [values objectAtIndex:buttonCount];
    CGFloat courseTravelled = [[currentCourse valueForKey:@"distanceTravelled"]floatValue];
    [currentCourse setValue:[NSNumber numberWithFloat:courseTravelled + distanceMoved] forKey:@"distanceTravelled"];

    // detect if the touch is inside the button frame
    for (UITouch *t in touches) {
        CGPoint touchPoint = [t locationInView:self.view];

        CGPoint testPoint = [self.view convertPoint:touchPoint toView:button];
        if ([button pointInside:testPoint withEvent:event]) {
            [self button1Clicked:button];
            return;
        }
    }
}

-(CGFloat)distanceBetween:(CGPoint)point1 and:(CGPoint)point2{
    CGFloat xDist = (point1.x - point2.x);
    CGFloat yDist = (point1.y - point2.y);
    return sqrt((xDist * xDist) + (yDist * yDist));
}

@end

当视图检测到初始触摸时,该按钮将被取消隐藏,游戏将开始