我正在使用半透明的导航栏和状态栏,我的 View Controller 需要全屏显示。因此,我的 View Controller 的 View 在 Nav 和 Status 栏下延伸并占据了整个屏幕。
我还有一个标签,我想将其直接对齐到导航栏下方。因为我不能直接在标签和导航栏之间添加约束,所以我在标签的顶部和它的父 View 的顶部之间添加了我的约束。我将约束的常量设置为等于状态栏的高度 + 导航栏的高度。
我遇到的问题是在纵向和横向之间旋转期间,因为导航栏的高度发生了变化,我需要我的标签也能很好地旋转,所以我需要知道 中导航栏的新高度>willRotateToInterfaceOrientation:
方法。
当 View Controller 从纵向或横向导航到时,我使用此方法确保标签位于正确的位置。它工作正常。
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Get Y origin for Label
CGFloat navBarY = self.navigationController.navigationBar.frame.origin.y;
CGFloat navBarHeight = self.navigationController.navigationBar.frame.size.height;
CGFloat labelY = navBarY + navBarHeight;
// Set vertical space constraint for Label
self.labelConstraint.constant = labelY;
}
当导航栏高度从 44 像素变为 32 像素时,我使用此方法在方向更改时重新定位标签。问题是,在旋转实际发生之前,我需要获得导航栏在旋转后的新高度。
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
// Get Y origin for Label
CGFloat navBarY = self.navigationController.navigationBar.frame.origin.y;
CGFloat navBarHeight = self.navigationController.navigationBar.frame.size.height;
CGFloat labelY = navBarY + navBarHeight;
// This obviously returns the the current Y origin for label before the rotation
// Which isn't very useful.
NSLog(@"labelY: %f", labelY);
// This code produces the desired effect, but obviously I want to avoid
// hard-coding the values.
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
self.labelConstraint.constant = 20 + 32;
} else {
self.labelConstraint.constant = 20 + 44;
}
}
为了好玩,我尝试在 didRotateFromInterfaceOrientation:
中设置旋转后标签的 Y 原点,但正如预期的那样,它并不平滑,并且标签在旋转完成后卡入到位。
预先感谢您的协助!
最佳答案
答案是:Size Classes。您可以自行了解它,Apple 对此进行了详细记录。您将不得不使用此函数:func willTransitionToTraitCollection(newCollection: UITraitCollection, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)
。设置 View 时,我建议在 View Controller 中添加两个属性,都是 NSLayoutConstraint
数组,一个用于纵向模式,一个用于横向。从 iOS 8 开始,可以同时激活/停用多个约束。在上述函数中,执行以下操作:
if newCollection.verticalSizeClass == .Compact { //orientiation is landscape
NSLayoutConstraint.deactivateConstraints(self.portraitConstraints)
NSLayoutConstraint.activateConstraints(self.landscapeConstraints)
} else {
NSLayoutConstraint.deactivateConstraints(self.landscapeConstraints)
NSLayoutConstraint.activateConstraints(self.portraitConstraints)
}
确保先停用,否则您的约束会发生冲突。
对于“迅速”的回答,我深表歉意,我想您可以将其“翻译”成 ObjC。如果您有任何问题,请随时提出。
关于ios - 在实际旋转之前确定导航栏的新框架 - iOS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17765960/