I don't like being limited by the built-in screen navigation and storyboards are severely limited so I use this "core window" model I came up with long ago, where one window acts as a foundation. I load another view controller but load a nested UIView inside the main view, I call this the core and animate it over everything but the controls I want to remain onscreen, e.g. status bar and tab bar.
In the past I avoided auto layout because there were only two screen sizes, I just created one resource for each one. Now there are at least four and avoiding auto layout isn't an option. But when I do my nested view trick in XCode with auto layout turned on I can't see the controls in the nested UIView, infuriating, and the interface builder is very limited with AutoLayout.
Changing transparency, Z order, removing size classes, no joy. It's only putting the controls in the nested UIView back in the main view that makes them visible.
I can get around this by scrapping the nested view and making the view controller's main view free form, then coding the controls that AutoLayout doesn't handle well after viewDidlayoutSubviews is called. This works.
But I would really like to know why controls in nested UIViews are invisible in IB. They weren't before.
Edit: the loaded nested UIView does work at runtime.
Related
I am building an iOS app with multiple screens but I want avoid duplication of code as well as one large storyboard. Ideally I would like to load the various View Controllers based on a selected storyboard in my content view when needed.
The template of the screen (Master/Root View) shall be composed by 3 Views, namely:
View A that acts as a Navigation View,
View B where the various View Controllers should be loaded based on user actions and,
View C, much like a Tab bar or a 3rd View where I can display some
circumstantial information.
Now, of course I could go with a traditional UINavigationController and UITabBar but I need greater control over those views, notably in terms of size (they have minimum heights that are larger than the ones for NavBar and TabBar).
I also need those Views to resize based on the Traits and Class Size to keep filling the entire screen.
I am trying to use container views to doing so, but I can't get them to resize automatically despite having tried a different set of constraints in auto-layout. Putting the 3 views in a stackview does not do the trick either.
Ultimately I would like to be able to work separately on my various Controller Views that will be loaded in View B, using their own storyboards, calling them programmatically in B and having everything automatically resized.
Thank you all for your kind and valuable input!
Chris
When using addChildViewController(childVC) / addChild(childVC) (Swift 4.1 / 4.2), followed by myContainerView.addSubview(childVC.view) you need to either
add constraints for the added subview
or
set the frame of the subview and .autoResizingMask
After that, your newly added subview will layout and resize correctly.
I've got a view controller that handles a lot of complex on-screen controls. One of these is a sliding menu that contains 9 UIButton controls drawn in a grid using constraints, like so:
The load time of this view controller is nearly 3 seconds on device, and I've narrowed down the cause to the quantity of UIButtons inside this view. (I originally thought it was because it was being drawn off screen, but moving it to the center of the view controller didn't help).
I'm trying to come up with a way to improve the performance of these buttons, but I'm not really sure which direction to go. Will loading them in a UICollectionView help? Or is there a way to lazy-load the buttons so that they're drawn after the view controller is presented?
Turns out migrating this to a UICollectionView (even using constraints written in code) has made a significant performance improvement to this view controller.
It also has the added benefit of supporting paged views - more than 9 controls in the menu.
I designed about 40 view controllers using a 5.5 inch storyboard layout. After all of that I tested it on the iPhone 4S...big mistake. everything is jumbled together being for a larger screen size. I was able to fix one view controller up using Size Classes. I am wondering if there is any way I can adjust all 40 at the same time, or at least avoid doing this for every single one. It is really frustrating finding this out now. Thanks!
This is a relatively complicated issue you are attempting to solve, but I have two potential solutions. Both suggestions are based on moving your current interface into containing UIScrollView instances
If you are using storyboards, then for each of your view controller scenes, put a UIScrollView as a descendent of the view controller's view. From there, provided your subviews are contained within other views (like a container view for a set of buttons), you can move those into your scroll view. You will have to setup constraints to define the size of the scroll view's content, but this will allow the size of the device to have a smaller impact on the interface as you will get scrolling as needed.
If you are using nib files (.xib) then it is essentially the same thing, but easier. In this case, move a UIScrollView onto the canvas, but not as a subview of the default view. Once that is out there, move the original view to be a subview of the scroll view and set constraints to be 0 from the subview to the scroll view. Finally, right click drag from the File's Owner icon to the scroll view and set that as the view outlet.
Hopefully one of these will help you.
I'm working on a project with a fairly complicated layout that I've developed programatically. The main view consists of 7 different sized views placed vertically with 6 spacer views in-between. All of the spacer views are constrained to be equally tall. According to a loop I'm doing with view.hasAmbiguousLayout, none of my views are ambiguous. I've been extra careful in checking all of the constraints, and the view acts as I expect on different device sizes.
The strange bit happens when I add a contained view controller. I've been using a contained view controller to manage a popup view. This subview has some transparency so I can see the main view below it. If this secondary view has any subviews at all, the main view's layout changes ever so slightly. The moment I add it some of the bottom views move slightly upward.
Is there a cause for this that I am missing or could it just be a bug in ios? (The same thing happens when I build the layout in interface builder)
What is the effect of having a UIView act as a child of another UIView in the scoreboard?
Using AVCam as an example, in the storyboard of the project, the components are layered out as following:
Observe that the 3 Button components act as children of “Cam Preview View”.
I’ve made an experiment and managed to get them to be children of “View”. This does not break any UIButton outlet functionality that I’ve managed to notice.
This is a design time choice by the developer. This changes how the controls can be moved by the constraints or other layout controls like springs and strut). Moving them around will not break any wired outlets however can introduce logical errors.
That said it's possible that there is no significant effect for this demo code.
In the first image you posted, those buttons are added as subviews of the Cam Preview View. It is the same as saying
[camPreviewView addSubview:button];
In the second image instead of the buttons subviews of the Cam Preview View, they are subviews of the View at the top of the hierarchy.
This is a design choice made by the developer. Clearly s/he wanted a view with three buttons contained inside as subviews. That way, you can move the Camera Preview View around and the buttons stay in their relative locations within the view.