iOS自动布局-将位于tableviewcell内的 View 移动到屏幕中央

标签 ios uitableview autolayout

我有一个表格 View ,其中的单元格包含 TextView 和 ImageView 。我的项目目前正在使用 AutoLayout。我的目标是让 imageview 在被点击时全屏显示。一种选择是使用模态视图 Controller ,但我想让这项工作有点像在 Facebook 应用程序中点击图像的方式,应用程序将图像居中并淡化背景。

因为我使用的是自动版式,我不能简单地设置 imageview 的框架来填充屏幕。相反,我需要使用自动布局约束。我的 ImageView 有 5 个约束,一个约束设置与单元格底部的距离,以及左侧和右侧,一个控制图像高度。最后一个是 ImageView 上方的 TextView 和图像顶部之间的垂直空间约束。虽然这似乎与高度和底部约束冲突,但出于某种原因,界面构建器迫使我拥有它。为避免出现问题,我将此约束的优先级设置为小于 1000(无论如何图像都不应与 textview 重叠,因为已设置 tableview 单元格高度,所以一切都将完美匹配)。

为了使图像居中,我将左右距离设置为零并移除了垂直空间限制。为了使图像居中,我将底部空间约束替换为 UIWindow 的中心 y 对齐约束,而不是 tableviewcell。我想让它位于屏幕中央,而不是单元格。

要获取主窗口,我使用这个:

AppDelegate* myDelegate = (((AppDelegate*) [UIApplication sharedApplication].delegate));
//access main window using myDelegate.window

然后,设置约束:

//currently sets the distance from the bottom of the cell to 14
//changing it...
[cellselected removeConstraint:cellselected.imagebottomspace];
cellselected.imagebottomspace = [NSLayoutConstraint constraintWithItem:cellselected.viewimage attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:myDelegate.window attribute:NSLayoutAttributeCenterY multiplier:0 constant:0];
[cellselected addConstraint:cellselected.imagebottomspace];

但是,这是行不通的。 ImageView 宽度和高度的变化应用得很好。但是,当读取 imagebottomspace 约束时,我得到了一个无法满足的布局——显然该约束与另一个约束冲突,后者将底部和 ImageView 之间的距离设置为 14,我刚刚删除的约束。所以它似乎并没有真正消除约束。

当我继续并让应用程序打破约束时, ImageView 会移动,但会移动到错误的位置。它不在屏幕中央。它向上移动并离开屏幕。

显然我的做法是不对的。我做错了什么?

最佳答案

所以我猜你想要这样的东西:

zooming image view demo

首先,您需要知道,从 Xcode 4.6.3 开始,nib 编辑器(“Interface Builder”)在表格 View 单元格中设置约束时存在错误。它应该在 subview 和单元格的内容 View 之间创建约束,但它会在 subview 和单元格本身之间创建约束。这往往会在运行时搞砸布局。 (此错误已在 Xcode 5 及更高版本中修复。)

这样做的结果是,您应该删除 nib 中的所有约束并在代码中重新创建它们,或者干脆去掉 nib 并在代码中创建单元格的整个 View 层次结构。

其次,有一种更简单的方法来进行图像缩放。以下是选择单元格时的基本过程:

  1. 将所选单元格的 ImageView 边界转换为顶级 View 坐标系中的 CGRect
  2. 创建一个仅用于缩放的新 ImageView ,并将其框架设置为该 CGRect。将其 userInteractionEnabled 设置为 YES。将其 autoresizingMask 设置为灵活的宽度和高度。添加点击手势识别器。
  3. 将新 ImageView 添加为顶级 View 的 subview 。
  4. 将单元格的 ImageView 的 hidden 属性设置为 YES
  5. 在动画 block 中,将新 ImageView 的框架设置为顶级 View 的边界。
  6. 禁用 TableView 的 panGestureRecognizer

当新的 ImageView 被点击时,反向操作:

  1. 将所选单元格的 ImageView 边界转换为顶级 View 坐标系中的 CGRect
  2. 在动画 block 中,将缩放 ImageView 的框架设置为该 CGRect
  3. 在动画完成 block 中:
    1. 从其父 View 中删除缩放 ImageView 。
    2. 将单元格的 ImageView 的 hidden 属性设置为 NO
    3. 启用 TableView 的 panGestureRecognizer

因为您没有移动原始 ImageView ,所以您不必弄乱它的约束。隐藏 View 仍然参与布局。

由于您是在代码中创建新的 ImageView ,因此它会将 translatesAutoresizingMaskIntoConstraints 默认设置为 YES。这意味着您可以设置它的框架。自动布局会自动将框架变成约束。

您可以在 this github repository 中找到完整的源代码.

关于iOS自动布局-将位于tableviewcell内的 View 移动到屏幕中央,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17439957/

相关文章:

ios - 使用 UITableView 调整 UICollectionView 大小,并以动态标题作为单元格

ios - UICustom 单元格在 iOS 7 中不显示标签

ios - 以编程方式使用自动布局约束在 UIView Swift 2.3 iOS10 中将 UIImageView 居中

ios - 更改 UIStackView 中 UIImageView 的高度优先级

ios - 获取 NSLayoutConstraints 关联 View

ios - 如何在 Swift 中检查用户是否已在应用内购买中支付自动续订订阅费用

ios - Xcode 找不到我在项目中制作的 .h 文件

ios - UITableView 的异步加载

iphone - 如何使用 OS 3.1 MapKit 实现可拖动的引脚?

ios - 按下主页按钮时如何关闭 UIAlertView?