views:

5329

answers:

12

When using a UITableViewController, the initWithStyle: method automatically creates the underlying UITableView with - according to the documentation - "the correct dimensions".

My problem is that these "correct dimensions" seem 320x460 (the iPhone's screen size), but I'm pushing this TableView/Controller pair into a UINavigationController which is itself contained in a UIView, which itself is about half the height of the screen.

No frame or bounds wrangling I can come up with seems to correctly reset the table's size, and as such it's "too long", meaning there are a collection of rows that are pushed off the bottom of the screen and are not visible nor reachable by scrolling.

So my question comes down to: what is the proper way to tell a UITableViewController to resize its component UITableView to a specified rectangle?

Thanks!

Update I've tried all the techniques suggested here to no avail, but I did find one interesting thing: if I eschew the UINavigationController altogether (which I'm not yet willing to do for production, but as an experiment), and add the table view as a direct subview of the enclosing view I mentioned, the frame size given is respected. The very moment I re-introduce the UINavigationController into the mix, no matter if it is added as a subview before or after the table view, and no matter if alloc/init it before or after the table view is added as a subview, the result is the same as it was before.

I'm beginning to suspect UINavigationController isn't much of a team player...

Update 2 The suggestion to check frame size after the table view on screen was a good one: turns out that the navigation controller is in fact resizing it some time in between load and display. My solution, hacky at best, has been to cache the frame given on load and to reset it if changed at the beginning of tableView:cellForRowAtIndexPath:. Why there you ask? Because it's the one place I found that worked, that's why!

I don't consider this a solution as it's obviously improper, but for the benefit of anyone else reading, it does seem to work.

+5  A: 

Why not just use a regular UIViewController and create the table manually?

Ben Gottlieb
+1  A: 

I agree with Ben's answer. I've often run into the situation where I need to resize a UITableVIew due to other controls on a view.

I usually just have a regular UIViewController with a UITableView IBOutlet. Then, if I need to, I can just manipulate the UITableView object's frame to get it to the size I need.

drewh
Care to elaborate on exactly how you accomplish this?
rpj
A: 

I must be doing something incorrectly, because even using the solution presented doesn't seem to work. Ie: even using a bare UIViewController (well, a subclass of one), I still run into the same problem.

Here is example code:

CGRect oFrame = theEnclosingUIView.frame;
oFrame.origin.x = 0;
oFrame.origin.y = 44;
oFrame.size.height -= 44;

NSLog(@"FRAME: %@", NSStringFromCGRect(oFrame));
UITableView* table = [[UITableView alloc] initWithFrame:oFrame style:UITableViewStylePlain];
_tableControl = [[MyUIViewControllerSubclass alloc] init];
_tableControl.view = table;
table.delegate = _tableControl;
table.dataSource = _tableControl;
_navControl = [[NavController alloc] initWithRootViewController:_tableControl];

The NSLog prints a frame size that appears correct ({{0, 44}, {320, 199}}) given that theEnclosingUIView's height is 243), but again I have rows that are unreachable. When trying to scroll to them, they appear but the "bounce" happens above the unreachable rows, making them unclickable.

Thanks again for the help everyone.

rpj
did you try assigning the frame in the viewWillAppear: method? Also, if that doesn't work, try something ridiculously small, like a height of 50, and see if that shows on screen.
Ben Gottlieb
I did; I tried assigning the height to something even as small as 10, but with not luck. Could it have something to do with the table calling tableView:heightForRowAtIndexPath: and erroneously adjusting its frame based on the return(s) from that call?
rpj
no, that just controls the height of the content, not the container. Have you tried logging the frame after the view is onscreen?
Ben Gottlieb
+1  A: 

I'm not sure why you're creating an additional view controller for your table. However, in your code, I don't see you adding the table view to its parent. You might also try reducing the bounds height until the whole thing appears on screen; once you do that, it may give you insight as to why it's not working the way you expect.

Ben Gottlieb
I need a view controller to be able to push onto a UINavigationController, hence why it's there. As such, I was under the impression it wasn't necessary to add the table view to the parent view, because the view controller takes care of that by proxy. Am I missing something?
rpj
Are you assigning the view outlet of MyUIViewControllerSubclass to your table, or its enclosing view?
Ben Gottlieb
As shown in the code I posted as an "answer", I'm definitely assigning the 'view' outlet to the table that I've just created.
rpj
+1  A: 

Check the autoresizingMask and contentMode properties of the UITableView. These can both affect the frame.

davidcann
A: 

If you are using Interface Builder, you can simply go to "Table View Size" properties window, and change Bottom Insets for both Content and Scroller with the height of another widget.

leonho
A: 

Ryan - I've been struggling with the same problem -- no amount of frame setting in the "right" place and disabling autoresizing and such helped. BUT your fix (hacky as it may be) works!

FWIW, in an, uh, upcoming software release, this weird overly-aggressive-autoresizing behavior has changed, such that the hack isn't necessary. But until that reaches my user, this works.

A: 

I had the same problem and I solved it by resizing the tableView in the viewDidAppear function of the UITableViewController. Not the ideal solution but it works.

Daniel
A: 

I think I have a solution that works. I posted info here: mitchallen.com/iphone/archives/184

(Sorry, you'll have to cut and paste - I'm a new user and can't post live links yet).

+2  A: 

I had the same problem and I solved it with:

-(void) loadView {
    [self setView:[[[UIView alloc] initWithFrame:CGRectZero] autorelease]];
    [[self view] setAutoresizesSubviews:NO];

    /* Create & configure table and other views... */

    [self setResultsTable:[[RadarTableViewController alloc] initWithNibName:nil bundle:nil]];
    [[resultsTable view] setFrame:CGRectMake(0,45,320,200)];
}

This is done in the parent (just a plain UIViewController in my case) controller.

Blago
Thx, my 181 px Tableview inside a UIViewController got always shrinked, now it's listening to the frame settings since I use your [[self view] setAutoresizesSubviews:NO];
Allisone
A: 

Hi

Did you manager to get this quirk fixed in your App? It is driving me crazy!! I did what you said putting the setFrame method in the cellForRowAtIndexPath function, however on the navigation controller clicking on didSelectRow and going back to the table default the size back to normal instead of the size I want grrrrr

dimos
If I ever figure it out, I'll surely post a comment or an answer. If someone else figures it out and responds, I'll surely mark it as an answer.
rpj
A: 

Hi, I found this post, hope it useful.

Just don't use the UITableViewController

Phuong