简体   繁体   中英

How to control the transition between 2 UIView states using a swipe gesture?

I want to be able to transition between 2 states of a UIView with a swipe left, swipe right gestures. Essentially I want to start expanding the view's height as the user starts swiping left and "shrink" it when a swipe right is initiated. I can easily animate between the two states with CAAnimation but what I want ideally is the gesture to control the transition instead of giving it a "duration". So essentially the gesture's range is mapped to the expansion / shrinkage of height... I'm doing a terrible job of explaining myself but Apple does this all the time.

Here's how my custom UIView looks at the moment:

class CustomUIView: UIView {

    @IBOutlet var swipeView: UIView!

    var shouldExecuteExpandAnimation:Bool = true;
    var shouldExecuteShrinkAnimation:Bool = true;


    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        NSBundle.mainBundle().loadNibNamed("CustomUIView", owner: self, options: nil)
        swipeView.backgroundColor = UIColor.grayColor()
        self.addSubview(self.swipeView)
    }


    func performAnimation(fromTransform:CATransform3D, toTransform:CATransform3D, duration:CFTimeInterval) {

        var animation:CABasicAnimation = CABasicAnimation(keyPath: "transform")
        animation.delegate = self
        var transformView = transform
        animation.fromValue = NSValue(CATransform3D: fromTransform)
        animation.toValue = NSValue(CATransform3D: toTransform)
        animation.duration = duration
        self.swipeView.layer.addAnimation(animation, forKey: nil)
        self.swipeView.layer.transform = toTransform

    }


    func expandView() {

        if shouldExecuteExpandAnimation {
            performAnimation(CATransform3DIdentity, toTransform: CATransform3DMakeScale(1, 4, 1), duration: 0.1)
            shouldExecuteShrinkAnimation = true;
        }

        shouldExecuteExpandAnimation = false;
    }


    func shrinkView() {

        if shouldExecuteShrinkAnimation {
            performAnimation(CATransform3DMakeScale(1, 4, 1), toTransform: CATransform3DMakeScale(1, 1, 1), duration: 0.1)
            shouldExecuteExpandAnimation = true
        }

        shouldExecuteShrinkAnimation = false;
    }


    func manageViewWithGesture(gestureRecognizer:UISwipeGestureRecognizer) {

            switch gestureRecognizer.direction {

            case UISwipeGestureRecognizerDirection.Right:
                expandView()
            case UISwipeGestureRecognizerDirection.Left:
                shrinkView()
            default:
                break
            }

    }

}

As Aaron says, you can't get intermediate values from a swipe. Nothing happens, then it fires. You need to use a pan gesture recognizer or your own custom gesture recognizer. For this it would probably be easier to interpret the translation values you get from a standard pan gesture recognizer.

You could then use those values to manually make an animation vary from start to finish. I have a project on github that lets you vary an animation from start to finish using a slider.

You could adapt that approach to making an animation run as the user drags a pan gesture.

Check out this link:

KeyframeViewAnimations demo project on Github

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM