我有一个表格 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 会移动,但会移动到错误的位置。它不在屏幕中央。它向上移动并离开屏幕。
显然我的做法是不对的。我做错了什么?
最佳答案
所以我猜你想要这样的东西:
首先,您需要知道,从 Xcode 4.6.3 开始,nib 编辑器(“Interface Builder”)在表格 View 单元格中设置约束时存在错误。它应该在 subview 和单元格的内容 View 之间创建约束,但它会在 subview 和单元格本身之间创建约束。这往往会在运行时搞砸布局。 (此错误已在 Xcode 5 及更高版本中修复。)
这样做的结果是,您应该删除 nib 中的所有约束并在代码中重新创建它们,或者干脆去掉 nib 并在代码中创建单元格的整个 View 层次结构。
其次,有一种更简单的方法来进行图像缩放。以下是选择单元格时的基本过程:
- 将所选单元格的 ImageView 边界转换为顶级 View 坐标系中的
CGRect
。 - 创建一个仅用于缩放的新 ImageView ,并将其框架设置为该
CGRect
。将其userInteractionEnabled
设置为YES
。将其autoresizingMask
设置为灵活的宽度和高度。添加点击手势识别器。 - 将新 ImageView 添加为顶级 View 的 subview 。
- 将单元格的 ImageView 的
hidden
属性设置为YES
。 - 在动画 block 中,将新 ImageView 的框架设置为顶级 View 的边界。
- 禁用 TableView 的
panGestureRecognizer
。
当新的 ImageView 被点击时,反向操作:
- 将所选单元格的 ImageView 边界转换为顶级 View 坐标系中的
CGRect
。 - 在动画 block 中,将缩放 ImageView 的框架设置为该
CGRect
。 - 在动画完成 block 中:
- 从其父 View 中删除缩放 ImageView 。
- 将单元格的 ImageView 的
hidden
属性设置为NO
。 - 启用 TableView 的
panGestureRecognizer
。
因为您没有移动原始 ImageView ,所以您不必弄乱它的约束。隐藏 View 仍然参与布局。
由于您是在代码中创建新的 ImageView ,因此它会将 translatesAutoresizingMaskIntoConstraints
默认设置为 YES
。这意味着您可以设置它的框架。自动布局会自动将框架变成约束。
您可以在 this github repository 中找到完整的源代码.
关于iOS自动布局-将位于tableviewcell内的 View 移动到屏幕中央,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17439957/