iphone - 使用view.bounds进行边界

标签 iphone objective-c cocoa-touch uikit boundary

我正在用iphone开发一些基本的应用程序/实用程序/游戏,以便更好地掌握它。
我现在有一个设置,手指移动时CGRect会移动,但是我不希望CGRect超出boundsview范围。
原始方法

- (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语句呢?那会比尝试的更好吗?
尝试
我正在尝试使用下面的@brad goss方法,但是它不起作用?
Touch Started: (319.000000,350.000000)
Touch Result: (319.000000,350.000000)
Boundaries calculated: X:(0.000000,288.000000) Y(0.000000,328.000000)

触摸开始是实际的开始触摸。
触摸结果应该是更改的结果。
上面的日志显示它在定义的switch之外,即不工作。我不会重新发布他写的代码,因为它是完全相同的。
尝试问题
我发现了这个问题。这与上面的类型情况相同,但在设置单个值时会记录这些值。
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)

我还没弄明白,一发现就贴在这里了。否则我会忘了更新,加上。
我要回去看看在每一种可能的情况下到底发生了什么。
错误
发现了另一个问题,从if计算boundsboundaries的代码,但没有从subtracts计算到maximums的代码。这一点很重要,因为这就是add的作用,可以阻止minimums离开屏幕。
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
好吧,我已经解决了另一个问题。当显示时,我正在添加boundary值。我忘了把它加到这个新密码里。代码现在如下所示:
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*/;

显示的圆的大小在rect的内部,因此y足以显示拇指上方的圆。虽然这是固定的,但仍然没有帮助解决我们原来的问题。
左上角:
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)

它正常工作,但是我很困惑为什么正确的值是从64px CGRect而不是20px中出来的。这里有些东西弄混了。
右上角:
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)

可以预见的是,它只对最小值起作用。我仍然很困惑这些函数应该做什么。如果你有洞察力,我将不胜感激!
解决了的!
谢天谢地,我们漫长的道路即将结束。所以,因为我不知道,这里是MAXMIN要做的。由于发生的混乱,我起初并不清楚。
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

因此,在这种情况下,要正确使用这些功能,必须执行以下操作:
一。计算x和y的最大值和最小值。
每个值的最低值计算为
view.origin + keepOnScreenRect.width  

每个值的最高值计算为
view.origin + view.size.height/width - keepOnScreenRect.height/width

别忘了手指的偏移量!
如果您正在执行我所做的操作,并且keeponscreenrect位于用户手指的上方,那么您应该只将额外的偏移量添加到y的最大值,因为y的最小值是屏幕/视图的底部,您在物理上无法将其降到0以下。
如果您想知道为什么要这样做,那是因为用户无法通过手指看到。
2.获取触摸的位置MIN
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    startTouchLocation = [touch locationInView:self];
    NSLog(@"Touch Started: (%f,%f)", startTouchLocation.x, startTouchLocation.y);

三。应用数学约束:
首先,我们得到MAX或最大值,这两个值都是根据我们的限制touchesBegan:MAX的最小可能值。这将计算屏幕左侧的限制。其结果设置为minX
currentTouchLocation.x = MAX(minX, startTouchLocation.x);

第二,根据我们的极限,我们得到两个最大可能值中的startTouchLocation或最小值,对于X。请注意,我们不是使用原始触摸的位置,而是我们刚才使用的currentTouchLocation函数的结果位置。这个值已经在屏幕的左边被检查过了,所以我们检查右边。
currentTouchLocation.x = MIN(maxX, currentTouchLocation.x);

这给了我们一个MIN的位置,保证在我们的范围内。然后对maxX执行相同的操作。
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];
}

今天是学习的好日子。

最佳答案

你肯定想用它的超视界来限制它的运动。
不要经常调用setneeds显示。在方法结束时调用一次。你可能在不必要地重新绘制。
我想用下面的方法来完成这个任务。

// 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];
}

关于iphone - 使用view.bounds进行边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1922748/

相关文章:

iphone - 像这样实现 Objective C init 方法有什么意义呢?

iphone - 使用自定义字体将文本本地化为中文

iphone - Phonegap 地理位置错误 : timeout

ios - 使用 iOS 进行信用卡支付

ios - [__NSArrayM objectAtIndex :]: index 2 beyond bounds for empty array

ios - 如何在一个 UIViewController 中处理多个 View

iPhone:如何使用 NSURLCredential 获得 HTTPS Web 服务的基本身份验证

iphone - 是否可以在 iPhone 上的 UIWebView 上以编程方式调用 "select all",然后调用 "copy"?

ios - 使用Objective-C压缩文件

ios - 将对象添加到现有 NSMutableArray 会导致异常