ios - pageCurl 动画与触摸交互

标签 ios swift animation touch page-curl

我正在寻找一种方法来在 UIView 上指示与触摸(开始/移动/结束)交互的卷页动画 like this

注意:

  1. 我不会使用 UIPageController。动画应应用于 UIView
  2. 动画与触摸开始、触摸移动和触摸结束之间的交互非常重要。完全像视频

示例代码但不适用于触摸:

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.

    BackBtn.layer.cornerRadius = 5.0

    AnimationBtn.layer.cornerRadius = 5.0

    transition.delegate = self
    transition.duration = 1.5
    transition.startProgress = 0
    transition.endProgress = 1
    transition.type = CATransitionType(string: "pageCurl") as String
    transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    transition.fillMode = kCAFillModeBoth
    transition.isRemovedOnCompletion = false
}

接触感动:

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

    super.touchesMoved(touches, with: event)

    if let touch = touches.first {

        let endPosition = touch.location(in: touch.view)

        differenceX = startPosition.x - endPosition.x

        differenceY = endPosition.y - startPosition.y

        transition.subtype = kCATransitionFromRight

        touch.view!.layer.add(transition, forKey: kCATransition)

        webView.scrollView.contentOffset = CGPoint(x: nextPage + differenceX, y: 0)
   }
}

最佳答案

我找到了答案。我只需要更改 transition.startProgresstransition.endProgress

示例代码:

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

    calculatePageCount()

    if let touch = touches.first {

        startPosition = touch.location(in: self.view)

        endPosition = startPosition

        previousPositionX = startPosition.x

        print("start x: \(startPosition.x), start y: \(startPosition.y)")

        transition.startProgress = 0.0

        if index == 0 && startPosition.x > (screenWidth / 2) {

            transition.endProgress = 1.0 - Float(startPosition.x / screenWidth)
            transition.subtype = kCATransitionFromRight

            self.view.layer.add(transition, forKey: kCATransition)
        } else if index != 0 {
            if index != (pageCounter - 1) && startPosition.x > (screenWidth / 2) {
                if self.view.layer.animationKeys() != nil {
                    self.view.layer.removeAllAnimations()
                }

                transition.endProgress = 1.0 - Float(startPosition.x / screenWidth)
                transition.subtype = kCATransitionFromRight
                self.view.layer.add(transition, forKey: kCATransition)
            } else if startPosition.x < (screenWidth / 2) {
                if self.view.layer.animationKeys() != nil {
                    self.view.layer.removeAllAnimations()
                }

                transition.endProgress = Float(startPosition.x / screenWidth)
                transition.subtype = kCATransitionFromLeft
                self.view.layer.add(transition, forKey: kCATransition)
            } else {
                if self.view.layer.animationKeys() != nil {
                    self.view.layer.removeAllAnimations()
                }
            }
        } else {
            if self.view.layer.animationKeys() != nil {
                self.view.layer.removeAllAnimations()
            }
        }
    }
}

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

    if let touch = touches.first {

        endPosition = touch.location(in: touch.view)

        print("end x: \(endPosition.x), end y: \(endPosition.y)")

        differenceX = startPosition.x - endPosition.x

        differenceY = endPosition.y - startPosition.y

        let differencePosition = endPosition.x - previousPositionX

        previousPositionX = endPosition.x

        print("difference x: \(differenceX)")

        if self.view.layer.animationKeys() != nil {

            transition.startProgress = transition.endProgress

            if differenceX > 0 {

                differencePosition < 0 ? (transition.endProgress = transition.endProgress + Float((abs(differencePosition) / screenWidth))) : (transition.endProgress = transition.endProgress - Float((abs(differencePosition) / screenWidth)))

                self.view.layer.removeAllAnimations()
                self.view.layer.add(transition, forKey: kCATransition)
            } else {

                differencePosition > 0 ? (transition.endProgress = transition.endProgress + Float((abs(differencePosition) / screenWidth))) : (transition.endProgress = transition.endProgress - Float((abs(differencePosition) / screenWidth)))

                self.view.layer.removeAllAnimations()
                self.view.layer.add(transition, forKey: kCATransition)
            }
        }
    }
}

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

    print("touch ended")

    if self.view.layer.animationKeys() != nil {

        if startPosition.x == endPosition.x {

            transition.startProgress = transition.endProgress
            transition.endProgress = 0

            self.view.layer.removeAllAnimations()
            self.view.layer.add(transition, forKey: kCATransition)
        } else {

            if differenceX > 0 {

                if differenceX > (screenWidth / 2) {

                    if index < (pageCounter - 1) {
                        index += 1
                    }
                    transition.startProgress = transition.endProgress
                    transition.endProgress = 1

                    self.view.layer.removeAllAnimations()
                    self.view.layer.add(transition, forKey: kCATransition)
                } else {
                    transition.endProgress = 0

                    self.view.layer.removeAllAnimations()
                    self.view.layer.add(transition, forKey: kCATransition)
                }
            } else {

                if abs(differenceX) > (screenWidth / 2) {
                    if index > 0 {
                        index -= 1

                        transition.startProgress = transition.endProgress
                        transition.endProgress = 1

                        self.view.layer.removeAllAnimations()
                        self.view.layer.add(transition, forKey: kCATransition)
                    } else {
                        transition.endProgress = 0

                        self.view.layer.removeAllAnimations()
                        self.view.layer.add(transition, forKey: kCATransition)
                    }
                } else {

                    transition.endProgress = 0

                    self.view.layer.removeAllAnimations()
                    self.view.layer.add(transition, forKey: kCATransition)
                }
            }
        }
    }
    nextPage = CGFloat(index) * webView.scrollView.bounds.size.width
    webView.scrollView.contentOffset = CGPoint(x: nextPage, y: 0)
}

func calculatePageCount() {

    pageCounter = Int((webView.scrollView.contentSize.width / webView.scrollView.bounds.size.width).rounded())
}

关于ios - pageCurl 动画与触摸交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57074745/

相关文章:

swift - Twitter API 返回错误 401(使用 OAuthSwift)

ios - 初始化(编码器:) has not Implement

javascript - 在小间隔内通过 javascript 更新 css 时卡住轨道动画

iphone - @""字符串类型并释放你不拥有的对象问题

swift - 在 Swift 中向 Here Maps 添加 WMS 图层

ios - 为什么 viewDidAppear 没有调用?

ios - 使用大量内存的动画iOS7

javascript - 创建选取框样式动画

ios - 如何将 Eureka 表单与另一个表放在 UIViewController 中?

ios - 旋转景观集合View