假设我们有一个带有内部大自定义 UIImageView 的 UITableViewCell,如下图所示:
我已添加 UILongPressGestureRecOgnizer
到 UITableViewCell,所以在 longPress 之后用户可以移动这个大图像。但我希望这个 Action 在 UITableViewCell
的范围内.
我现在所做的:
UIView *view = sender.view;
CGPoint point = [sender locationInView:view.superview];
if (sender.state == UIGestureRecognizerStateChanged)
{
CGPoint oldCenter = view.center;
CGPoint newCenter = oldCenter;
CGFloat deltaX = point.x - _priorPoint.x;
CGFloat deltaY = point.y - _priorPoint.y;
newCenter.x += deltaX;
newCenter.y += deltaY;
CGRect oldFrame = view.frame;
CGRect newFrame = CGRectMake(oldFrame.origin.x + deltaX, oldFrame.origin.y+deltaY, view.width, view.height);
if (CGRectContainsRect(newFrame, self.bounds)) {
self.customImageView.center = newCenter;
}
else
{
CGFloat newX = newFrame.origin.x;
CGFloat newY = newFrame.origin.y;
if (newX<view.x) {
newX = oldFrame.origin.x;
}
else if ((newFrame.origin.x + newFrame.size.width)>view.right)
{
newX = oldFrame.origin.x;
}
if (newY<view.y) {
newY = oldFrame.origin.y;
}
else if ((newY + newFrame.size.height)>view.bottom)
{
newY = view.y;
}
NSLog(@"newX:%f, newY:%f", newX, newY);
newFrame = CGRectMake(newX, newY, view.width, view.height);
self.customImageView.frame = newFrame;
}
_priorPoint = point;
问题是当我对角移动手指时,图像移动有点生涩。沿对角线移动时,例如当
X
超出范围,如果 Y
有效,Y
点应该更新。这里有什么问题?你有什么主意吗?
最佳答案
我为此做的事情有点难以理解,但是这里......
我在正在移动的 View 中进行触摸交互。在 touchesBegan
drawingFrame = self.frame;
initialViewOrigin = self.frame.origin;
startingTouch = [[touches anyObject] locationInView:[self superview]];
这些都是类变量。然后在
touchesMoved
:lastTouchPoint = [[touches anyObject] locationInView:[self superview]];
float newLocationX = initialViewOrigin.x + (p.x - startingTouch.x);
float newLocationY = initialViewOrigin.y + (p.y - startingTouch.y);
//Do some location checks for sending it too far off the screen or whatnot
drawingFrame.origin = [self scrollLimit:newLocationX y:newLocationY];
CGRect frame = self.frame;
frame.origin.x = drawingFrame.origin.x;
frame.origin.y = drawingFrame.origin.y;
self.frame = frame;
所有有趣的事情都发生在
scrollLimit
功能:-(CGPoint)scrollLimit:(float)x1 y:(float)y1
{
//My app always requires landscape, so make sure the parent's sizes are taken accordingly
int parentHeight = MIN(self.superview.frame.size.width,self.superview.frame.size.height);
int parentWidth = MAX(self.superview.frame.size.width,self.superview.frame.size.height);
if(self.frame.size.width < parentWidth)
{
if(x1 < 1)
{
x1 = 1;
}
else if(x1 >= parentWidth - self.frame.size.width)
{
x1 = parentWidth - self.frame.size.width;
}
}
else{
x1 = initialViewOrigin.x;
}
if(self.frame.size.height < parentHeight)
{
if(y1 < 1)
{
y1 = 1;
}
else if(y1 > parentHeight - self.frame.size.height)
{
y1 = parentHeight - self.frame.size.height;
}
}
else{
y1 = initialViewOrigin.y;
}
return CGPointMake(x1,y1);
}
所有这些确保 View 保持在您设置的范围内(在我的情况下只是 super View 范围),并且它还使拖动体验流畅和逼真。我见过的其他一些方法可能会导致您的手指离开您正在滚动的项目并且永远不会同步备份。我确信我的代码不会按原样为您工作,但它应该让您朝着正确的方向前进。
在我的方法中,我还模拟了 View “ throw ”的惯性,同时仍保持边界 super View 框。由于这不在您的问题范围内,并且需要很长时间才能变得完美,所以我将把它作为练习留给读者......
关于ios - 将可拖动的 UIView 限制为 SuperView 的边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37491067/