ios - 将可拖动的 UIView 限制为 SuperView 的边界

标签 ios objective-c uigesturerecognizer

假设我们有一个带有内部大自定义 UIImageView 的 UITableViewCell,如下图所示:
我已添加 UILongPressGestureRecOgnizer到 UITableViewCell,所以在 longPress 之后用户可以移动这个大图像。但我希望这个 Action 在 UITableViewCell 的范围内.
enter image description here

我现在所做的:

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/

相关文章:

ios - 自动启动时,TeamCity 无法运行 iOS appium 测试

ios - flutter 中的 flutter inappwebview 警告

ios - 在 Docker 中使用 FaSTLane 构建 iOS 应用

iphone - 触摸 uiTabBar 上方

iphone - 如何解析 iOS 中有特殊字符的 xml 数据?

ios - UITapGestureRecognizer 干扰 UISlider

ios - 如何禁用 "gesture recognizer"(XMCircleGestureRecognizer)?

ios - Kontakt 信标和 iOS : didStartMonitoringForRegion not working as expected

ios - 为什么转换后的 UIView 会与层次结构中更高层的其他 View 重叠?

objective-c - iOS 将 tapGesture 添加到多个 View