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

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

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

Ответ 1

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

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

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

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

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

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

Ответ 2

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

image

Ответ 3

Вызов 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

Ответ 4

Лео прав, нижнее значениеLayoutGuide возвращается некорректно. Но снятие крайних краев под нижними полосками (или переопределение 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;
}