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;
}