UIViews заканчиваются под панелью вкладок

В моем приложении я выровнял метку по стандартному количеству из bottomLayoutGuide, используя autolayout. При первом запуске приложения все выкладывается так, как я хотел, но когда я переключаю вкладки и возвращаюсь назад, ярлык исчезает под контроллером панели вкладок.

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

4 ответа

Решение

Это происходит из-за ошибки в iOS7, где нижнее руководство по разметке неправильно установлено на высоту 0 вместо высоты панели вкладок. При повороте устройства нижняя направляющая будет установлена ​​правильно.

В настоящее время лучшим вариантом является отключение расширенного нижнего макета:

- (UIRectEdge)edgesForExtendedLayout
{
    return [super edgesForExtendedLayout] ^ UIRectEdgeBottom;
}

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

Обязательно откройте отчет об ошибке на https://bugreport.apple.com/

Чтобы уточнить немного больше, кажется viewDidLayoutSubviews вызывается дважды при переключении контроллеров представления. В первый раз все настроено правильно, но во второй раз высота направляющей нижнего макета равна 0. Из трассировки стека видно, что первый поступает из макета панели вкладок, а второй вызов из запланированного макета CALayer, что неверно.,

Хотя в ответе Лео показано, как это сделать программно, если вы хотите сделать это из конструктора интерфейса, выберите ваш View Controller и снимите флажок "Под нижними панелями" в разделе "Расширить края":

образ

Вызов setNeedsLayout - это все, что нужно сделать. По сути, это исправляет ошибку фреймворка. Он должен вызываться в самом представлении UITabBarController при выборе нового представления. Создайте делегата для контроллера панели вкладок приложения. и поместите это в объект делегата:

@interface MyPatch : NSObject <UITabBarControllerDelegate>

@end

@implementation MyPatch

-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
    [tabBarController.view setNeedsLayout];
}

@end

И инициализировать его где угодно... как-то так:

@interface AppDelegate : UIResponder <UIApplicationDelegate>
{
         MyPatch *patch;

}

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    patch=[MyPatch new];
    myTabBarController.delegate=patch;
}

@end

Лев прав, bottomLayoutGuide возвращается неправильно. Но отмена выдвижения краев под нижними планками (или переопределение edgesForExtendedLayout) имел слишком много нежелательных эффектов для других подпредставлений для меня.

Если вы хотите изменить только ограничение для одного вида в соответствии с нижним руководством по компоновке, внедрите viewWillLayoutSubviews и проверьте значение bottomLayoutGuide свойство и адаптировать это одно ограничение, если требуется, например, так:

- (void)viewWillLayoutSubviews {
    [self adaptBottomLayoutGuides];
}

/// Workaround for iOS7 bug returning wrong bottomLayoutGuide length if this is 1st tab in TabViewController
- (void)adaptBottomLayoutGuides {
    NSLog(@"%f", self.bottomLayoutGuide.length);

    CGFloat expectedHeight = 123;
    CGFloat adaptedSpacing = expectedHeight - self.bottomLayoutGuide.length;
    self.viewBottomLayoutSpacingConstrain.constant = adaptedSpacing;
}
Другие вопросы по тегам