convertRect:toView:返回双倍大小和距原点两倍的距离

ric*_*chy 5 cocoa-touch uikit uiview ios retina-display

我将图像视图传递给需要图像视图大小的init方法.然后调用convertRect:toView:

- (id) initWithImageView:(UIImageView*) imageView {
    self = [super init];
    if (self) {
        CGRect imageViewFrame = [[imageView superview] convertRect: imageView.frame toView: self.view];
    }
}
Run Code Online (Sandbox Code Playgroud)

这被称为:

MyViewController *viewController = [[MyViewController alloc] initWithImageView:imageView];
viewController.delegate = self;
[self.tabBarController presentViewController:viewController animated:NO completion:nil];
Run Code Online (Sandbox Code Playgroud)

然后是imageViewFrame

(origin = (x = 0, y = -120.22867049625003), size = (width = 750, height = 750))
Run Code Online (Sandbox Code Playgroud)

imageView有一个框架

frame = (0 -60.1143; 375 375);
Run Code Online (Sandbox Code Playgroud)

它的超级视图有一个框架

frame = (0 0; 375 254.5);
Run Code Online (Sandbox Code Playgroud)

为什么它会扩大到x2?

在iPhone 6 plus(3x)模拟器上进一步测试使imageViewFrame成为可能

(origin = (x = 0, y = -199.30952358000002), size = (width = 1242, height = 1242))
Run Code Online (Sandbox Code Playgroud)

第一次测试是在iPhone 6模拟器(2x)上完成的.为什么convertRect:toView:以像素而不是点工作?

Kju*_*uly 2

在您的 中-initWithImageView:,您的self.view尚未生成,您可以尝试缓存imageView临时文件,并在其中执行 rect 转换操作-viewDidLoad

// If you don't user Interface Builder
- (void)loadView
{
   CGRect frame = <your_view_frame>;
   UIView * view = [[UIView alloc] initWithFrame:frame];
   self.view = view;
}

- (void)viewDidLoad
{
  [super viewDidLoad];

  CGRect imageViewFrame = [[imageView superview] convertRect:imageView.frame toView:self.view];
  ...
}
Run Code Online (Sandbox Code Playgroud)

编辑

正如文档针对-convertRect:toView:'s view param 所说:

作为转换操作目标的视图。如果视图为零,则此方法将转换为窗口基坐标。否则,视图和接收者必须属于同一个 UIWindow 对象。

如果您坚持在-initWithImageView方法中执行操作,请在方法中声明自定义视图 iVar、alloc & init -initWithImageView,然后在 中-loadView,将 iVar 分配给self.view。当然,你用来转换 rect 的方式-initWithImageView应该是

CGRect frame = <your_view_frame>;
_iVarView = [[UIView alloc] initWithFrame:frame];
CGRect imageViewFrame = [[imageView superview] convertRect:imageView.frame
                                                    toView:_iVarView];
Run Code Online (Sandbox Code Playgroud)

-loadView

- (void)loadView
{
   self.view = _iVarView;
}
Run Code Online (Sandbox Code Playgroud)

但不建议这样做,我建议你在视图生命周期的正确方法中初始化UI。