Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Auto Layout problems

I'm having a hard time getting a real layout to work using auto layout. I've watched all the easy tutorials on basic stuff but sizing for the 3 screens is a pain.

This is my basic layout, I need the items below to maintain a consistent ration between each other but grow and shrink between the iphone sizes otherwise the iphone 6+ would have large amount of white space below the items. My thought was that the distance between the items top and bottom lines would shrink/grow.

I've tried adding the constraints and equal heights, putting less or equal on the lines but it just makes them all out of wack. One will be smaller than the other for them to fit.

here's a quick mockup

example link


header



item 1


item2


item3


item4

Thanks for any help.

Keith

10 Answers

you should be able to programatically set the row height in viewDidLoad. since you have 4 cells, set the row height to the height of the entire view divided by 4.

override func viewDidLoad() {
super.viewDidLoad()

// 4 cells, so divide the height of the view by 4
tableView.rowHeight = tableView.frame.size.height / 4
}

in theory, that should set the row height to where all 4 cells fit exactly in the frame on all devices. this is assuming a plain tableView without a header/navbar etc. you may have to fiddle around with that if you have a tableHeader/nav bar etc (in that case you would need to subtract the heights of those from the frame before performing the division)

Now, in my mind I think it would look best if the cells were a set row height (44 is the default) on all devices. but if you want the row height to change, I think the above code will do what you want

That worked great! I see what you are saying about the row height but I don't want to show any more than four or have any blank space below.

I disabled user interaction and added this: tableView.scrollEnabled = false

The only problem is the tableView is being shifted to the right about 20px. It's aligned to the edge and the x & y is 0. I added this but it didn't really do anything. tableView.separatorInset.left = 0

Thanks for all the help.

are you deploying for iOS 8? if so try adding the following code in viewDidLoad:

tableView.layoutMargins = UIEdgeInsetsZero;

iOS 8 introduced margins so the above code should fix the 15px default left margin

are you only going to have 4 items?

are you saying that you want the tableView items to take up the whole screen and have no blank cells below the occupied ones?

Thanks for the reply. Yeah, 4 static items, I might add a footer at some point. I'm not using a table view though just lines as an image between the text label.

Keith

Yeah, 4 static items, I might add a footer at some point. I'm not using a table view

you probably should try and use a table view controller since this is generally the situation you use them in. you can create static tables with a tableView controller which is exactly what you want (you just change the tableView attributes from prototype cells to static cells, then drag UITableViewcells onto it, create sections etc)

im sure how it will handle the blank space, but doing what you are doing now is probably not the best idea

Thanks again for replying. I didn't really think to use a table view controller. My code is all setup to have that screen a regular view controller, maybe I can add a table view inside it and just add 4 dynamic titles. I just liked having the freedom to easily customize the text and add an icon next to it without doing it all in code.

maybe I can add a table view inside it and just add 4 dynamic titles.

unfortunately static cells are only supported inside tableViewControllers, not tableViews inside regular viewControllers.

Okay, I guess I'll make a dynamic table view. Just to make sure, these aren't selectable table items these are just a bunch of labels that look like a table because of the style i'm doing.

thats fine. you can disable selection in the attributes of the tableView.

Thanks, I'll mess with this for awhile and post back.

I've got that all working and it lays out nicely with a dynamic table view and icons next to the text. I'm still having trouble getting it stretch/shrink though. Basically the row height is what needs to adjust.

That helped, it moved it over 15 like you said but there is still a little left. It's weird, even when I pin left and right with 0 it still has it.

remove the constraints and repin them. when you pin the next time make sure "pin to margins" or whatever it says is unchecked. that might be whats doing it

Weird, still doing it. I did what you said, unchecked that and did 0 left and right.

can you post a screen shot of what your app looks like when you run it

Sure here is the test i've been working on

table view test

you could try setting a negative inset:

tableView.layoutMargins = UIEdgeInsets(top: 0, left: -15, bottom: 0, right: 0)

you may have to play around with the value a bit to get it right

I tried that but it won't go left anymore, it does go all the other directions in positive numbers

I just increased the size past the margins and moved everything outside. I guess that would work.

see my other answer about implementing willDisplayCell. if it works its probably a better solution that increasing the size

you may need to set the layout margins of the cells in addition to the tableView. try implementing the following tableView data source method in your tableViewController:

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {

tableView.seperatorInset = UIEdgeInsetsZero
tableView.layoutMargins = UIEdgeInsetsZero
cell.layoutMargins = UIEdgeInsetsZero
}

source: this stack overflow post

Awesome, cell.layoutMargins = UIEdgeInsetsZero is the winner!

I really appreciate you taking the time for this.

no problem. glad its finally looking how you want it