Table View Controllers created in Interface Builder have their bottom cells clipped and obscured on iPhone X - ios

If a Table View Controller is created using Interface Builder, on iPhone X the lowest visible cell will be obscured by the home screen indicator, and the cell's corners clipped by the curved screen, by default - see screenshot below.
If I use a View Controller and insert a Table View, then set it up by hand, I can use the bottom layout guide with the table view, to ensure this obscuring and clipping behavior doesn't happen, i.e., by not allowing the table view to extend into the curved part of the screen.
I'm upgrading a few legacy apps, and I'd prefer not to have to convert the existing Table View Controllers into View Controllers if possible. How can I make Table View Controllers created with Interface Builder behave?
According to the Apple docs, by using the standard interface elements this shouldn't be a problem.
Inset essential content to prevent clipping. In general, content
should be centered and symmetrically inset so it looks great in any
orientation and isn't clipped by corners or the device's sensor
housing, or obscured by the indicator for accessing the Home screen.
For best results, use standard, system-provided interface elements and
Auto Layout to construct your interface. All apps should adhere to the
safe area and layout margins defined by UIKit, which ensure
appropriate insetting based on the device and context.

If you enabled automaticallyAdjustsScrollViewInsets, table view will be upon home indicator when you scroll to bottom. I think this is what Apple wants, take advantage of the full screen at the same time every elements can be interacted.
If you want cells never obscured or clipped in UITableViewController. I suggest you use plain style table view, set contentInset to make section footer hovered under home indicator. I tried this, It worked but looked ugly. Like this:

In the end, I converted the Table View Controllers into View Controllers and added a bottom alignment constraint to the Table View

Related

iOS Auto Resizable Container Views

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.

ios 8 layout using uitableview static cell & uitableview dynamic prototypes

I work on a app, nothing fancy, but since is my first app, there alot of stuff I never did before.
So, I'm trying to build a view like the image attached.
I've looked up on the Internet how to do something like that but I don't know what is better/cleaner way to do.
As you can see I have 3 areas: the title, the tableview in the middle and a button on the lower side.
The table will expand based on the content (3 lines or 30 lines) so the button must move down and a scroll bar should appear.
So, my idea:
Using a tableview having 3 static cells: one to put my title, second to put a tableview having prototypes cells, and a third one for the button.
That way I would have a scroll bar when the table in the middle grows, pushing the button.
Here I have a question: how to have the table view (the inner tableview) resize itself, pushing the height of the middle row, instead of having a fixed width with a scroll.
Is the the best way to achieve that?
Thanks for any idea.
C.C.
Are you sure you want to push the bottom UI down as the table grows? You say whether the table has 3 or 30 cells, but what if it has 300 cells? Your user then has to scroll to the bottom to reach the button and tab bar. I think you'll find that it would be better to use Auto Layout and let the table fill the screen space between the title and the button. The table will scroll so if you have 300 cells then you can scroll through inside the table's available area.
The advantage here is you won't be fighting with Auto Layout. If your user rotates an iPhone 4S into landscape you'll only have a few rows displayed but conversely if they run in portrait on an iPad you'll fill all of that space.
As for how to do it, the other advantage is that you don't need the nested table you describe. Use a constraint to attach the title label to the top layout guide, then attach the tab bar to the bottom layout guide. Put a vertical space constraint between the button and the tab bar. Finally, put vertical space constraints between the table and the title & the table and the button. (You'll need to implement constraints for the horizontal axis as well, but that's pretty simple.)
There's are refinements you can put into place if you want the table to shrink to fit if there are only 3 rows, but this should get you started and you may not want that anyway.
Key point: the tableView wants to scroll naturally, inside a view sized to fit the display. Don't change that behavior unless you really have to. Neither your users nor UIKit expects what you're trying to do, and the table is going to fight you all the way about it.
Nesting UIScrollViews (which your nested table would do) works, but it opens up a lot of bad UI flow problems. In my experience every time somebody wants nested scrollViews there's some other approach which is more "natural" to iOS interface paradigms.
If you're dead set on the UI you described I wouldn't use a table for the outer structure. Just make it a UIScrollView and calculate your content size based on the number of rows the table will display. You can actually do that, and then use Auto Layout as I described.

UITabBarController: Tab bar covers view

I am fairly new to UI elements in iOS (all of my apps were Gl games) but I'm trying it out and I found myself in a bit of a pickle...
The view controller for the bulk of my app is a subclass of UITabBarController and I have a few tabs with (currently empty) child view controllers. For the most part I have these working fine, but my problem is with correctly sizing and placing items inside of a tabbed view controller. If, for instance, I try to place something just above the tab bar, then I can't just set the Y position to the height of the the child view controller's view minus the height of the object I'm placing. I also need to account for the tab bar itself.
I can see that part of my problem is that I'm simply creating the view controller and not telling it what size it's view needs to be. Is there a function provided to me to calculate the height the view needs to be? I could just figure out the height of the bar and subtract that from the overall height, but that just feels to flimsy to me.
Any ideas?
EDIT:
I am doing it all programmatically and I don't intend to use Interface Builder. My main concern with the view size is making sure that things like table views fit snugly.
If you are using Interface Builder and auto layout, you can place UIView items on your UIViewController and if you set a size constraint on the view you're placing you can also set position constraints that are relative to screen edge or adjacent views, in your case UITabBar.

iOS Contained View Controller Caused Auto layout Issues

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)

Xcode 6.1 IOS really long form

I am quite new to xcode.
I am trying to create a contact details form for an iPhone using the storyboard. The problem is that form is longer than the display and I can't work out how to design it using the storyboard.
Any ideas?
Tom
In IB, you can set the controller's size in Simulated Metrics to Freeform, then select the view and make it as tall as you want. Then, add a scroll view to take up the whole view, and add your UIElements, and lay them out how you want. When you run the app, the view controller will still only be as big as the screen (obviously), but the scroll view will be as big as you made the view in IB (you may need to increase its contentSize even more to be able to scroll to the bottom).
Such forms are often made in storyboards using a UITableView and setting the "content" of the table to be "Static Cells." You can set any number of cells and the contents of the cell you want. The table itself is scrollable inside the storyboard/Interface Builder editor and looks much the way it would when presented to a user.
First, select the tableView on the left
Then, you can move it simply scrolling (on mac, two fingers on the trackpad, or using the mouse wheel)
You should have a look at UIScrollView, it is designed to support content larger than screen size (like you see in web browser or settings)
Basic usage is:
//Set a size which will be able to cover all form elements
[yourScrollView setContentSize:CGSizeMake()];
//Your scrollView now extends from CGPoint 0,0 to contentSize.width,contentSize.height.
//Your subviews should be positioned according to scrollview's bounds not the viewcontroller.view or any other container view.
//Add all the form elements
[yourScrollView addSubview:...];
[yourScrollView setDelegate:self]; //If you need actions after user scrolled etc.
Have a look at the developer manual for more info. Most method names are quite self explanatory.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIScrollView_Class/Reference/UIScrollView.html

Resources