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

Posted

技术标签:

【中文标题】convertRect:toView:返回两倍大小和与原点的距离的两倍【英文标题】:convertRect: toView: returns double size and twice the distance from the origin 【发布时间】:2015-04-24 08:29:55 【问题描述】:

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

- (id) initWithImageView:(UIImageView*) imageView 
    self = [super init];
    if (self) 
        CGRect imageViewFrame = [[imageView superview] convertRect: imageView.frame toView: self.view];
    

调用方式:

MyViewController *viewController = [[MyViewController alloc] initWithImageView:imageView];
viewController.delegate = self;
[self.tabBarController presentViewController:viewController animated:NO completion:nil];

imageViewFrame 然后是

(origin = (x = 0, y = -120.22867049625003), size = (width = 750, height = 750))

imageView 有一帧

frame = (0 -60.1143; 375 375);

它的超级视图是有一个框架

frame = (0 0; 375 254.5);

为什么要放大 2 倍?

在 iPhone 6 plus (3x) 模拟器上进一步测试生成 imageViewFrame

(origin = (x = 0, y = -199.30952358000002), size = (width = 1242, height = 1242))

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

【问题讨论】:

你将 ImageView 传递给什么类?是 UIScrollView 还是类似的东西? 你为什么不直接使用imageview的框架比如:CGRect imageViewFrame = imageView.frame; ps4 - 它只是一个 UIViewController 子类 Mrunal - 因为我不知道 [imageView superview] 会一直处于 0,0。 你应该提供更多的代码,现在很难说是什么问题。你在哪里调用这个初始化函数?可以展示一下吗? 【参考方案1】:

在你的-initWithImageView:,你的self.view还没有生成,你可以尝试缓存imageView临时,在-viewDidLoad做rect转换动作:

// 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];
  ...


编辑

正如文档对-convertRect:toView: 的视图参数所说:

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

如果你坚持在-initWithImageView方法中做,在你的-initWithImageView方法中声明一个自定义视图iVar,alloc & init,然后在-loadView中,将iVar分配给self.view。当然,你在-initWithImageView中转换rect的方式应该是

CGRect frame = <your_view_frame>;
_iVarView = [[UIView alloc] initWithFrame:frame];
CGRect imageViewFrame = [[imageView superview] convertRect:imageView.frame
                                                    toView:_iVarView];

-loadView:

- (void)loadView

   self.view = _iVarView;

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

【讨论】:

这很好,但在这种情况下,我需要 init 中的大小。如果未加载视图,convertRect:toView: 是否会回退到像素?调用 self.view 作为 convertRect:toView: 的参数还不够早,无法处理点?【参考方案2】:

这是一个正确的方法: 斯威夫特:

extension UIView 

    func convertRectCorrectly(rect: CGRect, toView view: UIView) -> CGRect 
        if UIScreen.mainScreen().scale == 1 
            return self.convertRect(rect, toView: view)
        
        else if self == view 
            return rect
        
        else 
            var rectInParent = self.convertRect(rect, toView: self.superview)
            rectInParent.origin.x /= UIScreen.mainScreen().scale
            rectInParent.origin.y /= UIScreen.mainScreen().scale
            let superViewRect = self.superview!.convertRectCorrectly(self.superview!.frame, toView: view)
            rectInParent.origin.x += superViewRect.origin.x
            rectInParent.origin.y += superViewRect.origin.y
            return rectInParent
        
    

【讨论】:

以上是关于convertRect:toView:返回两倍大小和与原点的距离的两倍的主要内容,如果未能解决你的问题,请参考以下文章

了解 convertRect:toView:、convertRect:FromView:、convertPoint:toView: 和 convertPoint:fromView: 方法

- (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view

iOS convertRect:view.frame toView: x 异常翻倍?

OC convertRect

为啥 mysqli_fetch_array() 返回数组大小的两倍? [关闭]

iOS convertPoint:toView: 返回不一致的值