2

我无法准确读取高度和宽度。所以我做了这个快速而肮脏的应用程序来测试情况。

这是代码:

@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

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

[height x width]
self: [1004.000000 x 768.000000]
box: [1004.000000 x 768.000000]
device: 0 status: 1

这是对的!

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

[height x width]
self: [768.000000 x 1004.000000]
box: [1004.000000 x 768.000000]
device: 3 status: 3

实际高度 x 宽度:748 x 1024

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

[height x width]
self: [1024.000000 x 748.000000]
box: [1024.000000 x 748.000000]
device: 0 status: 3

实际高度 x 宽度:748 x 1024

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

[height x width]
self: [748.000000 x 1024.000000]
box: [748.000000 x 1024.000000]
device: 1 status: 1

实际高度 x 宽度:1004 x 768

我将其旋转回横向,然后得到以下读数:

[height x width]
self: [768.000000 x 1004.000000]
box: [1004.000000 x 768.000000]
device: 3 status: 3

实际高度 x 宽度:748 x 1024

在所有情况下,boxUIView 都会覆盖整个屏幕,因此它会自动调整正确的方向变化。这些结果与模拟器和实际 iPad 上的测试结果一致,我在 iPhone 上也有类似的体验。

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

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

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

5 回答 5

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;

此外,我会使用该UIViewController方法更改方向并移除NSNotificationCenter观察者。

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    [self updateInfo];
}

最后,获取正确大小的第一个调用应该是 in ,viewWillAppear因为它会不正确 in viewDidLoad

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self updateInfo];
}
于 2013-08-13T16:04:40.090 回答
1

我试过你的代码,发现这里有一个错误。

错误的原因-您没有navigationController基于appdelegate. 将您window的 '设置rootViewControllernavigationController不知道为什么,但viewController基于 ' 的视图没有给出正确的框架。

我的意见 -notification当你已经有一个
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation在方向改变后调用的方法时,不要在这里使用。好吧,您正在使用notificationNP,这只是我的看法。

还有一件事我想说

box = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];

你为什么不干脆做

box = [[UIView alloc] initWithFrame:self.view.bounds];

你的代码没问题。只需将窗口的 rootViewController 设置为 navigationController 或 tabbarController。

这是示例代码

于 2013-08-14T04:40:08.023 回答
0

来自苹果文档

讨论 当视图的边界发生变化时,该视图会根据每个子视图的自动调整大小掩码自动调整其子视图的大小。您可以通过使用 C 位 OR 运算符组合 UIViewAutoresizing 中描述的常量来指定此掩码的值。结合这些常量,您可以指定视图的哪些尺寸应该相对于父视图增大或缩小。该属性的默认值为 UIViewAutoresizingNone,表示视图根本不应该调整大小。

当沿同一轴设置多个选项时,默认行为是在柔性部分之间按比例分配大小差异。相对于其他柔性部分,柔性部分越大,它越可能增长。例如,假设该属性包含 UIViewAutoresizingFlexibleWidth 和 UIViewAutoresizingFlexibleRightMargin 常量但不包含 UIViewAutoresizingFlexibleLeftMargin 常量,则表示视图左边距的宽度是固定的,但视图的宽度和右边距可能会发生变化。因此,视图看起来锚定在其父视图的左侧,而视图宽度和视图右侧的间隙都增加了。

如果自动调整大小的行为不能提供视图所需的精确布局,则可以使用自定义容器视图并覆盖其 layoutSubviews 方法来更精确地定位子视图。

它可能与在这里autoresizing masks阅读更多相关信息有关。

于 2013-08-13T16:00:38.290 回答
0

myview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];

为我工作

于 2018-03-27T09:13:53.353 回答
0

我已经制作了宏vWidthvHeight它将正确处理所有这些逻辑,并带有后备:

#define sWidth [[UIScreen mainScreen] bounds].size.width
#define sHeight [[UIScreen mainScreen] bounds].size.height

#define vWidth (\
(^float (void){\
BOOL isClassMethod = [[self class] respondsToSelector:_cmd];\
if (isClassMethod) {\
return sWidth;\
} else {\
float __vWidth = ([self isKindOfClass:[UIViewController class]]?((UIViewController *)self).view.frame.size.width:((UIView *)self).frame.size.width);\
if (!__vWidth) {\
__vWidth = ([self isKindOfClass:[UIViewController class]]?((UIViewController *)self).view.superview.frame.size.width:((UIView *)self).superview.frame.size.width);\
}\
if (!__vWidth) {\
__vWidth = sWidth;\
}\
return __vWidth;\
}\
})()\
)
#define vHeight (\
(^float (void){\
BOOL isClassMethod = [[self class] respondsToSelector:_cmd];\
if (isClassMethod) {\
return sHeight;\
} else {\
float __vHeight = ([self isKindOfClass:[UIViewController class]]?((UIViewController *)self).view.frame.size.height:((UIView *)self).frame.size.height);\
if (!__vHeight) {\
__vHeight = ([self isKindOfClass:[UIViewController class]]?((UIViewController *)self).view.superview.frame.size.height:((UIView *)self).superview.frame.size.height);\
}\
if (!__vHeight) {\
__vHeight = sHeight;\
}\
return __vHeight;\
}\
})()\
)
于 2018-06-22T08:26:30.200 回答