iOS 在 UITableViewCell 中以编程方式设置 UIImageView 约束在滚动 tableview 时变得混乱
Posted
技术标签:
【中文标题】iOS 在 UITableViewCell 中以编程方式设置 UIImageView 约束在滚动 tableview 时变得混乱【英文标题】:iOS setting UIImageView constraints programmatically in UITableViewCell gets messed up while scrolling the tableview 【发布时间】:2017-11-28 12:23:08 【问题描述】:我以编程方式在UITableViewCell
内更改UIImageView
的高度。因此,当有图片网址时,高度为100.0
,当图片网址为零时,高度为0.0
.
这是我在tableViewCell
课程中使用的代码:
func setConstraints(_height:CGFloat)
self.commentImage.addConstraint(NSLayoutConstraint(item: self.commentImage,attribute: .height,relatedBy: .equal,toItem: self.commentImage,attribute: .width,multiplier: _height / 287.0,constant: 0))
self.commentImage.updateConstraints()
self.commentImage.layoutIfNeeded()
if let img = comment.image
let imgUrl = URL(string: img)
self.commentImage.sd_setImage(with: imgUrl, placeholderImage: UIImage(named: "PlaceHolder Shop"))
setConstraints(_height: 100.0)
else
self.commentImage.image = nil
setConstraints(_height: 0.0)
现在的问题是,当我滚动 tableview 时,一些没有图像 url 的行,得到 UIImageView
的高度为 100.0
,这留下了一个空白区域,如果我滚动 tableView 非常快,有时行中的图像消失了。
我应该怎么做才能解决这个问题?我在这里缺少什么?
【问题讨论】:
在单元格中添加堆栈视图并将图像视图添加为子视图。根据 url 隐藏和显示图像视图。它会自动调整约束。 这很好。谢谢伙计。 【参考方案1】:带有堆栈视图的CustomTableViewCell
class CustomTableViewCell: UITableViewCell
let titleLbl = UILabel()
let stackView = UIStackView()
let imgView = UIImageView()
override func awakeFromNib()
super.awakeFromNib()
override func setSelected(_ selected: Bool, animated: Bool)
super.setSelected(selected, animated: animated)
override init(style: UITableViewCellStyle, reuseIdentifier: String?)
super.init(style: style, reuseIdentifier: reuseIdentifier)
titleLbl.translatesAutoresizingMaskIntoConstraints = false
addSubview(titleLbl)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 0
stackView.alignment = .fill
stackView.distribution = .fill
addSubview(stackView)
imgView.translatesAutoresizingMaskIntoConstraints = false
let imgViewHeight = imgView.heightAnchor.constraint(equalToConstant: 100)
imgViewHeight.priority = .defaultLow
imgViewHeight.isActive = true
imgView.addConstraint(imgViewHeight)
stackView.addArrangedSubview(imgView)
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[titleLbl]|", options: [], metrics: nil, views: ["titleLbl":titleLbl,"stackView":stackView]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[titleLbl(30)][stackView]|", options: [.alignAllLeading,.alignAllTrailing], metrics: nil, views: ["titleLbl":titleLbl,"stackView":stackView]))
required init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
带有自动高度tableView的ViewController
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
@IBOutlet var tableView: UITableView!
override func viewDidLoad()
super.viewDidLoad()
tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "CustomCell")
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 130
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return 15
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell") as! CustomTableViewCell
cell.titleLbl.text = "Row \(indexPath.row)"
// set cell.imgView.image
cell.imgView.isHidden = cell.imageView?.image == nil
return cell
【讨论】:
【参考方案2】:UITableViewCells 被回收。您的 setConstraints
方法实际上并未设置约束;它再次添加一个新的约束。要正确执行此操作,您只需在 Interface builder 中设置约束即可。在尺寸检查器中找到高度约束并双击它以在文档大纲中选择它。选项从约束拖动到您的 tableViewCell 以创建一个名为 heightConstraint 的 IBOutlet。更改代码如下:
func setConstraints(_height:CGFloat)
heightConstraint.constant = height
commentImage.setNeedsLayout()
【讨论】:
以上是关于iOS 在 UITableViewCell 中以编程方式设置 UIImageView 约束在滚动 tableview 时变得混乱的主要内容,如果未能解决你的问题,请参考以下文章
如何在标准 UITableViewCell 中以编程方式自动布局右侧的自定义 UIButton。
我在自定义 UITableViewCell 中以编程方式设置布局约束时遇到问题
以编程方式为 UITableViewCell 设置 LayoutMargins - iOS 7 替代方案
在 Swift 中以编程方式突出显示 UITableViewCell