IPhone - после отклонения Modal View Controller - пробел остается наверху страницы

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

Итак, у меня есть:

- (void)viewDidAppear:(BOOL)animated
{
     NewAccountViewController *newAccountViewController = [[[NewAccountViewController alloc] initWithNibName:@"NewAccountViewController" bundle:nil] autorelease];

     UINavigationController *accountNavigationController = [[UINavigationController alloc] initWithRootViewController:newAccountViewController];
  [self presentModalViewController:accountNavigationController animated:YES];       
}

И в newAccountViewController у меня есть простая кнопка навигационного элемента, которая отклоняет контроллер модального представления с помощью функции offsetModalViewController.

Это все работает, и когда модаль отклоняется, вид в навигационном контроллере виден с его заголовком пункта навигации вверху.

Но есть белый пробел примерно того же размера, что и строка состояния между строкой состояния и верхней частью синей панели навигации. Если я не буду делать модальный, то разрыв никогда не будет. Это происходит только после того, как модальный представлен и отклонен. Я пробовал делать анимированные: НЕТ как на настоящем, так и на sendModalViewController. Я также не пытался использовать навигационный контроллер в модальном режиме, и это тоже ничего не делало. Любые идеи были бы замечательными! Спасибо.

Ответ 1

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

Ответ 2

У меня была та же проблема. Мое решение состояло в том, чтобы временно закрыть строку состояния непосредственно перед переключением просмотров:

- (void) temporarilyHideStatusBar {
  [[UIApplication sharedApplication] setStatusBarHidden:YES];
  [self performSelector:@selector(showStatusBar) withObject:nil afterDelay:0];
}
- (void) showStatusBar {
  [[UIApplication sharedApplication] setStatusBarHidden:NO];
}

// Use these by calling the hide function just before a broken view switch:
[self temporarilyHideStatusBar];
[self doViewSwitch];

// No need to call [self showStatusBar]; explicitly.

Я экспериментировал с другими решениями на основе кода, и мне это нравится лучше всего потому, что он работает в 100% случаев - некоторые из моих основанных на рамах решений работали большую часть времени - и потому, что он имеет минимальный видимый пользователем эффекты.

Я подозреваю, что это ошибка Apple, и было бы неплохо услышать от них официальное слово о лучшем обходном пути.

Ответ 3

Я столкнулся с той же проблемой. Не уверен, что вызывает его, но я исправил его следующей строкой кода сразу после отклонения моего модального представления:

[self.view setFrame:CGRectMake(0, 10, self.view.frame.size.width, self.view.frame.size.height)];

Просто настройте смещение Y, чтобы удовлетворить ваши потребности. В другом случае мне пришлось сделать это 20 вместо 10.

Ответ 4

Просто хотел перезвонить и сказать, что у меня была совершенно противоположная проблема - белый зазор в нижней части экрана. И исправление было также противоположным, я представлял из подсмотра, когда мне нужно было представлять от родителя. Спасибо!

Ответ 5

В случае, если кто-нибудь посмотрит на этот пост (я сделал это сегодня, и другие могли бы). Я новичок в объективе c, но вы можете смеяться над моим предложением, но здесь идет.

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

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

Вот что выглядел бы простой метод AppDelegate didFinishLaunchingWithOptions:

(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.

    TEGGameViewController *gameVC = [[TEGGameViewController alloc] init];

    self.window.rootViewController = gameVC;

    [self.window makeKeyAndVisible];
    return YES;
}

Ответ 6

