ios - Swift:平移(拖动)后如何使惯性平滑?

标签 ios swift swift2

我已经学习 Swift 2.2 好几天了。完成官方教程后,我正在尝试制作一些功能示例。例如。我正在尝试制作头像装饰器。

@IBAction func moveAvatar(recognizer:UIPanGestureRecognizer) {
    recognizer.maximumNumberOfTouches = 1
    recognizer.minimumNumberOfTouches = 1
    let debugOutOfBounds = false
    let debugGestureRecognizer = false
    let debugVelocity = true
    if (debugGestureRecognizer) {
        print("pan")
    }
    let translation = recognizer.translationInView(self.avatar)

    let standardAvatarSize:CGFloat = Conf.Size.avatarRadius * 2
    if (self.avatar.frame.width <  standardAvatarSize) {
        self.avatar.frame = CGRect(origin: self.avatar.frame.origin, size: CGSize(width: standardAvatarSize, height:standardAvatarSize))
    }
    if let view = recognizer.view {
        switch recognizer.state {
        case .Began:
            if (debugVelocity) {
                print("Began: velocity: \(recognizer.velocityInView(view))  translation: \(translation)")
            }
            
            self.panAvatarLastTranslation = translation
            self.avatar.center = CGPoint(x: self.avatar.center.x + translation.x, y: self.avatar.center.y + translation.y)
        case .Changed:
            if (debugVelocity) {
                print("Changed: velocity: \(recognizer.velocityInView(view))  translation: \(translation)")
            }
            if (translation != CGPoint(x: 0.0, y: 0.0)) {
                self.panAvatarLastTranslation = translation
            }
            self.avatar.center = CGPoint(x: self.avatar.center.x + translation.x, y: self.avatar.center.y + translation.y)
        case .Ended:
            if (debugVelocity) {
                print("Ended: velocity: \(recognizer.velocityInView(view))  translation: \(translation)")
            }
            let velocityDistance = sqrt(pow(recognizer.velocityInView(view).x, CGFloat(2)) + pow(recognizer.velocityInView(view).y, CGFloat(2)))
            print(velocityDistance)
            if (velocityDistance > 100) {
                let inertiaDelay: NSTimeInterval = 0.5
                let inertiaDistance : CGFloat = velocityDistance * CGFloat(inertiaDelay) * 0.02
                let inertiaX:CGFloat = self.panAvatarLastTranslation.x * inertiaDistance
                let inertiaY:CGFloat = self.panAvatarLastTranslation.y * inertiaDistance
                                    //sqrt(pow(inertiaX, CGFloat(2)) + pow(inertiaY, CGFloat(2)))
                //print("inertiaDelay: \(inertiaDelay)")
                UIView.animateWithDuration(inertiaDelay, animations: {
                    self.avatar.center.x += inertiaX
                    self.avatar.center.y += inertiaY
                })
            }
        default:
            print("default")
        }

        let standardAvatarBound: [String:CGFloat] = [
            "top": UIApplication.sharedApplication().statusBarFrame.height + UIScreen.mainScreen().bounds.width / 2 - Conf.Size.avatarRadius,
            "right": UIScreen.mainScreen().bounds.width / 2 + Conf.Size.avatarRadius,
            "bottom": UIApplication.sharedApplication().statusBarFrame.height + UIScreen.mainScreen().bounds.width / 2 + Conf.Size.avatarRadius,
            "left": UIScreen.mainScreen().bounds.width / 2 - Conf.Size.avatarRadius
        ]
        let avatarBound: [String:CGFloat] = [
            "top": self.avatar.center.y - self.avatar.frame.height / 2,
            "right": self.avatar.frame.width / 2 + self.avatar.center.x,
            "bottom": self.avatar.center.y + self.avatar.frame.height / 2,
            "left": self.avatar.center.x - self.avatar.frame.width / 2
        ]
        
        if (self.panAvatarLastTranslation.x < 0 && avatarBound["right"] < standardAvatarBound["right"]) {
            UIView.animateWithDuration(0.5, animations: {
                self.avatar.center.x += (standardAvatarBound["right"]! - avatarBound["right"]!)
            })
            if (debugOutOfBounds) {
                print("Out of right bound")
            }
        }
        
        if(self.panAvatarLastTranslation.x > 0 && avatarBound["left"] > standardAvatarBound["left"]) {
            UIView.animateWithDuration(0.5, animations: {
                self.avatar.center.x -= (avatarBound["left"]! - standardAvatarBound["left"]!)
            })
            if (debugOutOfBounds) {
                print("Out of left bound")
            }
        }
        
        if(self.panAvatarLastTranslation.y > 0 && avatarBound["top"] > standardAvatarBound["top"]) {
            UIView.animateWithDuration(0.5, animations: {
                self.avatar.center.y -= (avatarBound["top"]! - standardAvatarBound["top"]!)
            })
            if (debugOutOfBounds) {
                print("Out of top bound")
            }
        }
        if(self.panAvatarLastTranslation.y < 0 && avatarBound["bottom"] < standardAvatarBound["bottom"]) {
            UIView.animateWithDuration(0.5, animations: {
                self.avatar.center.y += (standardAvatarBound["bottom"]! - avatarBound["bottom"]!)
            })
            if (debugOutOfBounds) {
                print("Out of bottom bound")
            }
        }
    }
    recognizer.setTranslation(CGPointZero, inView: view)
}

好的,如您所见,我在平移手势识别器的“.Ended”状态下处理拖动惯性。 它运作良好,但并不顺利。我该怎么做才能使平移惯性变得平滑?

这是源代码:https://github.com/AarioAi/NotesOpen/tree/master/Swift

最佳答案

尝试使用不同的方法制作动画。哎呀this tutorial

关于ios - Swift:平移(拖动)后如何使惯性平滑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35959838/

相关文章:

ios - 在 PromiseKit 6 中返回 void

ios - Swift tableviewcell 边界未正确绑定(bind)/固定?

arrays - Swift2 检查字典中的数组

swift - 如何在 View 内快速制作带有多行标签的正确 ScrollView

ios - 'required' initializer 'init(coder:)' 必须由 'UITableViewCell' 的子类提供`

swift - 如何为动画中的单个 SKTextures 设置持续时间

ios - 将 FacebookSDK.framework 添加到我自己的静态库中

ios - Docusign 快速集成

ios - 动画 UIView 时自动调整 CAShapeLayer 大小

ios - 错误 ITMS-90096 - 缺少 iOS 7 的启动图像