我正在尝试制作一个可以在屏幕上拖动的UIView,并且当释放时会捕捉到最近的边缘。
我已经整理了拖动 - 我正在使用UILongPressGestureRecognizer,当状态结束时,我正在调用以下方法,其中point是longPressGestureRecognizer的locationInView,而rect是包含gesturerecognizer和的姿势的UIView。可拖动的UIView。这个方法返回一个CGPoint,然后我将其设置为可拖动的UIView的中心。
- (CGPoint)closestPointForPoint:(CGPoint)point toSnapToInRect:(CGRect)rect {
CGPoint closestPoint = point;
/// Left/Right
if ((point.x - rect.origin.x) > (rect.size.width - point.x)) {
/// Point is closer to right side of frame, update the closestPoint's x.
closestPoint.x = rect.size.width - (self.draggableView.frame.size.width / 2) - draggableViewMargin;
}
else {
/// Point is closer to left side of frame, update the closestPoint's x.
closestPoint.x = rect.origin.x + (self.draggableView.frame.size.width / 2) + draggableViewMargin;
}
/// Top/Bottom
if ((point.y - rect.origin.y) > (rect.size.height - point.y)) {
/// Point is closer to top of frame, update the closestPoint's y.
closestPoint.y = rect.size.height - (self.draggableView.frame.size.height / 2) - draggableViewMargin;
}
else {
/// Point is closer to bottom of frame, update the closestPoint's y.
closestPoint.y = rect.origin.y + (self.draggableView.frame.size.height / 2) + draggableViewMargin;
}
return closestPoint;
}
除了当我放开视图时,它会捕捉到最近的角落。这很好,但不是我想要的。我希望它能够捕捉到最近的边缘,所以例如如果我放开视图时它的点是x:50 y:100(在1136 x 640的超视图中)我希望它对齐到左侧(如x值较小但是向下100像素而不是角落。
有人可以告诉我该怎么做吗?
由于
答案 0 :(得分:3)
您的问题是您并查找是向左或向右捕捉以及是向上还是向下捕捉。您正在寻找的是一种算法,可以决定对齐,向左,向上或向下捕捉。
这是我的解决方案:
//put all of the distances between the point and rect edges in an array.
NSArray *values = @[@(point.x - rect.origin.x), @(rect.size.width - point.x), @(point.y - rect.origin.y), @(rect.size.height - point.y)];
//Find the smallest distance.
NSNumber *minimumValue = [NSNumber numberWithInteger:NSIntegerMax];
for(NSNumber *value in values){
if([value intValue] < [minimumValue intValue]){
minimumValue = value;
}
}
if([minimumValue intValue] == point.x - rect.origin.x){
//snap to the left
}
if([minimumValue intValue] == rect.size.width - point.x){
//snap to the right
}
if([minimumValue intValue] == point.y - rect.origin.y){
//snap to the top
}
if([minimumValue intValue] == rect.size.height - point.y){
//snap to the bottom
}
它将所有值(上边距,右边距......)放在一个数组中,并迭代查找最小值。您可以编写if
语句的实现。我已经为你评论了每个人。我希望这能够帮到你。
修改:
我已更新代码并修复了一些错误。当我测试它时,它对我有用。
答案 1 :(得分:1)
您应该尝试仅针对一个方向应用捕捉,x或y;也许这样的事情可以奏效:
- (CGPoint)closestPointForPoint:(CGPoint)point toSnapToInRect:(CGRect)rect {
CGPoint closestPoint = point;
/// Left/Right
if (MIN(point.x - rect.origin.x, rect.size.width - point.x) < MIN(point.y - rect.origin.y, rect.size.height - point.y)) {
if ((point.x - rect.origin.x) > (rect.size.width - point.x)) {
/// Point is closer to right side of frame, update the closestPoint's x.
closestPoint.x = rect.size.width - (self.draggableView.frame.size.width / 2) - draggableViewMargin;
}
else {
/// Point is closer to left side of frame, update the closestPoint's x.
closestPoint.x = rect.origin.x + (self.draggableView.frame.size.width / 2) + draggableViewMargin;
}
} else {
/// Top/Bottom
if ((point.y - rect.origin.y) > (rect.size.height - point.y)) {
/// Point is closer to top of frame, update the closestPoint's y.
closestPoint.y = rect.size.height - (self.draggableView.frame.size.height / 2) - draggableViewMargin;
}
else {
/// Point is closer to bottom of frame, update the closestPoint's y.
closestPoint.y = rect.origin.y + (self.draggableView.frame.size.height / 2) + draggableViewMargin;
}
}
return closestPoint;
}
答案 2 :(得分:1)
这个答案对我不起作用,也许我会混淆rect
和point
我有另一个解决方案,它不需要循环,只需要一些方程式检查。
首先,将屏幕划分为四个区域。由于缺乏声誉,我现在无法发布图片,脚本文件在这里:http://i.stack.imgur.com/40Mos.jpg
然后,记下尺寸坐标系中线条的公式
最后,列出每个区域的方程式,现在你可以用方程式x y替换方程式中的x y。
CGPoint endPoint = [recognizer locationInView:self.view];
CGFloat k = self.view.bounds.size.height / self.view.bounds.size.width;
CGFloat b = self.view.bounds.size.height;
if (endPoint.y < k * endPoint.x && endPoint.y < -1 * k * endPoint.x + b) {
NSLog(@"top edge");
} else if (endPoint.y <= k * endPoint.x && endPoint.y >= -1 * k * endPoint.x + b) {
NSLog(@"right edge");
} else if (endPoint.y > k * endPoint.x && endPoint.y > -1 * k * endPoint.x + b) {
NSLog(@"bottom edge");
} else if (endPoint.y > k * endPoint.x && endPoint.y < -1 * k * endPoint.x + b) {
NSLog(@"left edge");
}