iOS: Top UITableView row bleeds into carrier - ios

The alignment of our table is working well except of the top alignment of the top cell which bleeds into the "carrier area". What is required to address this?
We're using self sizing cells:
override func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = 68.0
tableView.rowHeight = UITableViewAutomaticDimension
Overview of the current constraints:

Basically Apple doesn't want you to do what you're doing. Look at Apple's apps (Settings, Mail, etc.). You will never see a full-screen table view without a navigation bar at the top. So imitate that. Instead of fighting the framework, wrap your view controller in a UINavigationController and let the navigation bar push the top of the table view down for you automatically.

Normally when you use a navigation controller to wrap the view controller, TopLayoutGuide (and BottomLayoutGuide will be set for you and with "Adjust Scroll View Insets" that you can set in the storyboard file, it will automatically set contentInsets of the outermost scrollview for you to accommodate that. But since you don't use a navigation controller to wrap your view controller here, you have like three options.
1. Manually set the frame of the table view to offset for the status bar's height.
We just move the table view down 20 points and make it 20 points shorter. The ideal place is somewhere in your code we know it will be called every time the superview's bound is changed. One of them is in viewDidLayoutSubviews.
Try putting this code in your view controller's code.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.view.superview!.backgroundColor = UIColor.whiteColor()
let insets = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)
self.view.frame = UIEdgeInsetsInsetRect(self.view.superview!.bounds, insets)
}
Please note that I have to set the background color of the superview's to white because the superview (which is likely to be UIWindow) might have no background color and it will make the top part appears black. And normally in the production code, you might want to check whether the superview's bound has really changed before setting the frame.
2. Use UIViewController and add UITableView as subview.
This way Interface Builder will allow you to set the constraints all you want.
3. Just wrap this with UINavigationController
And it will appear like most apps that have a navigation bar on the top. This might not be what you want. But I rarely see a table view without wrapping by a navigation controller.

