Swift: 在滑动手势上移动 UIView

Swift: move UIView on slide gesture

我正在尝试将向上滑动手势的 UIView 从其初始位置移动到固定的最终位置。图像应随手势移动,而不是独立动画。

我没有尝试过任何东西,因为我不知道从哪里开始,使用哪种手势 class。

您可能想使用 UIPanGestureRecognizer

let gesture = UIPanGestureRecognizer(target: self, action: Selector("wasDragged:"))
customView.addGestureRecognizer(gesture)
gesture.delegate = self

并且仅沿 y 轴拖动对象:

func wasDragged(gesture: UIPanGestureRecognizer) {
    let translation = gesture.translationInView(self.view)

    // Use translation.y to change the position of your customView, e.g.
    customView.center.y = translation.y // Customize this.
}

终于像下面这样做了。

let gesture = UIPanGestureRecognizer(target: self, action: Selector("wasDragged:"))
slideUpView.addGestureRecognizer(gesture)
slideUpView.userInteractionEnabled = true
gesture.delegate = self

检测到手势时调用以下函数,(这里我将视图限制为最大 centre.y 555,并且当视图移过该点时我将重置回 554 )

func wasDragged(gestureRecognizer: UIPanGestureRecognizer) {
    if gestureRecognizer.state == UIGestureRecognizerState.Began || gestureRecognizer.state == UIGestureRecognizerState.Changed {
        let translation = gestureRecognizer.translationInView(self.view)
        print(gestureRecognizer.view!.center.y)
        if(gestureRecognizer.view!.center.y < 555) {
            gestureRecognizer.view!.center = CGPointMake(gestureRecognizer.view!.center.x, gestureRecognizer.view!.center.y + translation.y)
        }else {
            gestureRecognizer.view!.center = CGPointMake(gestureRecognizer.view!.center.x, 554)
        }

        gestureRecognizer.setTranslation(CGPointMake(0,0), inView: self.view)
    }

}

更新 Swift 3.x

分配选择器时,语法已更改,现在需要 #selector

let gesture = UIPanGestureRecognizer(target: self, action: #selector(navViewDragged(gesture:)))

    self.navLayoutView.addGestureRecognizer(gesture)
    self.navLayoutView.isUserInteractionEnabled = true
    gesture.delegate = self

函数实现:

func navViewDragged(gesture: UIPanGestureRecognizer){
     //Code here
}
@IBAction func handlePanGesture(_ recognizer: UIPanGestureRecognizer) {

    if MainView.bounds.contains(mainImage.frame) {
        let recognizerCenter = recognizer.location(in:  MainView)

        mainImage.center = recognizerCenter
    }

    if MainView.bounds.intersection(mainImage.frame).width > 50 && MainView.bounds.intersection(mainImage.frame).height > 0 {
        let recognizerCenter = recognizer.location(in: MainView)
        print(recognizerCenter)
        mainImage.center = recognizerCenter
    }

}

@IBAction func handlePinchGesture(_ recognizer: UIPinchGestureRecognizer) {

    mainImage.transform = mainImage.transform.scaledBy(x: recognizer.scale, y: recognizer.scale)
    recognizer.scale = 1.0
}

@IBAction func handleRotateGesture(_ recognizer: UIRotationGestureRecognizer) {

    mainImage.transform = mainImage.transform.rotated(by: recognizer.rotation)
    recognizer.rotation = 0.0

}

Swift 4:

@objc func wasDragged(_ gestureRecognizer: UIPanGestureRecognizer) {

    if gestureRecognizer.state == UIGestureRecognizer.State.began || gestureRecognizer.state == UIGestureRecognizer.State.changed {

        let translation = gestureRecognizer.translation(in: self.view)
        print(gestureRecognizer.view!.center.y)

        if(gestureRecognizer.view!.center.y < 555) {

            gestureRecognizer.view!.center = CGPoint(x: gestureRecognizer.view!.center.x, y: gestureRecognizer.view!.center.y + translation.y)

        }else {
            gestureRecognizer.view!.center = CGPoint(x:gestureRecognizer.view!.center.x, y:554)
        }
        gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
    }
}

通话

let gesture = UIPanGestureRecognizer(target: self, action: self.wasDragged(gestureRecognizer:))
customView.addGestureRecognizer(gesture)
gesture.delegate = self

将视图移动到 Swift 3

中的任意位置
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(dragged(gestureRecognizer:)))
demoView.isUserInteractionEnabled = true
demoView.addGestureRecognizer(panGesture)

函数

@objc func dragged(gestureRecognizer: UIPanGestureRecognizer) {
    if gestureRecognizer.state == UIGestureRecognizerState.began || gestureRecognizer.state == UIGestureRecognizerState.changed {
        let translation = gestureRecognizer.translation(in: self.view)
        gestureRecognizer.view!.center = CGPoint(x: gestureRecognizer.view!.center.x + translation.x, y: gestureRecognizer.view!.center.y + translation.y)
        gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
    }
}

这就是您真正做到的方式,就像股票应用程序中的新闻视图一样

首先在Storyboard中给滑动视图添加2个约束,一个是完全打开时的状态,一个是关闭时的状态。不要忘记禁用/未安装约束之一,以便在到达场景时您的视图看起来是打开或关闭的。 在您的代码中引用它们

@IBOutlet weak var optionsOpenedConstraint: NSLayoutConstraint!
@IBOutlet weak var optionsVisiableConstraint: NSLayoutConstraint!

现在将 UIPanGestureRecognizer 添加到 viewDidLoad 函数的视图中。

let gesture = UIPanGestureRecognizer(target: self, action: #selector(type(of: self).wasDragged(gestureRecognizer:)))
    optionsView.addGestureRecognizer(gesture)

最后添加这个回调和 2 个函数:

@objc func wasDragged(gestureRecognizer: UIPanGestureRecognizer) {
    let distanceFromBottom = screenHeight - gestureRecognizer.view!.center.y
    if gestureRecognizer.state == UIGestureRecognizer.State.began || gestureRecognizer.state == UIGestureRecognizer.State.changed {
        optionsOpenedConstraint.isActive = false
        optionsVisiableConstraint.isActive = false
        let translation = gestureRecognizer.translation(in: self.view)
        if((distanceFromBottom - translation.y) < 100) {
            gestureRecognizer.view!.center = CGPoint(x: gestureRecognizer.view!.center.x, y: gestureRecognizer.view!.center.y + translation.y)
            gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
        }

    }
    if gestureRecognizer.state == UIGestureRecognizer.State.ended{
        if distanceFromBottom > 6{
            openOptionsPanel()
        }else{
            closeOptionsPanel()
        }
    }
}
func openOptionsPanel(){
    optionsOpenedConstraint.isActive = true
    optionsVisiableConstraint.isActive = false
    UIView.animate(withDuration: 0.5) {
        self.view.layoutIfNeeded()
    }
}

func closeOptionsPanel(){
    optionsOpenedConstraint.isActive = false
    optionsVisiableConstraint.isActive = true
    UIView.animate(withDuration: 0.5) {
        self.view.layoutIfNeeded()
    }
}

哇哦