斯威夫特:如何在平移(拖动)后产生平滑的惯性?

时间:2016-03-12 15:52:48

标签: 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

1 个答案:

答案 0 :(得分:1)

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