2

I'm working on making an iOS app.

Now I'm stuck to do the following stuff.

  • detail screen is popped up as modal screen
  • user wants to close the modal window by dragging down like Twitter's photo screen

And I tried to code by reference to How to use UIPanGestureRecognizer to move object? iPhone/iPad

My code looks like below. It makes tableView move to strange direction and then close the modal.

var firstX: CGFloat = 0
var firstY: CGFloat = 0
var finalX: CGFloat = 0
var finalY: CGFloat = 0

override func viewDidLoad() {
    super.viewDidLoad()
    let recognizer : UIPanGestureRecognizer = UIPanGestureRecognizer(target: self, action: "move:")
    recognizer.minimumNumberOfTouches = 1
    recognizer.maximumNumberOfTouches = 1
    self.tableView.addGestureRecognizer(recognizer)
}

func move(sender : UIPanGestureRecognizer) {
    print("move")

    self.view.bringSubviewToFront(tableView)
    var translatedPoint : CGPoint = sender.translationInView(self.view)
    if sender.state == UIGestureRecognizerState.Began {
        firstX = 0 // (sender.view?.center.x)!
        firstY = (tableView?.center.y)!
    }
    translatedPoint = CGPointMake(firstX+translatedPoint.x, firstY)
    tableView?.center = translatedPoint

    if sender.state == UIGestureRecognizerState.Ended {
        let velocityY = 0.2 * sender.velocityInView(self.view).y
        finalX = firstX //translatedPoint.x + velocityX
        finalY = translatedPoint.y + velocityY

        if (UIDeviceOrientationIsPortrait(UIDevice.currentDevice().orientation)) {

            if finalY < 0 {
                finalY = 0
            } else if finalY > 1024 {
                finalY = 1024
            }

        } else {

            if finalY < 0 {
                finalY = 0
            } else if finalY > 768 {
                finalY = 1024
            }
        }

        let animationDuration = ( abs(velocityY) * 0.0002 ) + 0.2

        UIView.beginAnimations(nil, context: nil)
        UIView.setAnimationDuration(Double(animationDuration))
        UIView.setAnimationCurve(UIViewAnimationCurve.EaseOut)
        UIView.setAnimationDelegate(self)
        UIView.setAnimationDidStopSelector("animationDidFinish")
        self.view.center = CGPointMake(finalX, finalY)
        UIView.commitAnimations()


    }
}

func animationDidFinish() {
    print("animationDidFinish")
    if finalY > 50 {
        self.dismissViewControllerAnimated(true, completion: nil)
    }

}

Does anyone point me to the right direction? Thanks in advance.

Community
  • 1
  • 1
raimtoon
  • 725
  • 1
  • 11
  • 27

1 Answers1

0

You will need to create a custom modal animation. You should read Customizing the Transition Animations from the Presentation and Transitions section of the View Controller Programming Guide for iOS.

Specifically there is a part in there on Adding Interactivity to Your Transitions, but you will probably need to read more than just that part to understand.

In short, you will have to create an implementation of UIViewControllerTransitioningDelegate and assign that to the transitioning delegate of the view controller being presented. The job of the UIViewControllerTransitioningDelegate is to vend a number of other objects to UIKit that handle a custom animation (and optionally presentation) for presenting and dismissing the view controller.

In addition to your implementation of UIViewControllerTransitioningDelegate you will also have to create implementations of UIViewControllerAnimatedTransitioning and UIViewControllerInteractiveTransitioning. These objects will ultimately be the ones performing the relevant animations, and they are the objects vended to UIKit by your UIViewControllerTransitioningDelegate implementation.

Charles A.
  • 10,685
  • 1
  • 42
  • 39
  • I don't have any that I could post. Almost certainly though there are examples of using these APIs available in the documentation and/or from WWDC sessions. – Charles A. Mar 24 '16 at 22:15