Хорошо, я не знаю, почему это происходит, это случилось со мной, хотя и плохо рассказывал вам, как я ее исправил. Я обнаружил, что добавление представления в 0,0 делало его совпадающим со строкой состояния... это странно, потому что до 3.0 у меня никогда не было проектов, которые выполняли это поведение. 0,0 всегда находилось под строкой состояния. Во всяком случае, я видел, что это перекрытие, поэтому я начал ставить свои взгляды на 0,20 или, как ни странно, в строке состояния. Это было здорово, пока я не попытался использовать модальный контроллер представлений, когда он отклонил, я обнаружил, что размер строки состояния (что вы задерживаете), по какой-то причине модальный взгляд считает, что 0,0 не перекрывает строку состояния и когда он отклоняет 0,20 (из вашего предыдущего обзора), как будто (0,0) не превышает круг и (0,20) имеет дополнительный белый зазор. Почему это произошло? Нет подсказки. В любом случае, чтобы исправить это, я знал, что мне нужно исправить все перекрытие вида и строки состояния на 0,0 штуки. Я продолжал пытаться, но ничего, тогда я решил попытаться создать новый проект на основе представления в xcode (который устанавливает для вас начальное представление) и посмотреть, перекрывается ли их представление (или если оно помещено на 0,20), что я что он НЕ перекрывался, а 0,0 был правильным размещением, прямо под строкой состояния и не перекрывая его. Bizzare? я думаю так. Итак, что я сделал в своем проекте, это скопировать настройки, которые они создали во вновь созданный проект на основе представления (они установили свойство viewControllers через Interface Builder, вы можете создать проект на основе представления, как я, и просто имитировать их настройку), я обнаружил, что это устранило проблему, просмотры на 0,0 больше не перекрывали строку состояния, и отклонение диспетчеров модального представления больше не покидало пробел. Не знаю, если это ваш случай, но это может быть, надеюсь, это поможет вам.

Ответ 7

У меня была такая же проблема... мое решение? Вручную установите высоту представления, которое вы показываете модально до 480 пикселей в построителе интерфейса.

Проблема решена.

Ответ 8

Данный ответ трудно понять, скорее как неопределенный намек, поэтому попробуйте объяснить более подробно:

Проблема заключается в том, что контроллер корневого представления, метод viewDidAppear: представлен в вопросе, выглядит как простой UIViewController. И как мы можем видеть в документации Apple для wantsFullScreenLayout:

Значение по умолчанию для этого свойства равно NO, что вызывает отображение вида, поэтому оно не перекрывает строку состояния

Этот контроллер корневого представления представляет UINavigationController по модулю, поэтому представленный навигационный контроллер использует не весь экран. Также кажется, что значение по умолчанию UINavigationController для wantsFullScreenLayout равно YES. Именно поэтому контроллер навигации добавляет пробел - чтобы не перекрывать строку состояния с помощью панели навигации.

Итак, есть несколько способов решить эту проблему:

1) Представленный контроллер навигации с свойством wantsFullScreenLayout, установленным на NO. (Или представить ~ свежий UIViewController с представлением UINavigationController в качестве подзаголовка)

2) Измените свойство rootViewController UIWindow на контроллер навигации вручную, поэтому навигационный контроллер отображается во всем окне. Может использовать его, например. когда первый экран является разновидностью одноразового ввода PIN-кода/пароля, и мы можем легко отбросить его после успешного входа и изменения для контроллера навигации.

Ответ 9

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

Моя проблема заключается в том, что как только я нажал Modal VC на подзаголовок TabController (который, в свою очередь, представляет собой подпрограмму всеобъемлющего NavController View, который контролирует верхний NavBar... который превращается в кошмар делегации) и затем отпустите MVC, представление, которое возвращается, подталкивается под NavBar. Не происходит, когда я добавляю или нажимаю любые другие подпункты, только с MVC.

[self.view setFrame: (CGRect)], похоже, делает трюк, если я его назову сразу после [self offsetModal...]. Тем не менее, он должен быть вызван во всех подзаголовках моего контроллера панели вкладок, или даже другие списки шунтируются под панелью. Poopy.

Делает вещи головной болью, но не неразрешимой. Но я согласен, что это новая ошибка с 3.x(или, возможно, одна из этих двухсторонних "новых возможностей" ), и это совершенно раздражает. Я загружаю 3.1.2 SDK сейчас, и, надеюсь, он обращается к этому. Прошу прокомментировать мои строки [setFrame] и посмотреть, что произойдет. Но, надеюсь, если это не решится в этой версии, это будет скоро. До тех пор кажется, что в решении много (по общему признанию, хакерских и повторяющихся) кода.

EDIT: Нет, обновление не помогло. Полуют. Вернемся к коду, куда я иду, чтобы определить положение каждого экрана. Потрясающие. Надеемся, что размер Nav и Tab Bars не изменится.

