I am using storyboard layouts to set up view layout.
I am supporting both iPhone and iPad layouts.
When the view is created with initWithCoder:
, it is initially created with the frame size of the device I was last looking at in Interface Builder.
If I am designing with the iPhone X layout in interface builder and then build and run on an iPad, the view is initially created with iPhone X screen dimensions. Then viewDidLayoutSubviews:
is called and it updates the screen dimensions to the correct iPad size.
The subviews are using
drawRect
inside UIViews to draw the view graphics. I am doing this so I can change graphic colors via code. I change the color variable and then callsetNeedsDispay
on the view to redraw the view with new colors usingCGGraphicsContext
commands.It also allows me to draw any graphic image at any size. And with lots of graphics that means I don't have to include all the different images at 1x, 2x and 3x sizes in my bundle. It's all drawn dynamically.
Some of these images are laid out when the view loads and not in Interface Builder. So I check the screen size and draw the button size and position accordingly.
What happens is, viewDidLoad
is called and it draws the graphics based on the initial screen size.
Then viewDidLayoutSubviews
is called and I have to update the drawing of the subviews I placed manually repositioning them based on new screen dimensions and then calling the drawRect
on them. I feel like this is just unnecessary extra work for the device.
In addition to that, viewDidLayoutSubviews
is called for other reasons then just resizing the view on initial load of the viewController. So then each time it's called it will go redraw the subviews, even if they don't need it.
And, if the device I am running on is the same as the device I was using in Interface Builder, it doesn't call the viewDidLayoutSubviews
. I can't just let the view layout the subviews there because there is no guarantee it will be called.
My solution so far is creating a variable to track the screen width. I set the variable in viewDidLoad
. If it creates the view at iPhone X size, my screenWidthTracker = 1125
. When viewDidLayoutSubviews
is called I compare the current screen size to screenWidthTracker.
if (self.view.frame != screenWidthTracker) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"updateView" object:self];
};
if the view has changed size, it sends a message to redraw views. Any views I have placed manually as subviews are registered to listen for @"updateView".
Is there a better way to manage this? Is there a method that gets called ONLY when screen dimensions change and not when its updating the position of other subviews? Should I be utilizing viewDidAppear? I feel as though that is too late in the chain and I don't want the user to see button size updates.