2010-01-27 3 views
10

В некоторых моих проектах приложений или только для некоторых UIView, после pushViewController navigationController, мое новое представление будет сдвинуто с окна на высоту строки состояния. В результате я помещу этот код в метод viewDidLoad.Почему некоторые из моих UIViews смещаются после навигации?

CGRect frameAt = [self.view frame]; 
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame]; 
frameAt.origin.y += statusBarFrame.size.height; 
[self.view setFrame: frameAt]; 

Это не имеет смысла для меня, что это намерение XCode и Interface Builder, так что я подозреваю, что я делаю что-то принципиально неправильно с SDK во время моего дизайна просмотра. Кроме того, в редких случаях, когда мне не нужно менять свое мнение, я действительно не знаю, какая разница в двух подходах к дизайну.

Обратите внимание, что большую часть времени я пытаюсь спроектировать свои представления с использованием IB, с небольшой настройкой.

Кто-нибудь еще сталкивается с этим и знает, что они делают, чтобы исправить без такой заглушки кода?

+0

Также обратите внимание, что я играл с настройкой «смоделированный статус» и, по крайней мере, один раз, это оказалось правильной настройкой, поэтому мне не пришлось вносить изменения в код. – mobibob

ответ

16

Я использовал Apple's NavBar sample code, чтобы попытаться воспроизвести эту проблему.

в applicationDidFinishLaunching изначально реализована следующим образом:

[window addSubview:navigationController.view]; 
[window makeKeyAndVisible]; 

Если изменить его к этому:

UIViewController *shellController = [[UIViewController alloc] initWithNibName:nil bundle:nil]; 
[shellController.view addSubview:navigationController.view]; 
[window addSubview:shellController.view]; 
[window makeKeyAndVisible]; 

Тогда я получаю разрыв появляющийся.

Однако, если я только это:

UIView *shell = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
[shell addSubview:navigationController.view]; 
[window addSubview:shell]; 
[window makeKeyAndVisible]; 

Тогда все выглядит нормальной.

Таким образом, я думаю, что каждый контроллер вида будет смещать свой вид, если его контроллер корневого представления. Но навигационный контроллер переопределяет это поведение, чтобы компенсировать его представление независимо от того, является ли он контроллером корневого представления. Поэтому я бы сказал, что ваш пробел появляется, потому что у вас есть контроллер навигации где-то ниже в иерархии, чем это должно быть.

+0

Я думаю, что вы попали в проблему. Я собираюсь проверить другое приложение, у которого есть два его экрана с этой проблемой. Я думаю, что я добавил UINavigationController для этих UIViewControllers. Еще через 20 минут ... – mobibob

+0

Тайна решена! Вот и все !!! Я очень ценю ваше усердие в этом. Я изучил действительно отличный принцип добавления навигационной панели в существующие UIViewControllers.Так, как они были у меня, они были определены «ниже в иерархии UIView»; так что, когда я добавил их как IBOutlet в код, созданный в IB и подключив навигационный контроллер IB к IBOutlet из моего кода, я получил как навигационную функцию, которую я хотел, так и не видел артефакты просмотра. Кроме того, моя настройка кадра вызвала тревожный «прыжок», чтобы привязать его на место. Это 110% правильный ответ на мою проблему. – mobibob

+0

Я заметил, что на это был дан ответ 10 марта. Не уверен, совместим ли это с iOS6. У меня такая же проблема, но пробел находится ниже панели навигации. Вот мой вопрос: http://stackoverflow.com/questions/17790946/ios-containerview-with-modalview-gap-appears-after-dismissing-modal Спасибо. – user1107173

2

Главное, чтобы иметь в виду, что контроллер вида устанавливает рамку своего представления. Это связано с тем, что объем пространства, доступного для представления, может измениться в течение всего срока действия приложения, и только контроллер представления знает, как правильно отрегулировать рамку представления. Примеры того, когда количество изменений пространства включает в себя изменение высоты навигационной панели, поворот устройства от портрета к ландшафту, а строка состояния также может увеличиваться в высоту, если пользователь выполняет вызов. Из-за этого вы не должны изменять рамку представления самостоятельно.

Итак, первое, что вам нужно, это удалить весь код, связанный с модификацией рамки представления.

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

