我基本上试图模仿Instagram的时间线视图的外观和感觉,它允许在UITableViewCell
中显示各种宽高比的照片,并且左右齐平观点的边缘。
截至目前,我已将自动布局约束设置为尾部和前导设置为superview,两者都设置为常量0,并为周围元素设置底部空间和顶部空间约束。就图像本身而言,我将它设置为16:9的宽高比约束,但是在构建时删除"删除",因为图像有时可能具有不同的宽高比(16:12是一个)。
由于我在异步下载相关图像之前可以访问下载的JSON文件中的图像尺寸信息,因此我想在创建tableView时设置图像的高度/宽度约束JSON数据。截至目前,我正在从UITableViewController cellForRowAtIndexPath
调用的函数中的UITableViewCell子类中创建约束。以下是我用来创建约束的代码:
func configurePostTableViewCell(post: Post) {
self.newsfeedPhotoImageView.translatesAutoresizingMaskIntoConstraints = false
let photoHeight: CGFloat = CGFloat(post.photoHeight)
let photoWidth: CGFloat = CGFloat(post.photoWidth)
let aspectRatioConstraint: NSLayoutConstraint = NSLayoutConstraint(item: self.timelinePhotoImageView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: self.timelinePhotoImageView, attribute: NSLayoutAttribute.Width, multiplier: (photoHeight / photoWidth), constant: 0)
aspectRatioConstraint.identifier = "$programmaticAspectRatio$"
self.timelinePhotoImageView.addConstraint(aspectRatioConstraint)
}
正如我所提到的,函数本身是在cellForRowAtIndexPath
内调用的,我尝试在cell.
中使用与tableViewController
相同的代码,但最终的结果是相同的:
当我构建并运行时,代码最初看起来效果很好,两张不同方面的照片都能正确显示。然而问题是,当我向下滚动11行左右时(我假设)前几个单元格已经出列以便重复使用。我在单元格中设置了一个属性观察器,以便在单元格去初始化时打印到控制台,并且在单元格出列的同时出现以下错误:
2016-03-08 23:59:34.277 MyProject[12255:8479975] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x7fe8c2c31820 '$timelinePhotoLeading$' H:|-(0)-[MyProject.AsyncImageView:0x7fe8c2d16080] (Names: '|':UITableViewCellContentView:0x7fe8c2d13cb0 )>",
"<NSLayoutConstraint:0x7fe8c2d0b230 '$timelinePhotoTrailing$' H:[MyProject.AsyncImageView:0x7fe8c2d16080]-(0)-| (Names: '|':UITableViewCellContentView:0x7fe8c2d13cb0 )>",
"<NSLayoutConstraint:0x7fe8c2d1b3d0 '$programmaticAspectRatio$' MyProject.AsyncImageView:0x7fe8c2d16080.height == 0.75*MyProject.AsyncImageView:0x7fe8c2d16080.width>",
"<NSLayoutConstraint:0x7fe8c0dae7f0 '$programmaticAspectRatio$' MyProject.AsyncImageView:0x7fe8c2d16080.height == 0.5625*MyProject.AsyncImageView:0x7fe8c2d16080.width>",
"<NSLayoutConstraint:0x7fe8c2d2e220 'UIView-Encapsulated-Layout-Width' H:[UITableViewCellContentView:0x7fe8c2d13cb0(375)]>")
Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7fe8c2d1b3d0 '$programmaticAspectRatio$' MyProject.AsyncImageView:0x7fe8c2d16080.height == 0.75*MyProject.AsyncImageView:0x7fe8c2d16080.width>
当我向上滚动到顶部时,16:12的照片不再与左右边缘齐平,并且似乎采用了16:9照片的约束(这与我和#39一致) ; m从错误消息推断)。如果我正确地理解错误,那么单元格似乎试图将两个约束(16:9和16:12)应用于同一个单元格,尽管代码中指定了...这是什么&#39 ; s导致冲突。 tableViewController
子类包含一个&#34; post&#34;对象,每个对象都有相关图像保存的高度/宽度值,但在单元格出列后似乎没有使用数据。
所以我的问题是我该怎么做,以防止这些约束在出列后被搞砸了?此外,在出现错误消息后,以下16:12图像都没有正确显示,并且我再次收到相同的错误消息(每8个帖子大约下载额外的JSON ...类似于Instagram或Facebook,等)。
Here is a visual explanation of what's going wrong...
我至少在一周内一直在努力解决这个问题,而且我不确定我的策略中是否存在问题,或者我是否还需要其他功能在添加新单元格和旧单元格被回收时调用。如果有人有任何想法或希望看到更多我的代码,我将非常感谢您的帮助。
编辑:感谢下面评论者的帮助,我能够通过删除已有的宽高比约束来解决我的问题,然后从UITableViewController分配所需的值来创建一个新的:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let post = timelineComponent.content[indexPath.row]
let photoHeight: CGFloat = CGFloat(post.photoHeight)
let photoWidth: CGFloat = CGFloat(post.photoWidth)
cell.aspectRatio = photoHeight / photoWidth
cell.configurePostTableViewCell(post)
return cell
}
在UITableViewCell本身:
var aspectRatioLayoutConstraint: NSLayoutConstraint!
var aspectRatio: CGFloat! {
didSet {
self.postPhotoImageView.translatesAutoresizingMaskIntoConstraints = false
if self.aspectRatioLayoutConstraint != nil {
self.postPhotoImageView.removeConstraint(self.aspectRatioLayoutConstraint)
}
self.aspectRatioLayoutConstraint = NSLayoutConstraint(item: self.postPhotoImageView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: self.postPhotoImageView, attribute: NSLayoutAttribute.Width, multiplier: aspectRatio, constant: 0)
self.postPhotoImageView.addConstraint(aspectRatioLayoutConstraint)
self.setNeedsLayout()
}