目标C:准确地获得UIView的高度和宽度

Jim*_*ery 2 objective-c dimensions orientation cgrect

我在获取高度和宽度的准确读数时遇到问题.所以我制作了这个快速而又脏的应用来测试这种情况.

这是代码:

@interface wwfpViewController ()
@property (nonatomic, strong) UIView * box;
@property (nonatomic, strong) UILabel * info;
@end

@implementation wwfpViewController
@synthesize box,info;

- (void)viewDidLoad {
    [super viewDidLoad];

    box=[[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    [box setBackgroundColor:[UIColor darkGrayColor]];
    [box setAutoresizesSubviews:YES];
    [box setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];

    info=[[UILabel alloc] initWithFrame:CGRectMake(10, 10, 300, 300)];
    [info setTextColor:[UIColor whiteColor]];
    [info setBackgroundColor:[UIColor blackColor]];
    [info setLineBreakMode:NSLineBreakByWordWrapping];
    [info setNumberOfLines:10];
    [info setText:@"..."];

    [self.view addSubview:box];
    [box addSubview:info];

    [self updateInfo];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(updateView:)
                                                 name:UIApplicationDidChangeStatusBarOrientationNotification
                                               object:nil];

}

- (void) updateInfo {
    CGFloat selfHeight=self.view.frame.size.height;
    CGFloat selfWidth=self.view.frame.size.width;
    CGFloat boxHeight=box.frame.size.height;
    CGFloat boxWidth=box.frame.size.width;
    int deviceOrientation=[[UIDevice currentDevice] orientation];
    int statusOrientation=[[UIApplication sharedApplication] statusBarOrientation];

    NSString * str=[NSString stringWithFormat:@"[height x width] \nself: [%f x %f] \nbox: [%f x %f] \ndevice: %d status: %d",selfHeight,selfWidth,boxHeight,boxWidth,deviceOrientation,statusOrientation];

    [info setText:str];
}

- (void) updateView: (NSNotification*) notify {
    [self updateInfo];
}


@end
Run Code Online (Sandbox Code Playgroud)

当我在iPad上测试时,最初是在纵向模式下,信息标签会报告以下内容:

[height x width]
self: [1004.000000 x 768.000000]
box: [1004.000000 x 768.000000]
device: 0 status: 1
Run Code Online (Sandbox Code Playgroud)

这是对的!

然后当我将iPad旋转到横向时,我会得到以下读数:

[height x width]
self: [768.000000 x 1004.000000]
box: [1004.000000 x 768.000000]
device: 3 status: 3
Run Code Online (Sandbox Code Playgroud)

实际高度x宽度:748 x 1024

但是当我在iPad上横向测试时,信息标签会报告:

[height x width]
self: [1024.000000 x 748.000000]
box: [1024.000000 x 748.000000]
device: 0 status: 3
Run Code Online (Sandbox Code Playgroud)

实际高度x宽度:748 x 1024

然后,当我将iPad旋转为肖像时,我得到以下读数:

[height x width]
self: [748.000000 x 1024.000000]
box: [748.000000 x 1024.000000]
device: 1 status: 1
Run Code Online (Sandbox Code Playgroud)

实际高度x宽度:1004 x 768

我把它旋转回景观,然后我得到这些读数:

[height x width]
self: [768.000000 x 1004.000000]
box: [1004.000000 x 768.000000]
device: 3 status: 3
Run Code Online (Sandbox Code Playgroud)

实际高度x宽度:748 x 1024

在所有情况下,boxUIView都覆盖整个屏幕,因此可以自动调整方向更改.这些结果与模拟器一致,并在实际的iPad上进行测试,我在iPhone上也有类似的体验.

在此之后,我有几个问题:

  1. 我究竟做错了什么?
  2. 为什么高度和宽度与高度和宽度self.view不同,box两者看起来在视觉上相同?
  3. 无论方向如何变化,如何准确获取屏幕或视图的整体高度和宽度.

  4. 因为[UIDevice ... orientation]第一次使用时报告为零,我应该完全忽略它并坚持下去[UIApplication ... statusBarOrientation]吗?

Ian*_*n L 10

检查视图的边界而不是框架:

CGFloat selfHeight=self.view.bounds.size.height;
CGFloat selfWidth=self.view.bounds.size.width;
CGFloat boxHeight=box.bounds.size.height;
CGFloat boxWidth=box.bounds.size.width;
Run Code Online (Sandbox Code Playgroud)

此外,我将使用UIViewController方法更改方向并删除NSNotificationCenter观察者.

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    [self updateInfo];
}
Run Code Online (Sandbox Code Playgroud)

最后,第一次调用以获得正确的大小应该是viewWillAppear因为它在viewDidLoad以下方面是不正确的:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self updateInfo];
}
Run Code Online (Sandbox Code Playgroud)