防止可拖动视图离开屏幕

时间:2016-12-11 21:52:22

标签: ios swift drag subview

我有一个可拖动的按钮,我不希望用户能够拖动视图,以便边缘被屏幕边缘切断。

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let touch = touches.first {
            let position = touch.location(in: self.superview)

            self.center = CGPoint(x: position.x, y: position.y)

            }

        }

我这样做的方法就是大量的if / else语句检查屏幕上允许的区域。

 let halfOfButton = CGFloat(85 / 2)
            let heightOfTopBar = CGFloat(55) + halfOfButton
            let widthOfScreen = CGFloat((self.superview?.frame.width)!) - halfOfButton
            let heightOfScreen = CGFloat((self.superview?.frame.height)!) - heightOfTopBar

            let heightOfBotBar = CGFloat((self.superview?.frame.height)! - heightOfTopBar)


            if position.x > halfOfButton && position.x < widthOfScreen {
                self.center = CGPoint(x: position.x, y: position.y)

            } else {
                if position.x < halfOfButton {
                self.center = CGPoint(x: halfOfButton, y: position.y)
                } else {
                      self.center = CGPoint(x: widthOfScreen, y: position.y)
                }
            }

            if position.y > heightOfTopBar && position.y < heightOfScreen && position.x > halfOfButton && position.x < widthOfScreen {
                self.center = CGPoint(x: position.x, y: position.y)

            } else {
                if position.y < heightOfTopBar {
                    self.center = CGPoint(x: position.x, y: heightOfTopBar)
                } else {
                    self.center = CGPoint(x: position.x, y: heightOfScreen)
                }
            }
        }

有没有更好的方法来实现这一目标?上面的代码甚至还没有完全发挥作用。它在我所说的逻辑中有很多缺陷&#34;如果Y没问题,那么只需让触摸中心成为按钮的中心即可。但是这会覆盖我在X中编写的代码,即使Y可能没问题,X也不会。

我可以通过这种方式弄清楚这个逻辑,但肯定有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

尝试这样的事情:

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
    let position = touch.location(in: self.superview)

    var x:CGFloat = position.x
    var y:CGFloat = position.y

    let parentWidth = button.superView!.frame.size.width
    let parentHeight = button.superView!.frame.size.height

    let width = button.frame.size.width / 2
    let height = button.frame.size.height / 2

    x = max(width, x)
    x = min(x, parentWidth - width)

    y = max(height, y)
    y = min(y, parentHeight - height)



    self.center = CGPoint(x: x, y: y)

}

}

答案 1 :(得分:1)

我回过头来讨论这个问题并用这种方法解决了它。

首先,为了考虑按钮的大小,并且不想剪切它的一部分,我创建了一个视图(对于这个例子,我们称之为containerView)放置在你想要的区域上按钮出现。此视图需要从超级视图中减少其边距,使其顶部和底部边距是按钮高度的一半,它是领先的&amp;后缘是按钮宽度的一半。

通过这种设置,现在使用内置函数来包含其移动是相当简单的,它在没有if语句的情况下提供更好的性能。

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesMoved(touches, with: event)

    guard let touch = touches.first else {
        return
    }

    let location = touch.location(in: containerView)

    if containerView.point(inside: location, with: event) {
        button.center = location
    }
}

现在,根据您使用的坐标系,可能无法使用此技术将按钮正确放置在您想要的位置。如果确实发生了这种情况,您应该能够通过修改位置值来解决它,然后再将其分配给button.center属性。

修改应该是根据您的领先优势向右或向下移动。最高利润率。理想情况下,您可以使用storyboard约束,然后可以链接到控制器,允许您直接获取这些值以进行调整。