为啥这个 UIImageView 会自动居中?

Posted

技术标签:

【中文标题】为啥这个 UIImageView 会自动居中?【英文标题】:Why is this UIImageView autocentering itself?为什么这个 UIImageView 会自动居中? 【发布时间】:2011-03-13 07:32:18 【问题描述】:

我在另一个 UIScrollView 的 UIScrollView 中有一个 UIImageView(基于 Apple 的 PhotoScroller sample code)。当 UIScrollView 回调其控制器以关闭自身时,它会调用此方法:

- (void)dismiss 
    [scrollView removeFromSuperview];
    ImageScrollView *isv = [self currentImageScrollView];
    UIImage *image = isv.imageView;
    image.frame = [self.view convertRect:image.frame fromView:isv];

    [self.view insertSubview:image belowSubview:captionView];
    [(NSObject *)delegate performSelector:@selector(scrollViewDidClose:)
                               withObject:self
                               afterDelay:2.0];

现在这是奇怪的部分:图像视图在此方法执行后立即跳转到不同的位置,但在 scollViewDidClose 方法被委托调用之前。如果图像大于其新的超级视图,它会跳转,使其左边缘与其超级视图的左边缘对齐。如果它比它的新超级视图小,它会跳到视图的中心。此更改没有动画。

所以我的问题是,我该如何防止它这样做?我已经调整了超级视图 (self.view) 类和图像视图类,以查看可以调用哪些方法。调用此方法后,图像视图上既没有设置边框也没有设置中心,而在超级视图上调用了layoutSubviews 方法,即不是将图像跳转到中心或超级视图的左侧。我还尝试在超级视图中关闭autoResizesSubviews,并将图像视图的autoresizingMask 设置为UIViewAutoresizingNone,而行为没有变化。

那么这发生在哪里,为什么?更重要的是,如何让它停止?

这几天我一直在苦苦思索。任何指针或指导将不胜感激。

【问题讨论】:

您没有发布正确的代码。 UIScrollView 没有 imageView 属性,UIImage 没有 frame 属性。 Darren — 我正在使用基于 Apple 的 PhotoScroller example code 的 UIScrollView 的子类,它有一个 imageView ivar,我只是为其添加了一个访问器。 我已将类更改为ImageScrollView,它是具有imageView 属性的子类。感谢现场。 【参考方案1】:

ImageScrollView 是你的 UIImageView 的中心。在ImageScrollView layoutSubviews 中设置断点,您将看到 UIImageView 是如何居中的。

您正在获取ImageScrollView 的内部imageView 并将其置于另一个视图中。这是行不通的,因为ImageScrollView 仍然保留该UIImageView 实例的所有权并且仍在管理其布局。

您需要将图像复制到另一个UIImageView 实例中,或者您需要更改ImageScrollView 以允许它放弃其imageView 的所有权。

【讨论】:

我尝试在ImageScrollView 上设置一个标志,以便layoutSubviews 返回而不在我的UIScrollView 子类中执行任何操作。它没有效果;图像仍然居中。此外,在我的示例代码中,包含 ImageScrollView 的 UIScrollView 已从其父视图中删除。所以事实上,layoutSubviews 根本没有被调用——至少在我的-dismiss 方法完成执行之后没有调用。我会再愚弄一下,但我很确定layoutSubviews 不是这里的罪魁祸首——呃,除非它是父 UIScrollView 的原因。接下来必须检查。 只是摆弄,没有乐趣。 :-( 请注意 scrollView 已从其超级视图中删除。这可以防止在 scrollView UIScrollViewImageScrollView 中调用 layoutSubviews,或者至少在此代码执行后不会调用它们. 但是,我确实注意到,图像只是水平方向,而不是垂直方向。Hrm。可能是我的dismiss 方法之前调用了居中的代码,但它的效果正在发生之后的地方?这让我很困惑…… 好的,刚刚又做了一次,清理了一些东西,发现你完全正确,Darren。伙计哦 man 我很高兴终于解决了这个问题。非常感谢您的回答。 哦,顺便说一句,让它工作的关键是删除行`[scrollView removeFromSuperview];`。出于某种奇怪的原因,它继续进行居中。我不明白,但很高兴问题得到解决。【参考方案2】:

当您将“图像”视图作为子视图插入时,您没有设置它的框架。如果您希望视图显示在滚动视图中的特定位置,您可能需要明确地执行此操作。

【讨论】:

谢谢,这似乎很明显,不是吗?我担心我会让这个例子过于简单。不幸的是,我实际上已经在这段代码中以各种方式设置框架。它可以放在我放置的任何地方,但一旦此方法完成执行,它仍会立即转移到其新超级视图的中心。我更新了示例代码以反映这种可悲的情况。

以上是关于为啥这个 UIImageView 会自动居中?的主要内容,如果未能解决你的问题,请参考以下文章

调整大小后使用自动布局以编程方式居中 UIImageVIew

为啥更改 UIImageView 内容模式会影响其在 Xcode6 中的自动布局?

在 UIImageView 上一致地居中 CALayer 子层

以编程方式使用约束使 UIIMageView 居中

将 UIImageView 与自动布局对齐

UIImageVIew 根据 ImageView 大小裁剪图像中心