English 中文(简体)
谁调整了我的视野?
原标题:Who resized my view? (on iOS)

在Xcode 4.3.2 上使用空App模板创建了一个项目,因此没有涉及NIB。

FooView主计长.m 中:

-(void) loadView {
    UIView *view = [[UIView alloc] init];
    view.backgroundColor = [UIColor yellowColor];
    self.view = view;                     
}

因此,视图被即时化,指定给 self.view 。两种方法:

- (void)viewDidLoad {
    [super viewDidLoad];

    NSLog(@"self.view is %@", self.view);
}

-(void) viewDidAppear:(BOOL)animated {
    NSLog(@"self.view is %@", self.view);
}

第一种方法将打印出来

self.view is <UIView: 0x18e4d0; frame = (0 0; 0 0); layer = <CALayer: 0x182a00>>

第二个打印出来

self.view is <UIView: 0x18e4d0; frame = (0 20; 768 1004); layer = <CALayer: 0x182a00>>

因此,在 view did Load view diddAppear 之间,视图被调整大小。 调整大小的机制是什么? 我们能否真正指望它? 因为即使是马特·纽堡, 著名书编程 iOS, 2nd Ed的作者, 也是这样做的(见第508页)。

问题回答

You have to understand the ViewController lifecycle. In viewDidLoad the views will be created but the boundaries/dimensions won t be set. That will happen in a following step. You can use viewWillAppear for setting dimensions (what most people do). ViewDidAppear happens last, and there you already have the final appearance and the animations already started.

所以,在“Load”和“DidAppear”的视图之间, 这个视图得到了它的维度和界限, 它完全可靠, 并且记录在“View Consultal docs”中。

还请注意,每次需要创建视图时(类似第一次和在低记忆警告后-在需要内存时通常会将视图分配到一起-),每次查看控制器在堆栈顶部,且其视图即将发布时,都会呼叫WillAppear。

Have a look at the documentation related to view appearance: http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/RespondingtoDisplay-Notifications/RespondingtoDisplay-Notifications.html#//apple_ref/doc/uid/TP40007457-CH12

默认情况下, < a href="" "http:// developer.apple.com/library/ios/documentation/uikit/reference/uiview_glift/uiview/uiview.html#/apple_ref/oc/intp/instp/UIView/autoriezesSubviews" rel="nofollow" code>autorizesSubviews 属性将会在显示其子视图时导致对其子视图进行重新缩放。

在屏幕上显示之前不会实际创建自我。 视图是懒惰的。 调用 < code> view willAppear 后, 框架将被设置。 是的, 您可以信任这些值, 因为它们是根据电话的屏幕和方向设置的 。

自我. view 是一个相当特殊的视图, 我经常不直接使用它, 我通常只是添加一个容器子视图, 并将其作为主要视图处理。 由于调整大小, 最好不要将自我. view 当作静态实体对待 。 确保您在子视图中设置对面罩的自动化, 以便当自我. view 更改时能够正确显示这些面罩 。

要进一步回答您的问题, UIKit 具体设置视图框架, 以考虑到屏幕大小、 方向、 导航栏、 状态栏、 工具栏等。 您不能保证您在调用 < code> viewWillAppear 之前设定的框架是相同的。 事实上, 如果导航条、 方向或其他因素发生变化, 自我. view会变更多 。 所以即使到了 < code> viewWill Display 之后, 您也得不到自定义静态大小的保障 。 view, 如果您更改它, 它将会被适当重新设置以反映设备的状况 。

UIKit负责这个执行细节, 这是一种奢侈, 因为那样我们就不必考虑装置的具体变化,

当您将 viewcurrent s view s view 改为 ruotVictor application s window /strong>时, 似乎被重新缩放为 。 否则您必须手工设置框架 。

我试过这个代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];

    FooViewController *viewController = [[FooViewController alloc] init];

    self.window.rootViewController = viewController; 
    [self.window makeKeyAndVisible];

    FooViewController *viewController2 = [[FooViewController alloc] init];
    [viewController.view addSubview: [viewController2 view]];

    return YES;
}

view主计长 已调整大小, view主计长2 未调整大小。

另外:对于view主计长 ,所有这些方法都称为:

viewDidLoad
viewWillLayoutSubviews
viewDidLayoutSubviews
viewDidAppear

view Load view didAppear 被调用。

有趣的是:在调用 view主计长 前,对 viewWillLayoutSubviews 进行了调整。

编辑:

我想这值得进一步测试 用以下代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];

    FooViewController *viewController = [[FooViewController alloc] init];
    NSLog(@"after init: self.view is %@", viewController.view);
    self.window.rootViewController = viewController; 
    NSLog(@"after setting to rootViewController: self.view is %@", viewController.view);
    [self.window makeKeyAndVisible];
    NSLog(@"after makeKeyAndVisible: self.view is %@", viewController.view);

    return YES;
}

结果如下:

viewDidLoad:                         frame = (0 0; 0 0)
after init:                          frame = (0 0; 0 0)
after setting to rootViewController: frame = (0 0; 0 0)
after makeKeyAndVisible:             frame = (0 20; 320 460)
viewWillLayoutSubviews:              frame = (0 20; 320 460)
viewDidLayoutSubviews:               frame = (0 20; 320 460)
viewDidAppear:                       frame = (0 20; 320 460)

因此,“强势”代码[自. 窗口使Key和可视];“/code/强”是罪魁祸首。





相关问题
List Contents of Directory in a UITableView

I am trying to list the contents of Ringtones directory in a TableView, however, I am only getting the last file in the directory in ALL cells, instead of file per cell. This is my code: - (...

iPhone NSUserDefaults persistance difficulty

In my app i have a bunch of data i store in the NSUserdefaults. This information consists of an NSObject (Object1) with NSStrings and NSNumbers and also 2 instances of yet another object (Object2). ...

Writing a masked image to disk as a PNG file

Basically I m downloading images off of a webserver and then caching them to the disk, but before I do so I want to mask them. I m using the masking code everyone seems to point at which can be found ...

Resize UIImage with aspect ratio?

I m using this code to resize an image on the iPhone: CGRect screenRect = CGRectMake(0, 0, 320.0, 480.0); UIGraphicsBeginImageContext(screenRect.size); [value drawInRect:screenRect blendMode:...

Allowing interaction with a UIView under another UIView

Is there a simple way of allowing interaction with a button in a UIView that lies under another UIView - where there are no actual objects from the top UIView on top of the button? For instance, ...