I have a method I call to calculate the sizes of a bunch of labels I have in a custom UITableViewCell
subclass, which is in a UIPopoverController
. When the user rotates the device, I need to recalculate the sizes, and then have the table re-drawn to use the new sizes. Every method I've tried to detect the rotation is either depreciated, doesn't get called, or doesn't get called at the right time. Is there a method that will automatically get called when the device is rotated that I can recalculate my sizes in?
Edit: What I have tried and why it doesn't work:
shouldAutorotate
- doesn't get called - apparently depreciated.layoutSubviews
- gets called, but if I try to [self.tableView reloadData]
in here, I get stuck in an infinite loopNSNotificationCenter
observer for UIDeviceOrientationDidChangeNotification
- Gets called before my controller knows it's new dimensions, so I cannot recalculate my sizes here[self.tableView setNeedsDisplay]
in layoutSubviews
- doesn't prompt re-drawing of table.didRotateFromInterfaceOrientation
- doesn't get called - apparently depreciated.Edit 2: More details on what I'm trying to do
I'm trying to imitate a "rows-and-columns" style table, and line up the labels to imitate the columns. When I recalculate the sizes, I loop through all the rows of the table, then through each "column" in that row. I get the width of each column, and keep track of the largest width in all the rows for each column. Then I manipulate the spacing between widths and the font sizes to get it so that if any row has the widest label in every column, it will still fit on the screen.
You don't want to rely on the actual rendered UILabels inside of your cell to calculate your "column" widths. Do this instead:
calculateColumnWidthsForInterfaceOrientation:
that takes an UIInterfaceOrientation
. In that method, check if the requested orientation is portrait or landscape using UIInterfaceOrientationIsLandscape(orientation)
. Then, based on the orientation go through the data you want to display in your labels and find the widest column widths using NSString's sizeWithAttributes:
method (or one of its derivatives). Caches those values in an array or something.setColumnWidths:
to your custom table view cell that takes the desired column widths.tableView:cellForRowAtIndexPath:
method, retrieve the cached column widths and set it on the cell using the setColumnWidths:
method.didRotateFromInterfaceOrientation:
. Inside of it, call calculateColumnWidthsForInterfaceOrientation:
with the given orientation and after that call [self.tableView reloadData]
.viewDidLoad
, call [self calculateColumnWidthsForInterfaceOrientation:self.interfaceOrientation]
to do the initial setup of your data before the first rotation.That should do the trick.
Update: The total width of your cell should be equal to the total width of your table view. That can be managed with auto-layout or by other means. That size will be reflected in the cell's frame size.
Update 2:
Since we are talking about a popover, you could maybe simply dismiss the popover in willRotateToInterfaceOrientation:duration:
and then display it again with your new desired dimensions after the rotation is done in didRotateFromInterfaceOrientation:
.
in layoutSubviews try to recalculate subview one cell
for example in CustomCell.m
- (void)layoutSubviews
{
UIViewController *viewController = (id)[(AppDelegate *)[UIApplication sharedApplication].delegate window].rootViewController;
if (UIInterfaceOrientationIsPortrait(viewController.interfaceOrientation))
self.backgroundColor = [UIColor redColor];
else
self.backgroundColor = [UIColor greenColor];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With