在iOS 8中,我移动我的代码依靠viewWillTransitionToSize
调整我在UITabBarController下的viewControllers。但是,当当前未显示视图时,传递给它的大小不正确。
我写了一个小程序来隔离问题。它只是创建两个VC,标记它们,将它们放在TabBarController中,然后报告传递给viewWillTransitionToSize的大小。如果要重新创建它,可以使用以下代码替换虚拟项目AppDelegate.m。
输出低于程序。我做错了什么,或者是否有解决方法来获得正确的即将到来的尺寸?
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
@interface MyViewController : UIViewController
@property (strong, nonatomic) NSString * detailItem;
@end
@implementation MyViewController
- (void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
NSLog(@"%@ will transition from %@ to %@",self.detailItem, NSStringFromCGSize(self.view.frame.size), NSStringFromCGSize(size));
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
MyViewController * firstVC = [[MyViewController alloc] initWithNibName:nil bundle:nil];
firstVC.detailItem = @"Bookmark controller";
firstVC.tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem: UITabBarSystemItemBookmarks tag:0];
MyViewController *secondVC = [[MyViewController alloc] initWithNibName:nil bundle:nil];
secondVC.detailItem = @"History controller";
secondVC.tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem: UITabBarSystemItemHistory tag:1];
UITabBarController * tabBarController = [[UITabBarController alloc] initWithNibName:nil bundle:nil];
[tabBarController setViewControllers: @[firstVC, secondVC]];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
@end
输出如下:
<<starting in Bookmark VC in Portrait; transition to Landscape>>
Bookmark controller will transition from {375, 667} to {667, 375} <<Correct>>
History controller will transition from {375, 667} to {0, 0} <<Very wrong>>
<<transition back to Portrait>>
Bookmark controller will transition from {667, 375} to {375, 667} <<Correct>>
History controller will transition from {375, 667} to {667, 375} <<Wrong>>
<<switch to History tab; transition to Landscape>>
Bookmark controller will transition from {375, 667} to {375, 667} <<Wrong>>
History controller will transition from {375, 667} to {667, 375} <<Correct; note prev wrong size is now correct without notification>>
<<transition back to Portrait>>
Bookmark controller will transition from {375, 667} to {375, 667} <<Correct but still wrong current size>>
History controller will transition from {667, 375} to {375, 667} <<Correct>>
答案 0 :(得分:3)
我尝试使用下面的代码解决此问题。我不确定这是否100%正确,所以如果有人有一个好的解决方案,那么请告诉我们。
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
for viewController in viewControllers! {
viewController.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}
}
答案 1 :(得分:0)
没有;坦率地说,我作弊,并使用了以下版本的viewWillTransitionToSize
(在真实程序中,这是Apple的AAPLTraitOverrideViewController的子类,让我在iPhone 6上执行双窗格)。
它依赖于当前所选选项卡中的VC具有正确的旧帧大小这一事实,因此当为未选择的选项卡调用viewWillTransitionToSize
时,它会查看其兄弟给它的实际大小。然后它应用当前变换并采用绝对值以避免负数。请注意,这仅在VC是标签控制器的直接子节点时才有效。
如果您(或任何人)想出更好的方法,请告诉我们!
- (void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
NSLog(@"%@ will transition from %@ to %@",self.detailItem, NSStringFromCGSize(self.view.frame.size), NSStringFromCGSize(size));
CGSize realSize = size;
if (self.tabBarController) {
//workaround for inaccurate sizes being delivered to non-selected tabs
NSArray * viewControllers = self.tabBarController.viewControllers;
NSUInteger myIndex = [viewControllers indexOfObject:self];
NSUInteger selectedIndex = self.tabBarController.selectedIndex;
if (selectedIndex != myIndex && myIndex != NSNotFound && selectedIndex != NSNotFound) {
//not on screen, so use size from selected tab, transformed as indicated by coordinator
UIViewController * selectedVC = viewControllers[selectedIndex];
CGSize newSize = CGSizeApplyAffineTransform(selectedVC.view.frame.size, [coordinator targetTransform]);
realSize = CGSizeMake(fabsf(newSize.width), fabsf(newSize.height));
NSLog(@" Instead of: %@, rotating to correct size: %@ ",NSStringFromCGSize(size),NSStringFromCGSize(realSize));
}
}
[super viewWillTransitionToSize:realSize withTransitionCoordinator:coordinator];
}