Подтвердить что ты не робот

IOS7 - просмотр в строке состояния - edgeForExtendedLayout не работает

У меня есть проект, который был построен в прошлом году, и он использует XIB, никаких раскадровки. XIB не используют Auto Layout, но они используют некоторую Autosizing. У меня проблема при работе с iOS7, в которой все представления заправлены в строку состояния. Я полностью понимаю, что это новая функция с iOS7, в которой это можно ожидать. Однако все решения по его устранению, чтобы не делать этого, не работают. У меня есть изображение в верхней части представления, которое всегда отображается в строке состояния, и я не использую nav-bars или что-то в этом роде.

Я пробовал обновлять Y-deltas в XIB (они не влияют на представление), я попытался установить edgesForExtendedLayout на UIRectEdgeNone (ничего не делает) и множество других вещей. Каждый раз строка состояния отображается с видом, подвешенным под ним, независимо от того, что я делаю.. то есть, если я вручную не перемещаю представление в XIB, чтобы позволить место для строки состояния (но это решение не работает, потому что оно не выглядит правильно в iOS6, конечно).

Что странно в том, что даже когда я пытаюсь использовать строку кода для взлома в сдвиге вида, она не работает (например, следующее):

self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y+20, self.view.frame.size.width, self.view.frame.size.height);

.. Не то, чтобы я пошел с таким решением, но это просто странно, что он не работал (единственный раз, когда я обычно вижу, что не работает, если Auto Layout на месте, что не в этом случае).

Это требование к дизайну, которое отображается в строке состояния, и я просто озадачен тем, почему я не могу настроить представление в строке состояния для iOS7. Я прочитал каждый пост Qaru на эту тему, а также переход Apple/руководство. Еще раз повторю, я полностью понимаю, как он должен функционировать и каково должно быть ожидаемое решение, но ничто из этого не работает для этого конкретного проекта.

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

Спасибо заранее!

4b9b3361

Ответ 1

Если вы установите значения дельта iOS 6/7 в Interface Builder, не забудьте установить "View as" на "iOS 6" в документе Builder Interface, так как это макет iOS 6, который вы хотите реплицировать. Затем дельта будет использоваться только на iOS 7, чтобы подтолкнуть содержимое под панелью состояния. Если вы оставите "View as" установленным в iOS 7 (по умолчанию), дельта будет вместо этого отображать iOS 7 на iOS 6.

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

Вместо использования дельт наилучшее решение, которое я нашел, - включить автоматическую компоновку на вашем основном XIB, а затем установить ограничение верхнего пространства на верхнее/содержимое, чтобы следовать руководству Top Layout. Это руководство было введено в iOS 7 и представляет позицию ниже строки состояния. К сожалению, руководство не доступно в Interface Builder, когда не используется Storyboards, но вы можете добавить его программно.

То, что я сделал, это добавить ограничение на верхнее пространство для супервизора вместо этого в Interface Builder и создать в нем выход для этого кода. Затем, в viewDidLoad, если topLayoutGuide доступен (iOS 7+), замените ограничение в этой розетке на версию с использованием руководства Top Layout.

if ([self respondsToSelector:@selector(topLayoutGuide)]) {
    [self.view removeConstraint:self.containerTopSpaceConstraint];

    self.containerTopSpaceConstraint =
    [NSLayoutConstraint constraintWithItem:self.contentView
                                 attribute:NSLayoutAttributeTop
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.topLayoutGuide
                                 attribute:NSLayoutAttributeBottom
                                multiplier:1
                                  constant:0];

    [self.view addConstraint:self.containerTopSpaceConstraint];

    [self.view setNeedsUpdateConstraints];
    [self.view layoutIfNeeded];
}

Ответ 2

Для справки, решение ниже работало, когда я применил его к моим ViewControllers. Тем не менее, он не идеален и немного взломан. Если это единственный подход, который я могу принять, то пусть будет так.

float systemVersion=[[[UIDevice currentDevice] systemVersion] floatValue];
if(systemVersion>=7.0f)
{
    CGRect tempRect;
    for(UIView *sub in [[self view] subviews])
    {
        tempRect = [sub frame];
        tempRect.origin.y += 20.0f; //Height of status bar
        [sub setFrame:tempRect];
    }
}

Ответ 3

Apple предлагает вам использовать автозапуск для этого. Вам нужно установить ограничение на "Руководство по верхнему макету" в верхнем подзоне в вашем представлении.

См. этот документ для примеров:

https://developer.apple.com/library/ios/qa/qa1797/_index.html

Для этого без XIB вам нужно будет добавить ограничение программно. Apple docs - хороший пример этого, который я кратко изложил ниже.

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

id topGuide = [myViewController topLayoutGuide];
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(button, topGuide);
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[topGuide]-20-[button]" options:0 metrics:nil views:viewsDictionary]; 

Документацию по этому вопросу можно найти в описании UIViewController.

Ответ 4

1) Самое простое решение, если вы не против иметь непрозрачную панель навигации:

self.navigationController.navigationBar.translucent = NO;

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

Ответ 5

- (void)viewDidAppear:(BOOL)animated {
        [self.view setFrame:CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.height)];
// OR
        self.view.transform = CGAffineTransformMakeTranslation(0, 20);
}

Ответ 6

Пробовали ли вы просматривать ваши XIB в качестве источника и удалять любую строку, содержащую edgeforextendedlayout??

Нам пришлось удалить эту строку в наших сценариях раскадровки, так как основные представления сцен сценки представлены XIBs

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

Удаление этой строки позволило отображать XIB, как если бы их вершина возникла на том же верхнем уровне сцены раскадровки.

К сожалению, мы не знаем, что вызвало это, но я видел, как это произошло при изменении порядка содержимого в основном представлении XIB, чтобы сначала появился UITextView. Переупорядочение порядка элементов после того, как это было вызвано, не повлияло на устранение этого нежелательного поведения.

Надеюсь, что это поможет кому-то еще столкнуться с этой проблемой.

Ответ 7

Если вы используете раскадровку, установив верхний макет своего представления, вы можете снять флажок "Under Opaque Bars" в инспекторе атрибутов

Storyboard