Home iOS Custom Animation
Reply: 0

iOS Custom Animation

user3692
1#
user3692 Published in May 23, 2018, 6:54 pm

My app needs pop-ups. This pop-up takes up a portion of the screen and the rest of the screen should be filled with black with a fade-in effect. I want the actual view to come up from the bottom with the animation filled in black.

So I used UIViewControllerAnimatedTransitioning to add a black view to the parent view and adjust alpha value while child view controller popping up. UIViewControllerAnimatedTransitioning is not a problem. But I also want to use UIStoryboardSegue for same animation.

I implement this animation with UIStoryboardSegue. This cause problem.


Custom Segue

override func perform() {
    guard let firstView = self.source.view, let secondView = self.destination.view else {
        return
    }

    let screenWidth = UIScreen.main.bounds.size.width
    let screenHeight =  UIScreen.main.bounds.size.height

    secondView.frame = CGRect(x: 0.0, y: screenHeight, width: screenWidth, height: screenHeight)

    guard let window = UIApplication.shared.keyWindow else {
        return
    }

    window.insertSubview(secondView, aboveSubview: firstView)

    firstView.clipsToBounds = false
    let overlayView = UIView(frame: CGRect(x: 0, y: -screenHeight, width: screenWidth, height: screenHeight*2))
    overlayView.tag = 8082
    overlayView.backgroundColor = .black
    overlayView.alpha = 0.0
    firstView.addSubview(overlayView)

    UIView.animate(withDuration: 0.42, animations: {
        overlayView.alpha = 0.5

        secondView.frame = secondView.frame.offsetBy(dx: 0.0, dy: -screenHeight)
    }) { _ in
        self.source.present(self.destination, animated: false, completion: nil)
    }
}

Custom Segue Unwind

override func perform() {
    guard let secondView = self.source.view, let firstView = self.destination.view else {
        return
    }

    let screenHeight = UIScreen.main.bounds.size.height


    let filteredViews = firstView.subviews.filter { (view) -> Bool in
        if view.tag == 8082 {
            return true
        }

        return false
    }

    UIView.animate(withDuration: 0.42, animations: {
        if let overlayView = filteredViews.first {
            overlayView.alpha = 0.0
        }

        secondView.frame = secondView.frame.offsetBy(dx: 0.0, dy: screenHeight)
    }) { _ in
        self.source.dismiss(animated: false, completion: nil)
        if let overlayView = filteredViews.first {
            overlayView.removeFromSuperview()
        }
        firstView.clipsToBounds = true
    }
}

When apply segue, it works properly, and it doesn't matter if I disappear in the right way. The right way is using 'performSegue(with: "unwindTo...")' not using 'dismiss'.

When I using custom segue and want to dismiss the screen, I have to use 'performSegue' when I show popup with 'segue' from any screen. And I have to use 'dismiss' when show popup with 'present'.

There is no problem if I keep this rule. But show popup with 'segue' and disappear with 'dismiss' not using 'perforSegue(with: "unwindID"' cause big problem. The black view is not disappear and I can't do anything.

I distinguished it in the following way. But I think this is not good way.

if shouldPerformSegue(withIdentifier: "unwindToKeywordHelperVC", sender: self) {
    performSegue(withIdentifier: "unwindToKeywordHelperVC", sender: self)
} else {
    dismiss()
}

Is there any other good way?

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.345623 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO