iPhone UIViewController находится под строкой состояния

У меня есть представления UIView и UIController. Мой стандартный вид 320x460. В applicationDidFinishLaunching я делаю:

[window addSubview:[controller view]];

Странно то, что UIView находится под строкой состояния (как будто отсутствует розетка). Однако, если я поворачиваю iPhone в сторону, а затем обратно, он отображается нормально.

Это ожидаемое поведение (держу пари, я могу исправить это, установив смещение) или я делаю что-то неправильно?


person Mantas    schedule 09.12.2009    source источник
comment
попробовать смоделированные элементы интерфейса?   -  person Jacob Relkin    schedule 09.12.2009
comment
Я включил смоделированную строку состояния в окне, контроллере и представлении - не повезло ... Макет поврежден, когда приложение запускается в iPhone или симуляторе в XCode. Однако он отлично работает в симуляторе от InterfaceBuilder.   -  person Mantas    schedule 09.12.2009


Ответы (12)


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

if showing the status bar :
   [controller view].frame = CGRectMake(0, **20**, 320, 460);
else 
   [controller view].frame = CGRectMake(0, 0, 320, **480**);

вот почему IB показывает вам фиктивную строку состояния.

person n3wscott    schedule 09.12.2009
comment
Спасибо. Я уже использовал это, чтобы решить проблему. Я просто не был уверен, что это обычный способ исправить это. - person Mantas; 10.12.2009
comment
Отличное исправление, но примечание: 20 должно быть вторым параметром CGRectMake, а не первым :). - person makdad; 18.07.2010

Я столкнулся с этой проблемой при отображении UIViewController через presentModalViewController.

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

- (void) viewDidAppear: (BOOL) animated {
    //manually adjust the frame of the main view to prevent it from appearing under the status bar.
    UIApplication *app = [UIApplication sharedApplication];
    if(!app.statusBarHidden) {
        [self.view setFrame:CGRectMake(0.0,app.statusBarFrame.size.height, self.view.bounds.size.width, self.view.bounds.size.height - app.statusBarFrame.size.height)];
    }
}
person Nick Baicoianu    schedule 22.03.2010
comment
Последующие действия: лучшее решение, которое я видел для этого, - открыть файл nib для вашего контроллера представления, выбрать основной вид и в разделе «Элементы имитации пользовательского интерфейса» установить для параметра «Строка состояния» что-либо, кроме «Не указано». Я не могу объяснить, какие внутренние значения меняются, просто это решило проблему для моего приложения. Если вы сделаете это, вам не понадобится код в моем предыдущем ответе. - person Nick Baicoianu; 29.06.2010
comment
app.statusBarFrame.size.height возвращает 0. :( - person Gik; 09.11.2012
comment
Исправление (по моему замечанию): [[UIApplication sharedApplication] statusBarFrame].size.height возвращает 0, если он выполняется до чего-то вроде: [[UIApplication sharedApplication] setStatusBarHidden: NO withAnimation: NO]; Но после этого возвращает 20. statusbarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height; // высота строки состояния == 20 - person Gik; 09.11.2012

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

Отключение «Хочет полноэкранный режим» решило проблему.

person user1626682    schedule 23.09.2012

Наконец, я добрался до этого решения. Хорошо работает как для iPhone, так и для iPad:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

    // Allocate view controller and load nib file
    if (isIPhone) {
        self.mainViewController = [[[tfdMainViewController_iPhone alloc] initWithNibName:@"tfdMainViewController_iPhone" bundle:nil] autorelease];
    } else {
        self.mainViewController = [[[tfdMainViewController_iPad alloc] initWithNibName:@"tfdMainViewController_iPad" bundle:nil] autorelease];
    }

    // Offset correction (iPhone bug?)
    CGRect r = self.mainViewController.view.frame; 
    r = CGRectOffset(r, 0, [UIApplication sharedApplication].statusBarFrame.size.height);
    [self.mainViewController.view setFrame:r];  

    [window addSubview: self.mainViewController.view];
    [self.window makeKeyAndVisible];
    return YES;
}