ИЗМЕНИТЬ 2: Эй! Я решил это! (i R prowd.) Похоже, проблема заключалась в том, что, когда мой MVC был уволен, мое представление было передано обратно контроллеру панели табуляции, который "забыл", что над ним была панель навигации. Не говорите мне, как, я, вероятно, сейчас уже не задокументирован. Но я решил свою проблему, просто переопределив [subview.view setFrame: 0,0, width, height] после возвращения из редактирования. Не уверен, почему это имело какое-либо значение, но в приложении это произошло, потому что больше не первое и полторы рядов моего табличного представления, подкрадывающегося под панель навигации. Поэтому у меня действительно нет совета, просто найдите подходящее место, чтобы положить

[(appropriateViewController).view setFrame:CGRectMake(0,0,self.view.frame.size.width, self.view.frame.size.height];

Не знаю, почему это работает, но это так. Разве это не худшая ошибка?

Ответ 10

Я использовал @Mark Hammonds ответ, но просто reset смещение кадра к 0, т.е.

// this won't be called on the parent view if a modal dialog is dismissed. [self.parentViewController viewWillAppear: animated]; 
// actually dismiss the modal dialog. 
[[TOSplitViewController active] dismissModalViewControllerAnimated: animated]; 
// fix the mysterious white bar that appeared on the top. 
[[TOSplitViewController active].view setFrame:CGRectMake(0,0, [TOSplitViewController active].view.frame.size.width, [TOSplitViewController active].view.frame.size.height)];

Как вы могли догадаться, это было при попытке отклонить модальный диалог, представленный в верхней части разделенного представления на iPad-приложении.

Я попробовал ответить @Tyler, и это не сработало для меня.

Это на iOS4.1, ориентированное на iPad 3.2.

Ответ 11

Я столкнулся с этим несколько раз и сделал обходной путь (переустановка кадра) из-за временного давления, но в последний раз, когда я наткнулся на него, я нашел реальное решение. Вместо того, чтобы создавать контроллер верхнего уровня в коде (если он есть), попробуйте создать его в UIWindow и IBOutlet вместо AppDelegate.

Работал для меня.

Ответ 12

У меня была такая же проблема, и вот мое решение. Просто добавьте это в свой AdDelegate:

- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave
{
    if (!willLeave)
        [[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];
    return YES;
}

- (void)bannerViewActionDidFinish:(ADBannerView *)banner
{
    [[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES];
}

Это очень просто; Когда появляется объявление, я скрываю строку состояния, и когда объявление исчезает, я показываю его снова. Я надеюсь, что ответ поможет некоторым людям.

Ответ 13

Я нахожу, что и представление, и отклонение диспетчеров модального представления вызывают это, особенно если вы хотите выполнить пользовательский макет в -viewDidLoad (что, как утверждают некоторые, вы не должны, но я никогда не нашел лучшего, работающего). Что я делаю:

[self.view addSubview:self.viewController1.view]; // I suppose this layouts all (sub)views.
[self.viewController1.view removeFromSuperview]; 

Теперь вы можете представить как таковой:

    self.viewController1.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self.viewController2 presentModalViewController:self.viewController1 animated:YES];

не рискуя, чтобы viewController1 был выложен нечестным способом до тех пор, пока не будет выполнен переход, а затем щелкнуть туда, где бы он ни находился. То же самое относится и к увольнению. Работает для меня на iOS 3.0, хотя 5.0, iPhone и iPad.

Ответ 14

Я нашел более "элегантный" способ сделать это. Если вы добавите верхний вид в окно, размер которого совпадает с окном, и добавьте subviews к этому верхнему виду вместо окна, все подпункты будут смещены на 20 пикселей в правильном направлении, в строке состояния visibile, без пробелов везде и даже вращение будет работать правильно. Я тестировал его с iPad и iPhone 4.3 и 5.0... Какой улов?;)

Ответ 15

Вы могли бы поместить этот код, если вы упустите UIImagePickerController.

self.view.frame = CGRectMake(0, 0, 320, 480);

Ответ 16

Для меня мой modal view controller был MoviePlayer, и когда он будет представлен, казалось бы, строка состояния будет перерисована. Когда представление было отклонено, эта вторая строка состояния каким-то образом создала смещение 20 пикселей в нижней части экрана, чуть выше контроллера панели.

Чтобы исправить это, когда был представлен контроллер модального представления, я бы спрятал строку состояния. Когда фильм закончил игру, и диспетчер модального просмотра будет отклонен, я сделал видимый индикатор состояния.

- (void) moviePlayerLoadStateChanged:(NSNotification*)notification 
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}


- (void) moviePlayBackDidFinish:(NSNotification*)notification 
{
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}