拖动 UIView 时如何实现流畅的动画

Posted

技术标签:

【中文标题】拖动 UIView 时如何实现流畅的动画【英文标题】:How can I achieve a smooth animation when dragging a UIView 【发布时间】:2018-03-01 17:14:47 【问题描述】:

这是我迄今为止编写的用于在拖动时更改视图位置的代码。

UIPanGestureRecognizer 更改或开始时,视图会更改其中心点,当我放开手势时会发生这种情况。我不要那个。我希望它像 Notification Center and Control Center does 那样与我的拖累一起使用。

提前感谢您的帮助。

class ViewController: UIViewController 

let maxY = UIScreen.main.bounds.height
lazy var slideUpView: UIView = 
    let view = UIView(frame: CGRect(x: 0, y: maxY - 295, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height / 3 ))
    view.backgroundColor = .green
    return view
()


lazy var redImageView: UIView = 
    let view = UIView(frame: CGRect(x: 0, y: maxY - 295, width: UIScreen.main.bounds.width, height: slideUpView.frame.height / 2 ))
    view.backgroundColor = .red
    return view
()

override func viewDidLoad() 
    super.viewDidLoad()

    print("MaxX: \(UIScreen.main.bounds.maxX)")
    print("Max Hight: \(UIScreen.main.bounds.height)")
    print("MaxY: \(UIScreen.main.bounds.maxY)")
    print("Max width: \(UIScreen.main.bounds.width)")
    // MARK: add the views as subview
    let viewsArray = [slideUpView, redImageView]
    viewsArray.forEachview.addSubview($0)
    // Add a UIPanGestureRecognizer to it
    viewsArray.forEach createPanGestureRecognizer(targetView: $0)


// The Pan Gesture
func createPanGestureRecognizer(targetView: UIView) 
    let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(recognizer:)))
    panGesture.maximumNumberOfTouches = 1
    targetView.addGestureRecognizer(panGesture)


@objc func handlePanGesture(recognizer: UIPanGestureRecognizer) 
    if recognizer.state == UIGestureRecognizerState.began || recognizer.state == UIGestureRecognizerState.changed 
        let translation = recognizer.translation(in: self.view)
        print(recognizer.view!.center.y)
        let newPos = CGPoint(x:recognizer.view!.center.x + translation.x, y: recognizer.view!.center.y + translation.y)
        if insideDraggableArea(newPos) 
            guard let targetedView = recognizer.view else 
                print("Error: No View to handle")
                return
            
            targetedView.center.y = newPos.y
            recognizer.setTranslation(.zero, in: targetedView)
        
    


private func insideDraggableArea(_ point : CGPoint) -> Bool 
    return  // point.x > 50 && point.x < 200 &&
        point.y > (maxY * 0.27) && point.y <= maxY


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
    if let touch = touches.first 
        let position = touch.location(in: view)
        print(position)
    
  
 

【问题讨论】:

我现在不明白出了什么问题.. 解释一下自己好一点 只需使用 CABasicAnimation 来更改视图层位置 这里已经有一个关于如何解决问题的非常详细的答案***.com/a/48196975/2303865 它显示了如何旋转,但您可以调整答案以仅移动。如果您仍有问题,请尝试编辑您的问题并发布您的尝试并告诉我 Nate 已经提到它,您在此处列出的代码似乎有效,您需要更好地描述您的问题到底是什么。从问题看来,在您解除之前视图不会移动你的手指,但代码工作正常 这段代码运行良好。创建一个空白项目并包含此代码,您会看到它毫无问题地拖动。您必须有其他未包含在此处的内容。我们需要MCVE。继续将更多实际代码添加到空白项目中,直到可以重现问题为止。当然,这里有很多奇怪的东西(例如,当你没有任何委托方法时,为什么要指定委托?你通常会使用手势识别器或触摸方法,但不能同时使用两者;等等),但这并没有显示您报告的错误。 【参考方案1】:

我也有这个问题,至少在游乐场原型中......

我将所有翻译(您在更改状态下的)放入我在 handlePanGesture 函数中定义的 UIViewProperty 动画器中,然后在开始/更改状态中调用 .startAnimation()。

它需要对动画进行一些调整,但对我来说更流畅..

【讨论】:

不错的答案。让我免于编写大量冗余代码。【参考方案2】:

此代码运行良好。问题出在我昨天使用的模拟器中。在 iPhone 上进行测试时,一切都按照我想要的方式运行。

【讨论】:

以上是关于拖动 UIView 时如何实现流畅的动画的主要内容,如果未能解决你的问题,请参考以下文章

如何制作流畅的 UIView 分割动画?

如何实现可交互的 UIView 隐式动画

如何在 iOS 中获得最流畅的动画?

iOS动画效果和实现

如何中断 UIView 动画

iOS:UIView 在动画时改变大小,我该如何防止?