我有一個自定義單元格在XIB文件內部具有動態高度,該單元格顯示帶有消息和圖像的文章。由於圖像將從我的API異步加載,圖像的寬高比將與資源一起發送。在updateConstraints
方法中,將設置具有適當乘數的寬高比約束。異步加載的圖像的表格視圖單元格的動態高度
的XIB文件:
Cell類:
//
// PostTableViewCell.swift
// Lome
//
// Created by Tobias Feistmantl on 10/09/15.
// Copyright (c) 2015 Tobias Feistmantl. All rights reserved.
//
import UIKit
import Alamofire
class PostTableViewCell: UITableViewCell {
@IBOutlet weak var userProfileImageView: TFImageView!
@IBOutlet weak var usersNameLabel: UILabel!
@IBOutlet weak var usernameLabel: UILabel!
@IBOutlet weak var userProfileButton: TFCellButton!
@IBOutlet weak var distanceLabel: UILabel!
@IBOutlet weak var messageLabel: UILabel!
@IBOutlet weak var postImageView: UIImageView!
@IBOutlet weak var likeCountLabel: UILabel!
@IBOutlet weak var timestampLabel: UILabel!
@IBOutlet weak var likeButton: UIButton!
@IBOutlet weak var constraintBetweenMessageLabelAndPostImageView: NSLayoutConstraint!
var post: Post! {
didSet {
post.author.profileImage(version: .Thumbnail) { image, _ in
self.userProfileImageView.image = image
}
if let name = post.author.fullName {
usersNameLabel.text = name
usernameLabel.text = post.author.username
} else {
usersNameLabel.text = post.author.username
usernameLabel.hidden = true
}
if let attributedMessage = post.attributedMessage {
messageLabel.attributedText = attributedMessage
messageLabel.hidden = false
constraintBetweenMessageLabelAndPostImageView.constant = 15
} else {
messageLabel.hidden = true
messageLabel.attributedText = nil
constraintBetweenMessageLabelAndPostImageView.constant = 0
}
post.image { image, _ in
if let image = image {
self.postImageView.image = image
self.setNeedsUpdateConstraints()
}
}
timestampLabel.text = "Posted \(post.createdAt.timeAgoSinceNow())"
distanceLabel.text = post.distanceText
likeCountLabel.text = "\(post.likesCount) Likes"
likeButton.setImage(post.likeButtonImage, forState: .Normal)
}
}
override func updateConstraints() {
if let aspectRatio = post.imageAspectRatio {
postImageAspectConstraint = NSLayoutConstraint(item: postImageView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: postImageView, attribute: NSLayoutAttribute.Height, multiplier: CGFloat(aspectRatio), constant: 0)
}
super.updateConstraints()
}
func setupUserProfileButton(indexPath: NSIndexPath, viewController: UIViewController) {
userProfileButton.indexPath = indexPath
userProfileButton.addTarget(viewController, action: "userProfileButtonDidTouch:", forControlEvents: .TouchUpInside)
}
var postImageAspectConstraint: NSLayoutConstraint? {
didSet {
if let oldValue = oldValue {
postImageView.removeConstraint(oldValue)
}
if let postImageAspectConstraint = postImageAspectConstraint {
postImageView.addConstraint(postImageAspectConstraint)
}
}
}
override func prepareForReuse() {
super.prepareForReuse()
postImageAspectConstraint = nil
}
}
的cellForRowAtIndexPath
方法:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("postCell", forIndexPath: indexPath) as! PostTableViewCell
cell.post = posts[indexPath.row]
cell.setupUserProfileButton(indexPath, viewController: self)
return cell
}
在應用程序啓動按預期工作的一切,但如果我有一點冷靜,這個限制開始打破了在圖像方面都不對了或像下面的一些其他奇怪的事情:
錯誤:
2015-09-28 11:58:27.546 Lome[32812:528936] 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. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x7f8a008bf6f0 V:[Lome.TFImageView:0x7f8a008bf470(35)]>",
"<NSLayoutConstraint:0x7f89f9fbc490 V:|-(15)-[Lome.TFCellButton:0x7f8a0087fde0] (Names: '|':UITableViewCellContentView:0x7f8a008bf270)>",
"<NSLayoutConstraint:0x7f8a00831520 Lome.TFCellButton:0x7f8a0087fde0.top == Lome.TFImageView:0x7f8a008bf470.top>",
"<NSLayoutConstraint:0x7f8a008315c0 Lome.TFCellButton:0x7f8a0087fde0.bottom == Lome.TFImageView:0x7f8a008bf470.bottom>",
"<NSLayoutConstraint:0x7f8a00831750 V:[Lome.TFCellButton:0x7f8a0087fde0]-(18)-[UILabel:0x7f8a008806d0'Water']>",
"<NSLayoutConstraint:0x7f8a00831840 H:|-(0)-[UIImageView:0x7f8a00830910] (Names: '|':UITableViewCellContentView:0x7f8a008bf270)>",
"<NSLayoutConstraint:0x7f8a00831890 H:[UIImageView:0x7f8a00830910]-(0)-| (Names: '|':UITableViewCellContentView:0x7f8a008bf270)>",
"<NSLayoutConstraint:0x7f8a008318e0 V:[UILabel:0x7f8a008806d0'Water']-(15)-[UIImageView:0x7f8a00830910]>",
"<NSLayoutConstraint:0x7f8a00831930 V:[UIImageView:0x7f8a00830910]-(20)-[UILabel:0x7f8a00830b90'0 Likes']>",
"<NSLayoutConstraint:0x7f8a00831980 V:[UILabel:0x7f8a00830b90'0 Likes']-(20)-| (Names: '|':UITableViewCellContentView:0x7f8a008bf270)>",
"<NSLayoutConstraint:0x7f8a00860870 UIImageView:0x7f8a00830910.width == 0.6672*UIImageView:0x7f8a00830910.height>",
"<NSLayoutConstraint:0x7f8a0084e990 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7f8a008bf270(611)]>",
"<NSLayoutConstraint:0x7f8a0084f930 'UIView-Encapsulated-Layout-Width' H:[UITableViewCellContentView:0x7f8a008bf270(375)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7f8a008bf6f0 V:[Lome.TFImageView:0x7f8a008bf470(35)]>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2015-09-28 11:58:27.547 Lome[32812:528936] 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. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x7f89f9fbc490 V:|-(15)-[Lome.TFCellButton:0x7f8a0087fde0] (Names: '|':UITableViewCellContentView:0x7f8a008bf270)>",
"<NSLayoutConstraint:0x7f8a00831520 Lome.TFCellButton:0x7f8a0087fde0.top == Lome.TFImageView:0x7f8a008bf470.top>",
"<NSLayoutConstraint:0x7f8a008315c0 Lome.TFCellButton:0x7f8a0087fde0.bottom == Lome.TFImageView:0x7f8a008bf470.bottom>",
"<NSLayoutConstraint:0x7f8a00831750 V:[Lome.TFCellButton:0x7f8a0087fde0]-(18)-[UILabel:0x7f8a008806d0'Water']>",
"<NSLayoutConstraint:0x7f8a00831840 H:|-(0)-[UIImageView:0x7f8a00830910] (Names: '|':UITableViewCellContentView:0x7f8a008bf270)>",
"<NSLayoutConstraint:0x7f8a00831890 H:[UIImageView:0x7f8a00830910]-(0)-| (Names: '|':UITableViewCellContentView:0x7f8a008bf270)>",
"<NSLayoutConstraint:0x7f8a008318e0 V:[UILabel:0x7f8a008806d0'Water']-(15)-[UIImageView:0x7f8a00830910]>",
"<NSLayoutConstraint:0x7f8a00831930 V:[UIImageView:0x7f8a00830910]-(20)-[UILabel:0x7f8a00830b90'0 Likes']>",
"<NSLayoutConstraint:0x7f8a00831980 V:[UILabel:0x7f8a00830b90'0 Likes']-(20)-| (Names: '|':UITableViewCellContentView:0x7f8a008bf270)>",
"<NSLayoutConstraint:0x7f8a00860870 UIImageView:0x7f8a00830910.width == 0.6672*UIImageView:0x7f8a00830910.height>",
"<NSLayoutConstraint:0x7f8a0084e990 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7f8a008bf270(611)]>",
"<NSLayoutConstraint:0x7f8a0084f930 'UIView-Encapsulated-Layout-Width' H:[UITableViewCellContentView:0x7f8a008bf270(375)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7f8a00860870 UIImageView:0x7f8a00830910.width == 0.6672*UIImageView:0x7f8a00830910.height>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
我認爲這是與細胞但隨着重用你可以看到約束將在prepareForReuse
方法中被刪除。
我目前很沮喪,因爲我試圖解決這個問題,因爲幾天沒有找到解決方案。
我希望有人有一個解決方案。
在此先感謝。
你可以嘗試設置圖像視圖的高度而不是'updateConstraints:'中的寬度。從第一次看,這似乎是一個模棱兩可的情況,因爲你已經用'0'間距固定'ImageView'水平佈局,然後嘗試根據高度改變寬度。 – Gandalf
這是一個縱橫比約束而非寬度約束。 UIImageView的高度是寬度的0.6672倍。然而,如果我在IB中設置了一個固定的高度,並且不添加這種縱橫比約束,它可以工作,但由於每個圖像都是不同的,所以我總是有相同的高度和錯誤的寬高比。 – Tobias
我知道你已經應用了寬高比約束。我想你誤解了我指的是什麼。在你的縱橫比約束中,「第一項」是「寬度」。這意味着約束將試圖使'寬度'的變化不是該視圖的'高度'。因此,如果您倒轉第一個和第二個項目,並在乘數參數中反轉寬高比,則您將具有相同的約束,但根據圖像寬高比具有不同的高度。 – Gandalf