andreamazz / BubbleTransition

A custom modal transition that presents and dismiss a controller with an expanding bubble effect.
MIT License
3.32k stars 250 forks source link

destinationViewController's autolayout doesn't work. #17

Closed bianjingbulb closed 6 years ago

bianjingbulb commented 8 years ago

Hi, friend! Thanks for you great work. Here is a problem. The destinationViewController's autolayout doesn't work after I user BubbleTransition to present it.

qq20160307-2 2x

↑ my storyboard

qq20160307-1 2x

↑ devise screen.

Can you give me some ideas?

Thanks!

andreamazz commented 8 years ago

Hi @bianjingbulb If you use a standard modal transition the view is there?

bianjingbulb commented 8 years ago

@andreamazz thanks for replying me!!! I pushed the view like this ↓ let newPersonPostViewController = NewPersonPostViewController() self.presentViewController(newPersonPostViewController, animated: true, completion: nil)

andreamazz commented 8 years ago

Ok, but if you remove the bubble transition (and perform the system transition instead), does the issue go away?

bianjingbulb commented 8 years ago

Yes. ↓Like this.

qq20160309-1 2x
andreamazz commented 8 years ago

Can you provide a sample showing this issue? Or at least reproduce the issue in the demo project? I'm having trouble reproducing this.

donpironet commented 8 years ago

I've got the same problem. When using everything in full code the destination controller layout constraints are broken...

andreamazz commented 8 years ago

Please provide a sample showing the issue, I can't debug something that I can't reproduce.

donpironet commented 8 years ago

I just tried it in a new project and now it works. In my real app it doesn't. Then the constraints are broken. In the top left corner you see a label with some text and the constraints are center in middle of viewcontroller..

http://i65.tinypic.com/f37s4o.png

donpironet commented 8 years ago

I found the problem in my real app my ViewControllers have a BaseViewController that does some things. If I use this controller as base then it doesn't work:

class BaseViewController: UIViewController {

    // MARK: - Properties

    private var didSetupConstraints: Bool = false

    // MARK: - LifeCycle

    override func viewDidLoad() {
        super.viewDidLoad()

        self.setupNavigationBar()

        self.navigationController?.interactivePopGestureRecognizer?.delegate = self
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
    }

    override func loadView() {
        self.view = UIView()
        self.view.backgroundColor = UIColor.whiteColor()

        self.setupLoadView()

        self.view.setNeedsUpdateConstraints()
    }

    override func updateViewConstraints() {
        if !self.didSetupConstraints {
            self.setupConstraints()
            self.didSetupConstraints = true
        }

        super.updateViewConstraints()
    }

    // MARK: - Helpers

    func setupNavigationBar() {
        self.navigationItem.title = self.setupTitle()
    }

    func showWarningWithMessage(message: String) {
        self.showAlert(message, title: "Warning")
    }

    func showErrorWithMessage(message: String) {
        self.showAlert(message, title: "Error")
    }

    func showSuccess(message: String) {
        self.showAlert(message, title: "Success")
    }

    private func showAlert(message: String, title: String) {
        let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)

        let defaultAction = UIAlertAction(title: "Ok", style: .Default, handler: nil)
        alertController.addAction(defaultAction)

        presentViewController(alertController, animated: true, completion: nil)
    }

    func setNavigationBarTransparant(transparant: Bool) {
         self.navigationController?.navigationBar.translucent = transparant
    }

    // MARK: - Controller specific overrides

    func setupLoadView() {
        fatalError("Should be overwritten")
    }

    func setupConstraints() {
        fatalError("Should be overwritten")
    }

    func setupTitle() -> String {
        return ""
    }
}

// MARK: - UIGestureRecognizerDelegate

extension BaseViewController: UIGestureRecognizerDelegate {
    func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {

        if navigationController?.viewControllers.count == 2 {
            return true
        }

        if let navigationController = self.navigationController as? CustomNavigationController {
            navigationController.showControllers()
        }

        return false
    }
}
ozgur commented 7 years ago

I observed the same issue. My destination view controller has map view and it doesn't zoom to correct map area to show all annotations because its frame wasn't set correctly by this animator.

The problem is about using presentedViewController.center and presentedViewController.frame.size as the originalCenter and originalSize. They return the same frame and center values as the ones that are returned in presentedViewController.viewDidLoad which means they are highly inaccurate so can't be trusted. What you should do is to use the final frame of destination view controller at the end of the transition to set its center and the problem should go away:

if transitionMode == .present {
  ...
  let finalFrame = transitionContext.finalFrame(for: toViewController!)
  let originalCenter = CGPoint(x: finalFrame.width / 2, y: finalFrame.height / 2)
  let originalSize = finalFrame.size
  ...
  // Inside the animation block, set the frame: 
  UIView.animate(withDuration: .. {
    ...
    presentedControllerView.frame = finalFrame
  }
andres-cianio commented 7 years ago

I'm facing this same issue... Anyone care to share how to fix it? @ozgur @donpironet @andreamazz

ozgur commented 7 years ago

@andreamazz maybe you have an update on this? To me, a new PR is likely needed.

andreamazz commented 7 years ago

Again, I need a sample that reproduces the issue to test it. If you have found the solution, a PR is always welcome.

lupugabriel commented 6 years ago

I had the same problem as you. This was solved putting the ViewController inside a storyboard. in a xib does not work

andreamazz commented 6 years ago

Closing this for now. Feel free to reopen if you have sample code to reproduce the issue, or even better a PR.

Erumaru commented 5 years ago

I've had the same problem, because I use xib. My workaround: presentedVC.view.frame = presentingVC.view.bounds

Steps to reproduce (I'm not sure): 1) Create vc in xib 2) Change vc size (Set other iPhone representation) 3) Make bubble transition

Transition uses size from xib