我工作的一些基本的应用程序/实用工具/使用iPhone游戏得到它更好的抓地力。

我现在有一个设置,其中一个CGRect只要移动手指的动作,但我不希望CGRectboundsview外面去。

原始方法

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    startLocation = [touch locationInView:self];
    if (startLocation.x < 33){
        touchLocation.x = 33;
            //NSLog(@"Touch At:%f, %f", touchLocation.x, touchLocation.y);
        [self setNeedsDisplay];
    }
    if (startLocation.x > 288){
        touchLocation.x = 288;
            //NSLog(@"Touch At:%f, %f", touchLocation.x, touchLocation.y);
        [self setNeedsDisplay];
    }
    if (startLocation.y < 84){
        touchLocation.y = 84;
            //NSLog(@"Touch At:%f, %f", touchLocation.x, touchLocation.y);
        [self setNeedsDisplay];
    }
    if (startLocation.y > 460){
        touchLocation.y = 460;
            //NSLog(@"Touch At:%f, %f", touchLocation.x, touchLocation.y);
        [self setNeedsDisplay];
    }
    else {
        touchLocation = startLocation;
        [self setNeedsDisplay];
    }
}

问题

我已经试过这几种不同的方法,包括使用&&,使它只是一个声明。该boundaries显然是硬编码的,我不知道,手动设置touchLocation是要保持它在bounds的最佳方式。

这一切似乎愚蠢的,我什么时候可以很容易地self.view.bounds并得到边界CGRect。如何利用bounds的做到这一点?有没有更好的办法来防止它的发生不是手动设置touchLocation其他?我能以某种方式把一个硬性限制就可以了呢?

有关switch声明是什么?将这项工作比试图-ifs更好?


尝试

我现在正在试图利用@Brad戈斯的方法贴在下面,但它不工作?

Touch Started: (319.000000,350.000000)
Touch Result: (319.000000,350.000000)
Boundaries calculated: X:(0.000000,288.000000) Y(0.000000,328.000000)

接触开始的是实际的起始触摸。 触摸结果应当被改变的结果。

上面的日志中显示它的定义bounds以外,又名不工作。我不打算重新发布他写的代码,因为它是完全一样的。


尝试问题

我已经发现了这个问题。这是同一类型的情况如上,但因为它们是设置日志的单个值。

Touch Started: (293.000000,341.000000)
min x:288.000000
max x:293.000000
min y:328.000000
max y:341.000000
Touch Result: (293.000000,341.000000)
Boundaries calculated: X:(0.000000,288.000000) Y(0.000000,328.000000)

我还没有想通了,我只要我发现了它贴在这里。否则,我会忘记所有更新,添加呵。

我要回去看看到底发生了什么在每个可能的情况。


错误

发现了另一个问题,即计算从boundariessubtracts maximums的代码,但并不addminimums。这一点很重要,因为这是boundary是什么,从去关闭屏幕停止rect

maxX = b.origin.x + b.size.width/* - [box bounds].size.width */;
minX = b.origin.x/* + [box bounds].size.width */;
maxY = b.origin.y + b.size.height/* - [box bounds].size.height */;
minY = b.origin.y?/* + [box bounds].size.height */;

通过此固定,我可以继续在原问题的工作。


错误2

好的,我已修正的另一个问题。正在显示时,我加入到y值。我忘了把它添加到这个新的代码/提及。现在,该代码看起来是这样的:

maxX = b.origin.x + b.size.width/* - [box bounds].size.width */;
minX = b.origin.x/* + [box bounds].size.width */;
maxY = b.origin.y + b.size.height/* - [box bounds].size.height + 20*/;
minY = b.origin.y/* + [box bounds].size.height + 20*/;

被显示的圆的大小是一个64px CGRect的内侧,从而20px足以只显示拇指上方的圆。虽然这是固定的,但它仍然没有帮助解决我们原来的问题。

左上角:

Touch Started: (14.000000,20.000000)
min x:14.000000
max x:32.000000
min y:20.000000
max y:84.000000
Touch Result: (32.000000,84.000000)
Boundaries calculated: X:(32.000000,288.000000) Y(84.000000,276.000000)

它的工作原理,因为它应该,但我很困惑,为什么正确的价值观是走出MAX而不是MIN的。的东西在这里混合起来。

右上角:

Touch Started: (303.000000,21.000000)
min x:288.000000
max x:303.000000
min y:21.000000
max y:84.000000
Touch Result: (303.000000,84.000000)
Boundaries calculated: X:(32.000000,288.000000) Y(84.000000,276.000000)

它阻止我从MAX而不是MIN去关闭屏幕的顶部,再次。我仍然能飞离右,如上所示。

右下角:

Touch Started: (317.000000,358.000000)
min x:288.000000
max x:317.000000
min y:276.000000
max y:358.000000
Touch Result: (317.000000,358.000000)
Boundaries calculated: X:(32.000000,288.000000) Y(84.000000,276.000000)

它的失败上的两个方向。现在的实际值从MAX来了,最大值是从MIN到来。 WTF?

左下角:

Touch Started: (8.000000,354.000000)
min x:8.000000
max x:32.000000
min y:276.000000
max y:354.000000
Touch Result: (32.000000,354.000000)
Boundaries calculated: X:(32.000000,288.000000) Y(84.000000,276.000000)

预见的是,它仅工作了最小值。我仍然以什么这些功能所应该做的很迷茫。洞察将不胜感激!


解决!

我们的漫漫长路即将结束,谢天谢地。所以,因为我没有任何线索,这里是MINMAX做。这不是初始LLY明显,我由于是已经发生的混乱。

MAX(x,y) will output the larger of the two numbers
// MAX(13,37) = 37
MIN(x,y) will output the smallest of the two numbers
// MIN(13,37) = 13

因此,这是你必须做的正确使用这些功能在这种情况下什么:

1。计算最大和X和Y的最低值。

对于每个的最低值被计算为

view.origin + keepOnScreenRect.width  

每个的最高值被计算为

view.origin + view.size.height/width - keepOnScreenRect.height/width

不要忘了手指偏移!点击 如果你正在做什么,我所做的,并有keepOnScreenRect定位用户的手指稍上方,你应该只添加额外的偏移量Y的最大值,为Y的最小值是屏幕/视图的底部,这你身体无法比0去在较低

如果你想知道为什么这样做,这是因为用户无法通过他/她的手指看。

2。上touchesBegan:获取触摸的位置

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    startTouchLocation = [touch locationInView:self];
    NSLog(@"Touch Started: (%f,%f)", startTouchLocation.x, startTouchLocation.y);

3。应用数学约束:

首先,我们得到了MAX,或两者可能的最低值的最高值,根据我们的极限,minXstartTouchLocation,为X。这种计算在屏幕的左侧极限。这样做的结果被设定为currentTouchLocation

currentTouchLocation.x = MAX(minX, startTouchLocation.x);

其次,我们得到了MIN,或两者可能的最高值,最低值,根据我们的极限,maxXcurrentTouchLocation,为X。请注意,我们没有使用原来的触摸的位置,而是所导致的MAX功能的位置,我们只是用。此值已经检查了屏幕的左侧,所以我们检查的权利。

currentTouchLocation.x = MIN(maxX, currentTouchLocation.x);

这为我们提供了保证是我们的限制内的X位置。然后,我们对Y执行相同。

currentTouchLocation.y = MAX(minY, startTouchLocation.y);
currentTouchLocation.y = MIN(maxY, currentTouchLocation.y);

这一切的完成,我们现在可以告诉视图重绘自己,不再担心有我们可爱的小矩形以任何方式被切断。

[self setNeedsDisplay];

成品

/* Generates the limits based on the view's size, taking into account 
   the width/height of the rect being displayed in it. This should only
   be run once, unless the size of the view changes, in which case limits
   would have to be recalculated. The same goes for if you were to change
   the size of the displaying rect after calculation */

- (void)boundsCalculation {
    CGRect viewBounds = [self bounds];

        // calculate constraints
    maxX = viewBounds.origin.x + viewBounds.size.width - 32;
    minX = viewBounds.origin.x + 32;
    maxY = viewBounds.origin.y + viewBounds.size.height - 32;
    minY = viewBounds.origin.y + 84;
    NSLog(@"Boundaries calculated: X:(%f,%f) Y(%f,%f)", minX, maxX, minY, maxY);
}

/* Magic goodness that happens when the user touches the screen.
   Note that we don't calculate the bounds every time the user touches
   the screen, that would be silly. */

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    startTouchLocation = [touch locationInView:self];
    NSLog(@"Touch Started: (%f,%f)", startTouchLocation.x, startTouchLocation.y);

        // apply constraints
            // highest x value between the lowest allotted x value and touch
    currentTouchLocation.x = MAX(minX, startTouchLocation.x);
            // lowest x value between the highest allotted x value and touch
    currentTouchLocation.x = MIN(maxX, currentTouchLocation.x);
            // highest y value between the lowest allotted y value and touch
    currentTouchLocation.y = MAX(minY, startTouchLocation.y);
            // lowest y value between the highest allotted y value and touch
    currentTouchLocation.y = MIN(maxY, currentTouchLocation.y);
           // NSLog(@"Touch Result: (%f,%f)", currentTouchLocation.x, currentTouchLocation.y);

           // If you don't do this you won't see anything
    [self setNeedsDisplay];
}

今天是一个良好的学习一天。

有帮助吗?

解决方案

您一定要使用范围的是上海华来限制它的运动。

不要叫setNeedsDisplay经常。在方法的结束通话一次。你可能被不必要地重新绘制

我会使用类似下面的做到这一点。

// define these variables where ever you'd like
static float maxX = 0.;
static float maxY = 0.;
static float minX = 0.;
static float minY = 0.;

- (void)setupView {
    CGRect b = [self bounds];

    // calculate constraints
    maxX = b.origin.x + b.size.width/* - [box bounds].size.width */;
    minX = b.origin.x;
    maxY = b.origin.y + b.size.height/* - [box bounds].size.height */;
    minY = b.origin.y;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    startLocation = [touch locationInView:self];

    // apply constraints
    touchLocation.x = MIN(maxX, startLocation.x);
    touchLocation.x = MAX(minX, startLocation.x);
    touchLocation.y = MIN(maxY, startLocation.y);
    touchLocation.y = MAX(minY, startLocation.y);

    [self setNeedsDisplay];
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top