Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

StackOverflow Point

StackOverflow Point Navigation

  • Web Stories
  • Badges
  • Tags
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Web Stories
  • Badges
  • Tags
Home/ Questions/Q 2945
Alex Hales
  • 0
Alex HalesTeacher
Asked: June 1, 20222022-06-01T20:46:37+00:00 2022-06-01T20:46:37+00:00

ios – Layout not working when container view controller dynamically changes child view controller

  • 0

[ad_1]

I have a MainViewController that contains a ContainerViewController.

The ContainerViewController starts out showing childViewControllerA, and dynamically switches it out to childViewControllerB when a button in the childViewControllerA is clicked:

func showNextViewContoller() {

    let childViewControllerB = ChildViewControllerB()

    container.addViewController(childViewControllerB)
    container.children.first?.remove()  // Remove childViewControllerA
}

Here’s a diagram:

flow diagram for app

The second view controller (ViewControllerB) has an image view that I’d like to show in the center. So I assigned it the following constraints:

imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFill
   
    NSLayoutConstraint.activate([
        imageView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
        imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        imageView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.6),
    ])

The problem I’m running into is the imageView is not centered vertically: It’s lower than it should be.

When I run the app so that ContainerVeiwController shows childViewControllerB first, then it works as intended. The issue occurs only when childViewControllerB is switched in dynamically after childViewControllerA:

enter image description here

To help debug, I added the following code to all three ViewControllers:

override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        print("MainViewController bounds = \(self.view.bounds)")
    }

And this gave an interesting print out (running this on an iPhone 13 mini simulator):

MainViewController bounds = (0.0, 0.0, 375.0, 812.0) //iPhone 13 mini screen is 375 x 812
ChildViewControllerA bounds = (0.0, 0.0, 375.0,738.0). // 812 - 50 safety margin - 24 titlebar = 738.

Now, the switch happens after the button was clicked and childViewControllerB is added:

ChildViewControllerB bounds = (0.0, 0.0, 375.0, 812.0)

It seems like ChildViewControllerB is assuming a full screen size and ignoring the bounds of it’s parent view controller (ContainerViewController). So, the imageView’s hightAnchor is based on the full screen height, causing it to appear off center.

So, I changed the constraints on the imageView to:

NSLayoutConstraint.activate([
        canvasView.centerYAnchor.constraint(equalTo: super.view.centerYAnchor),
        canvasView.centerXAnchor.constraint(equalTo: super.view.centerXAnchor),
        canvasView.heightAnchor.constraint(equalTo: super.view.heightAnchor, multiplier: 0.6),
    ])

Next, I tried to force a layout update by adding any of these lines after the switch happens in showNextViewController() function above:

container.children.first?.view.layoutSubviews()

//and

container.children.first?.view.setNeedsLayout()

None of them worked.

How do I get ChildViewControllerB to respect the bounds of ContainerViewController?

If it helps, the imageView only needs to be in the center initially. It’ll eventually have a pan, pinch and rotate gesture attached, so the user can move it anywhere they want.

Edit 01:

This is how I’m adding and removing a child view controller:

extension UIViewController {
    func addViewController(_ child: UIViewController) {
        addChild(child)
        view.addSubview(child.view)
        child.didMove(toParent: self)
    }
    
    func remove() {
        guard parent != nil else { return }
        willMove(toParent: nil)
        view.removeFromSuperview()
        removeFromParent()
    }
}

[ad_2]

  • 0 0 Answers
  • 4 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report
Leave an answer

Leave an answer
Cancel reply

Browse

Sidebar

Ask A Question

Related Questions

  • xcode - Can you build dynamic libraries for iOS and ...

    • 0 Answers
  • bash - How to check if a process id (PID) ...

    • 3 Answers
  • database - Oracle: Changing VARCHAR2 column to CLOB

    • 5 Answers
  • What's the difference between HEAD, working tree and index, in ...

    • 4 Answers
  • Amazon EC2 Free tier - how many instances can I ...

    • 0 Answers

Stats

  • Questions : 43k

Subscribe

Login

Forgot Password?

Footer

Follow

© 2022 Stackoverflow Point. All Rights Reserved.

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.