P.S. По какой-то причине вид имеет правильную высоту: 480 (высота экрана в портретном режиме iPhone) - 20 (строка состояния) = 460, но не удалось установить вертикальное смещение. Довольно странное поведение, похоже на баг.

person Mike Keskinov    schedule 06.01.2012

Исправления в окне у меня не сработали, так как у меня был модальный вид. Модальное представление UIModalPresentationCurrentContext. Хорошо, вот что сработало для меня. Я искал в Интернете вверх и вниз, прежде чем заставить это работать. Я не могу переместить view.frame от родителя. Однако в представленииWillAppear я могу переместить его вниз:

- (void)viewWillAppear:(BOOL)animated
{
    // Move down to compensate for statusbar
    CGRect frame = parentView.navCon.view.frame;
    frame.origin.y = [UIApplication sharedApplication].statusBarFrame.size.height;
    parentView.navCon.view.frame = frame;
}
person Jon Ramvi    schedule 13.01.2012
comment
Это обман! ;-) Вы должны найти высоту строки состояния, а не запрограммировать ее на 20. Что, если Apple решит изменить ее на 25? Тогда вы будете отключены на 5px! - person Gik; 09.11.2012

Если вы используете «Смоделированные элементы пользовательского интерфейса» Interface Builder, вам также необходимо убедиться, что вы установили флаг «Изменить размер представления из NIB» в своем наконечнике MainWindow.

person ucangetit    schedule 16.03.2011

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

http://www.cocoanetics.com/2012/06/radar-view-frame-inconsistency-using-presentviewcontroller-wantsfullscreenlayout-yn/

http://openradar.appspot.com/radar?id=1758406

person markshiz    schedule 11.12.2012

Вы вручную устанавливаете скрытое свойство панели приложений ПОСЛЕ добавления подвида? Я не думаю, что это так, но если для него установлено значение none при первой загрузке представления, оно будет выглядеть так, как будто его нет, и если вы затем установите строку состояния как не скрытую, она появится сверху вашего взгляда.

Возможным решением является использование [[controller view] setNeedsLayout]; после добавления подвида или, возможно, [window layoutSubviews];. Я никогда не имел большого успеха, используя их для исправления проблем с макетом, но, поскольку он работает после поворота, стоит попробовать.

person Ian Henry    schedule 09.12.2009
comment
Я никогда не скрываю панель приложений. Переустановка вещей не помогла... - person Mantas; 09.12.2009

Даже у меня тоже возникла такая же проблема. Когда мы используем какой-то код для ориентации устройства, мы написали код в делегате приложения или в нашем контроллере представления. Там нам нужно изменить условие, чтобы использовать возврат ориентации ДА или НЕТ. Это решило нашу проблему.

person SURESH SANKE    schedule 10.07.2013

Я предпочитаю использовать UINavigationController для обертывания UIViewController, после чего вы устанавливаете NavigationBarHidden в UINavigationController. Это идеальное решение, потому что UINavigationController обрабатывает высоту строки состояния в iOS 7.

Вот мой код и мой снимок экрана.

UINavigationController *wrapNavController = [[UINavigationController alloc] initWithRootViewController:yourViewController] ;

[wrapNavController setNavigationBarHidden:YES] ;
person Grant Fong    schedule 05.01.2014

Решение Xcode 6, iOS7/8 предназначено для снятия флажка «Под верхними панелями» в разделе «Расширить края» раздела «Контроллер представления» инспектора атрибутов.

person Paul Cezanne    schedule 05.05.2015

Для Xamarin.iOS это будет:

if (UIApplication.SharedApplication.StatusBarHidden == false)
{
   var statusBarHeight = UIApplication.SharedApplication.StatusBarFrame.Height;
   View.Frame = new CoreGraphics.CGRect(0, statusBarHeight, View.Frame.Width, View.Frame.Height - statusBarHeight);
}
person Umer Khalid Butt    schedule 29.11.2017