2009-12-10 7 views
3

Это портрет:UITableView в UINavigationController попадает под навигационной панели после поворота

alt text http://i45.tinypic.com/2cp6ttf.jpg

Это пейзаж

alt text http://i47.tinypic.com/15g6ve9.jpg

Я попробовал это на вращение без успеха:

self.tableView.autoresizesSubviews = YES; 
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 

ответ

13

Я столкнулся с этой проблемой в последнее время. В моем случае это было связано с тем, что я выполнял вращения навигационного контроллера, который не был корневым контроллером окна приложения. Поэтому я использовал подход корректировки уведомлений о ротации/аффинном преобразовании/границах для изменения макета навигационного контроллера. Это работало правильно, но дало результаты, описанные здесь. Мне потребовалось некоторое время, чтобы заметить, что когда я поворачивался в альбом, высота навигационной панели не была правильно изменена (т. Е. От 44 до 32 пикселей, уменьшенная высота рамки для ландшафтного режима). Контроллер корневого представления моего приложения был, отвечающий на willRotateToInterfaceOrientation и сделалRotateFromInterfaceOrientation, однако. Этот контроллер просмотра уже знал о соответствующем контроллере навигации. Я исправил проблему, добавив следующий код в willRotateToInterfaceOrientation метода:

CGRect frame = self.navViewController.navigationBar.frame; 
if (toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) { 
    frame.size.height = 44; 
} else { 
    frame.size.height = 32; 
} 
self.navViewController.navigationBar.frame = frame; 

Надеется, что это спасает кому-то какое-то время в подобной ситуации.

+0

Спасибо. К сожалению, в моем случае навигационная панель правильно меняет высоту. Кажется, что показанное представление теряет все знания навигационной панели при вращении, поэтому верхняя часть ее появляется под навигационной панелью. Когда другое изображение выдвигается, а затем появляется, проблематичное представление перераспределяется правильно. Я попробовал setNeedsLayout, но безуспешно. – Oscar

+0

решил для меня, отличная работа –

+0

Это сработало отлично. –

0

Похоже, что после изменения ориентации вид таблицы немного прокручивается.

Вы пробовали позвонить scrollToRowAtIndexPath:atScrollPosition:animated: и прокручивать верхнюю строку?

+0

Нет, это не так, когда вы сметаете его, снова появляется под панелью навигации. В нижней части есть также панель инструментов с одинаковыми результатами. Нижняя часть tableView находится под ним в ландшафтном режиме – Jorge

0

Эта проблема может возникнуть, если вы указали «willAnimateRotationToInterfaceOrientation:» в вашем навигационном контроллере, но забыли вызвать супер из метода.

Вы должны иметь что-то вроде этого:

 - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 
     [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation]; 
// Your code here 

    } 
+0

Если я добавлю этот код, то получаю это предупреждение при компиляции: «UITableViewController» может не отвечать на «-willAnimateRotationToInterfaceOrientation: ' – Jorge

+0

Фрагмент кода должен войти в ваш контроллер навигации , а не ваш ТВЦ. – nzeltzer

+0

Если я добавлю этот код, я получаю это предупреждение при компиляции: «UIViewController» может не отвечать на «-willAnimateRotationToInterfaceOrientation:» -Suchita –

0

В этих ситуациях необходимо обратить внимание на ориентацию панели состояния, если вы меняете ее вручную. Если строка состояния не скрыта, и вы изменяете рамку своего представления, когда строка состояния находится в неправильной ориентации (в вашем коде, возможно, вы обновляете ориентацию строки состояния сразу после смены кадра), она будет автоматически неправильно измените размер навигационной панели, даже если у вас нет автоматического изменения размера.

7

При использовании настраиваемого контроллера представлений как пользователя root, который управляет другими контроллерами представлений, он отвечает за пересылку всех событий поворота на текущий активный подконтроллер (если я могу так называть). Эти события являются:

– willRotateToInterfaceOrientation:duration: 

– willAnimateRotationToInterfaceOrientation:duration: 

– didRotateFromInterfaceOrientation: 

– willAnimateFirstHalfOfRotationToInterfaceOrientation:duration: 

– didAnimateFirstHalfOfRotationToInterfaceOrientation: 

– willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration: 

Таким образом, в случае контроллера навигации, управляемый вашей пользовательские корневой контроллер, пересылка – willAnimateRotationToInterfaceOrientation:duration: к навигации контроллеру устраняет проблему с неправильной высотой навигационной панели при вращении.

+2

Это самое чистое решение. –

+0

Это должен быть принятый ответ. Также обратите внимание, что в iOS 5 и 6 вы можете автоматически переводить методы поворота и внешнего вида. – Andy

2

У меня точно такая же проблема, и @jstevenco привел меня к действительно странному решению. Мои взгляды также автоматическое изменение размеров на вращение, но TableView, кажется, не понимаю, что это navigationcontroller сидит:

В tableviewcontroller, добавьте следующее:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; 
CGRect frame = navBar.frame; 
if (fromInterfaceOrientation == UIInterfaceOrientationPortrait || fromInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) { 
    frame.size.height = 31.9; 
} else { 
    frame.size.height = 44.1; 
} 
navBar.frame = frame; 

} 

31,9 и 44,1 очень важно странно! Оставляя их 32 и 44, нет никакого изменения размера, поэтому он, кажется, игнорирует его. Работал для меня, надеюсь, что это поможет кому-то другому.

6

Добавьте следующую строку в метод didRotateFromInterfaceOrientation.

[self.navigationController.view layoutSubviews];

Я надеюсь, что это будет делать.

+0

Не работал для меня. – svth

+0

@svth atleast он работал до iOS6. – chandu

0

Ваш UINavigationController должен получить уведомление, когда меняется ориентация устройства. Этого не происходит, если вы только добавили view из UINavigationController в другой UIView.

Начиная с iOS 5, вы можете просто позвонить addChildViewController: на родителя UIViewController, который обеспечит распространение изменений ориентации на этот контроллер детского представления.