Вы можете установить свойство авторезистентности каждого поднабора в Interface Builder в инспекторе размеров (тот, который имеет значок линейки). В анимации белый квадрат представляет корневой вид контроллера вида, красное поле представляет выбранное в данный момент подвью. Вы заметите, что подвью привязывается к верхнему левому углу корневого представления по умолчанию. Это прекрасно, если размер представления никогда не изменяется, но мы знаем, что это не так. Если у вас есть подпункты, которые вы хотите отобразить внизу, неважно, что нужно, тогда вам нужно сыграть с диаграммой слева. Способ его работы заключается в том, что выбрана одна из четырех линий вокруг края, тогда фиксируется расстояние между этим краем корневого представления и краем подвью. Поэтому, если вы хотите, чтобы подвью отображалось внизу, вам нужно убедиться, что выбрана самая нижняя строка, а не верхняя. Две линии в середине влияют на изменение размера подзона при изменении размера корневого представления. Так, например, если у вас было представление таблицы, которое вы хотели бы занять всю высоту экрана, вы должны убедиться, что выбрана внутренняя вертикальная линия. Это называется моделью распорок и пружин.

Если вы добавляете подпрограммы программно, вам необходимо установить свойство autoresizingMask для каждого поднабора. Here's an explanation.

Надеюсь, что это поможет!

+0

Привет Моши, я думаю, вы подтвердили, что я верил (пусть система управляет представлениями и кадрами). К сожалению, со временем что-то в моем кодировании что-то изменит, а рамки сдвинутся.Обычно я смотрю на контроллер подкласса, когда я перемещаюсь и возвращаюсь. Я полагаю, что мое понимание (правильно), и мой реальный вопрос должен быть - как я могу определить, что я сделал, чтобы настроить мою иерархию и какой фундаментальный параметр/параметр мне нужно исправить. Я также прочитал (несколько раз) ссылочный документ. Я сделаю немного больше обзора, прежде чем решить, что это ответ. – mobibob

+0

Моши, я прочитал вопрос и ответчики Брайана. Некоторые из них обнаружили, что они должны установить размер кадра - это то, что я также сделал. Это звучит как какое-то состояние гонки при определении ориентации или что-то фундаментальное. Я проведу аутологию моих подзапросов, и если это сработает, я дам вам ответ. – mobibob

+0

Хм, это может помочь, если вы разместите структуру контроллера своего вида. В документах указано: При развертывании интерфейса навигации вы должны установить это представление в качестве корня любой иерархии представлений, которую вы создаете. Например, если вы сами развертываете интерфейс навигации, вы должны сделать это представление основным подзором вашего окна. Чтобы установить интерфейс навигации внутри интерфейса панели вкладок, вы должны установить представление контроллера навигации в качестве корневого представления соответствующей вкладки. – jamesmoschou

1

У меня возникли аналогичные проблемы.Проверьте мои два предыдущих вопроса:

IPhone - After dismissing Modal View Controller - gap is left at top of page

IPhone - UIView addSubview Gap at top

+0

Привет, Брайан. Как я уже упоминал в своих комментариях к Моши (выше), я просмотрел ваши вопросы и ответы (которые, я думаю, я исследовал, прежде чем задавать свой вопрос), и они оказались обещающими, но они не затрагивали мою проблему. Кроме того, я считаю, что настройка рамки на текущую настройку является неправильным решением, поскольку что-то другое скорее ошибочно. Я оставлю оставшихся без ответа (я ответил на проблему для одного из моих приложений, но я не думаю, что это решение для других приложений). – mobibob

+0

Хороший материал - эти ответы были полезны для моих исследований и проблем и предложили более глубокое понимание SDK, однако ответ Моши прямо исправил мою проблему и имел некоторые побочные эффекты очистки. Возможно, вы захотите вернуться к своей старой проблеме и убедиться, что это лучшее решение. - Искренне благодарю за ваши усилия. – mobibob

0

link text

Аналогичная ошибка обсуждается здесь.

Также установлена ​​анимация NO? Попробуйте настроить его на YES, поскольку это решило проблему, с которой я столкнулся.

0

Ответ Моши был очень полезен, поскольку я, наконец, осознал смысл пунктирных/сплошных линий в IB для управления свойствами изменения размеров элементов UIView.

Однако при настройке этих свойств не была решена аналогичная проблема, с которой я столкнулся с одним из моих взглядов. Этот вид имел статус и верхний бар, определенный в IB. Это был немного тяжелый, , содержащий UIWebView, который загружал бы HTML-строку в пределах viewWillAppear и несколько других элементов интерфейса.

При загрузке представления, если пользователь неожиданно изменил ориентацию устройства от портретного до ландшафтного, все содержимое представления сдвинется вниз по высоте строки состояния. Результирующий зазор между элементами управления представлением и его вершиной остался бы даже после переключения обратно в портретную ориентацию.

Что, наконец, решить свои проблемы, и мои оставшиеся волосы, добавляли строку:

self.view.frame = [[UIScreen mainScreen] bounds]; 

в

-(void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 

С тех пор мое содержание представления удерживается на месте, несмотря на резкие изменения ориентации устройства.