Select your table view. In the bottom right side of your screen (left of where you drag the objects to the screen) you will see 4 small buttons. If you click on the 2nd to the right (a square with 2 lines to it's sides) you will see a small sub-menu saying Add new constraints. Below it you have a square with 4 values (top-right-bottom-left). Make sure the top one is 0 and then click the semi-transparent dotted red line. It should become solid red. Now just click the "Add constraints" button at the bottom and you are done.

Related

UITableView contentOffset for headerView misaligned

My headerView in my tableView should go all the way to the top of the device. On iPhone X the same so the notch goes over it.
Then when I scroll my tableView I use scrollViewDidScroll(scrollView: UIScrollView) to change the height of my headerView to add scrollView.contentOffset.y so it goes all the way.
It works as soon as I scroll but not initially.
So it looks like this:
and this on the X
How to I get rid of the white area so the grey one goes under it when it loads?
I tried a couple places but it seems the tableView still has no contentOffsets... I think I am missing something fundamental here how "it should be done"...
Update: ViewHierarchy, blue is tablewView, but then I get this distance there...
Ok I found it. So it has to do with the change with safe areas introduced for the iPhone X.
There are two possibilities, it really depends on the storyboard setup:
If you are using a storyboard and your base is a UIViewController with a tableView placed inside it:
Then fixing the auto layout is the answer:
When safe area is enabled, click on your topmost view and create the top constraint is relative to the superView with constant 0. By default it wants to protect the safe area so it is set relative to the safe area.
If you are using a UITableViewController template (e.g. default when dragging out a navigation controller - tableview combo (my case))
Here there are no constraints that can be set. Hence it didn't work for me (see above).
To fix it click on the root tableView, select the size inspector and then set "content insets" to "never".
Or programmatically in viewDidLoad:
self.tableView.contentInsetAdjustmentBehavior = .never
Are you making your tableview in storyboard?
in viewDidLoad try anchoring your tableview:
tableview.topAnchor.constraint(equalTo: view.topAnchor).isActive = true

Swift: TableViewController in NavigationController - Change distance between first static cell and top

Ive created just a new xcode project without any coding. I just worked in the storyboard. There I have a Navigation Controller. My RootViewController has a TableView with Static cells in 3 sections (Grouped). The Section headers I deleted. My next step was to change the distances between the sections. For top I said 4 and for bottom 4, too. It looks now like this:
Now my problem: The size between the first section and the top is really big (I think 32 because thats the automatic distance between the sections). THe only place I found something was the size inspector - Content Insets. This is set to automatic. With no option I can put some values in myself. If I choose never there, the section got displayed under the Root View Controller header. My size inspector looks like this:
Can anyone tell me how I can reduce the size between viewController top and first section? Exactly I want to have a size of 16 between first section and the header of the Root View Controller.
And is there a way to do a change for the complete project so that also upcoming navigation controllers will have their tableview with a size of 16 between first section and the header?
What Ive tried: I found this question Why is there extra padding at the top of my UITableView with style UITableViewStyleGrouped in iOS7 Here someone asked for tableViews in general. The solutions I readed there which didnt worked for me:
Turn Adjust scroll view insets off. I tried this for the root as well as the navigation controller. I also tried to solve the problem in code.
Set edgesForExtendedLayout to none in viewDidLoad - nothing changed.
Set the header just for first section to 1.
self.navigationController?.navigationBar.isTranslucent = true changed nothing
Half correct: One solution was changing the contenInset manually in code. I dont like this because I would have to type the 16 points hard in my code. I dont know there the header of 32 comes from. So I dont know if the 16 points will stay forever. So I want a safer solution for future as well. THis was the hard solution:
self.tableView.contentInset = UIEdgeInsetsMake(-16, 0, 0, 0)
That top space comes from grouped style tableView header. You can add your own table header view at top of the table, set its color to "Group Table View Background Color", and set its height to what you want (16).
iOS11 Pure code Solution
Anyone looking to do this in pure code and remove the 35px empty space needs to add a tableHeaderView to their tableView - it appears having it as nil just sets it as default sizing of 35px
i.e.
tableView.tableHeaderView = tableHeaderView
var tableHeaderView:UIView = {
let view = UIView()
view.frame = CGRect(x: 0, y: 0, width: tableView.bounds.width, height: CGFloat.leastNormalMagnitude)
return view
}()
Note device width would be your bounds/view width and height is NOT 0 - but CGFloat.leastNormalMagnitude

iOS layout view to fill device screen

This should be a very basic question, but I have tried a lot of things and it isn't working. :/
I have a single view application which consists of a single, full-screen custom view. I had my view class set on the main view of the view controller, but the status bar was always overlaid on my view.
Apple says to fix this, constrain your view to the top layout guide, but that requires I move my view to be a child of the main view. So I moved it, but now I can't set up constraints to simply make my view fill 100% of vertical and horizontal space.
I have tried doing it in code, using constraints, stacked views, anything I can find, but to no avail.
So, the hopefully simple question is, how can I make a single UIView child of the main view of a view controller size to fill the container and account for the status bar? The UIView is a custom class, so if code is needed I can do that.
I have tried overriding the intrinsic and size that fits methods, but they created terrible results.
You can do this programmatically:
let childView: UIViewCustom = UIViewCustom()
childView.frame = rootView.frame
childView.bounds = rootView.bounds
rootView.addSubview(childView)
Or via IB:
first select your childView, then click on the pin button in the low-right corner of XCode, disable Constrain to margins, then click on each red bar and set to zero the constrain. Finally click on Add 4 Constraints
Hope it helps.
try this:
0.Assume that you have a custom class just for View (not ViewController) named AAA.
in Main.storyboard, drag a "View" from Object Library to your ViewController. Call it ViewB.
2.set the viewB layout and constrains
3.select the viewB and go to its identify inspector(3rd small button on the right panel)
4.in the class section: write it as: AAA
Hope this will help you.

Adding margin to TableViewController

I am experimenting with Xcode 6 and Swift and having a little issue with the Interface Builder.
I created a new scene by dragging a TableViewController which comes with a TableView however when run it on a simulator the top cell is far too close to the top, it almost touches the central Date and Carrier logo.
As this seems to be a root view, I cannot add constraints, I also cannot find a way to adjust so that I have a margin that is flexible / responsive to different screen size.
You don't want to try to constrain the table to underneath the status bar, as this will cause the content of the scroll view to magically vanish as it goes above the 20pt mark. Instead, allow it to continue to be full screen and simply set the table's contentInset property (More info in documentation).
This will cause the table to scroll as it normally would with the content going out the top of the screen, with the added ability to come to rest just under the status bar.
let statusBarHeight = UIApplication.sharedApplication().statusBarFrame.height
tableView.contentInset = UIEdgeInsetsMake(statusBarHeight, 0.0, 0.0, 0.0)

UIPageViewController resize child view to reserve space for itself

I am developing an iPhone application for ios 7.1. The ViewController hierarchy is like "NavigationController -> UIViewController -> UIPageViewController -> UITableViewControllers". NavigationBar is hidden. Status bar is present. Everything is done programmatically. No storyboard/Xib is used.
In the UIPageViewController, I am creating a custom Title view (similar to the Navigation bar, but inside its own view). Hence the child controller's view (UITableView) should be pushed below this Title View. I have tried adding a constraint ("V:[TitleView]-0-[ChildView]"), after setting translatesAutoresizingMaskIntoConstraints of child view to NO. But this resulted in a blank screen (except for the title view). Changing frame of the child view etc and all did not have any effect.
Apart from setting the above flag and adding the constraint, I have not added/modified any auto layout/auto resize related settings. The application supports only the portrait mode (Home button down). There is not going to be any other dynamic layout change either. Appreciate if you could help in resolving this issue.
Following is the solution I ended up with as of now. Project was on hold for some time, and now being rewritten in Swift. Hence the below code is in swift.
//in the UIPageViewController
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()
let scrollView = view.subviews[0] as UIView
scrollView.frame = CGRectMake(scrollView.frame.origin.x, 64, scrollView.frame.size.width, scrollView.frame.size.height - 64)
}
Basically I am moving and resizing the Page controller's default scroll view below my title view. I have to admit that I am not very happy with the solution. I feel that there must be some better alternative. (To make it safer, you can iterate the subviews to find the scroll view).
Look at the autoresize constraint from your page view controller and set it to false.
I think it's not the child which are autoresize but the pageviewcontroller frame.

Resources