问题描述
我有一个UICollectionView,它可以自动调整单元格的高度,因此它会根据单元格中的文本大小适当地调整高度。
我可以很好地单击所有按钮、向上或向下滚动等,但问题是,当我调用reloadData()时,由于某种原因,集合ViewCell的约束被搞砸了,它们堆叠在一起。
这里是调用reloadData()
之前的集合视图的图片:
这里是我调用reloadData()
后的集合VIew的图片:
有人可能知道为什么会发生这种情况以及我如何修复它吗?
以下是我的CustomCollectionView代码:
class CustomCollectionView: UICollectionView {
public let bottomRefresh = CollectionViewBottomRefresh()
init() {
let layout = UICollectionViewFlowLayout()
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
layout.scrollDirection = .vertical
layout.estimatedItemSize = CGSize(width: UIScreen.main.bounds.width, height: 50)
super.init(frame: .zero, collectionViewLayout: layout)
alwaysBounceVertical = true
backgroundColor = .systemBackground
delaysContentTouches = false
showsVerticalScrollIndicator = false
register(PostView.self, forCellWithReuseIdentifier: "post")
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesShouldCancel(in view: UIView) -> Bool {
if view is UIButton || view is UITextField {
return true
}
return super.touchesShouldCancel(in: view)
}
}
以下是我的CollectionViewCell代码:
class PostView: UICollectionViewCell, {
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(commentsButton)
contentView.addSubview(kuduAppTeamDeleteButton)
contentView.addSubview(titleLabel)
contentView.addSubview(infoButton)
contentView.addSubview(imageViewButton)
contentView.addSubview(likeButton)
contentView.addSubview(followButton)
contentView.addSubview(profile)
contentView.addSubview(likeCount)
contentView.addSubview(date)
contentView.addSubview(line)
addConstraints()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func setupView(post: Post) {
guard let post = fb.posts.firstIndex(where: { p in p.id == post.id }) else { return }
self.post = post
guard let user = fb.users.firstIndex(where: { user in user.id == fb.posts[post].uid }) else { return }
self.user = user
if fb.currentUser.likes.contains(fb.posts[post].id) {
self.likeButton.setImage(UIImage(systemName: "hand.thumbsup.fill"), for: .normal)
self.likeButton.tintColor = UIColor.theme.blueColor
} else {
self.likeButton.setImage(UIImage(systemName: "hand.thumbsup"), for: .normal)
self.likeButton.tintColor = .label
}
let result = String(format: "%ld %@", locale: Locale.current, fb.posts[post].likeCount, "")
likeCount.text = result
//Button Actions
infoButton.addAction(infoButtonAction, for: .touchUpInside)
likeButton.addAction(likeButtonAction, for: .touchUpInside)
followButton.addAction(followButtonAction, for: .touchUpInside)
imageViewButton.addAction(imageViewButtonAction, for: .touchUpInside)
profile.addAction(profileAction, for: .touchUpInside)
commentsButton.addAction(commentsButtonAction, for: .touchUpInside)
kuduAppTeamDeleteButton.addAction(kuduAppTeamDeleteButtonAction, for: .touchUpInside)
//Date
let dateFormatter = DateFormatter()
dateFormatter.timeStyle = .none
dateFormatter.dateStyle = .long
let dateString = dateFormatter.string(from: fb.posts[post].date)
date.text = dateString
//Set follow button text
if self.fb.currentUser.following.contains(fb.users[user].id) {
self.followButton.label.text = "Unfollow"
} else {
self.followButton.label.text = "Follow"
}
//Set imageview image
imageViewButton.setImage(fb.posts[post].image, for: .normal)
imageViewButton.imageView!.contentMode = .scaleAspectFill
//Set user image
profile.usernameLabel.text = fb.users[user].username
profile.profileImage.image = fb.users[user].profileImage
if profile.profileImage.image == UIImage(systemName: "person.circle.fill") {
profile.profileImage.tintColor = UIColor.theme.accentColor
}
//Set post title
titleLabel.text = fb.posts[post].title
}
override func prepareForReuse() {
//Remove all actions
infoButton.removeAction(infoButtonAction, for: .touchUpInside)
likeButton.removeAction(likeButtonAction, for: .touchUpInside)
imageViewButton.removeAction(imageViewButtonAction, for: .touchUpInside)
profile.removeAction(profileAction, for: .touchUpInside)
commentsButton.removeAction(commentsButtonAction, for: .touchUpInside)
followButton.removeAction(followButtonAction, for: .touchUpInside)
kuduAppTeamDeleteButton.removeAction(kuduAppTeamDeleteButtonAction, for: .touchUpInside)
//Remove any other text or images
for subview in imageViewButton.subviews {
if let subview = subview as? UIImageView, subview.image == UIImage(systemName: "play.circle.fill") {
subview.removeFromSuperview()
}
}
imageViewButton.setImage(nil, for: .normal)
kuduAppTeamDeleteButton.color = nil
profile.profileImage.image = nil
titleLabel.text = nil
date.text = nil
self.followButton.label.text = nil
}
// Sets a requried width and a dynamic height that changes depending on what is in the cell. So we can have searchbar as first cell heigh 50, and post in other cells with height of view.bounds.width.
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
let targetSize = CGSize(width: layoutAttributes.frame.width, height: 0)
layoutAttributes.frame.size = contentView.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel)
return layoutAttributes
}
private func addConstraints() {
kuduAppTeamDeleteButton.height(30)
kuduAppTeamDeleteButton.width(UIScreen.main.bounds.width / 4)
kuduAppTeamDeleteButton.bottom(to: commentsButton)
kuduAppTeamDeleteButton.leftToRight(of: commentsButton, offset: 5)
imageViewButton.width(UIScreen.main.bounds.width)
imageViewButton.height(UIScreen.main.bounds.width * 9/16)
imageViewButton.topToSuperview()
infoButton.leftToRight(of: titleLabel, offset: 6)
infoButton.topToBottom(of: imageViewButton, offset: 15)
infoButton.width(30)
infoButton.height(30)
titleLabel.horizontalToSuperview(insets: UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 40))
titleLabel.topToBottom(of: imageViewButton, offset: 5)
titleLabel.height(min: 50)
likeButton.topToBottom(of: titleLabel, offset: 10)
likeButton.trailingToSuperview(offset: 10)
likeButton.height(32)
likeButton.width(32)
profile.leadingToSuperview(offset: 5)
profile.topToBottom(of: titleLabel, offset: 10)
profile.widthToSuperview(multiplier: 0.4)
likeCount.trailingToLeading(of: likeButton, offset: -5)
likeCount.topToBottom(of: titleLabel, offset: 15)
followButton.topToBottom(of: titleLabel, offset: 5)
followButton.trailingToLeading(of: likeCount, offset: -10)
followButton.height(50)
followButton.width(UIScreen.main.bounds.width / 4)
date.bottom(to: commentsButton, offset: -5)
date.trailingToSuperview(offset: 5)
commentsButton.topToBottom(of: profile, offset: 10)
commentsButton.leadingToSuperview(offset: 5)
line.horizontalToSuperview()
line.bottom(to: commentsButton)
line.height(1)
contentView.bottom(to: line)
contentView.widthToSuperview()
}
}
提前谢谢!
推荐答案
终于想好了,如果其他人遇到此问题,您可以如何修复此问题。
所以我决定使用UITableView而不是UICollectionView。当您更改为UITableView时,您可以访问变量UITableView.automaticDimension
。
附注:如果您有一列,则只能使用UITableView。
我对我的UITableView执行了以下操作:
class MyTableView: UITableView {
public let bottomRefresh = TableViewBottomRefresh()
init() {
super.init(frame: .zero, style: .plain)
rowHeight = UITableView.automaticDimension
estimatedRowHeight = 500
separatorStyle = .none
allowsSelection = false
delaysContentTouches = false
alwaysBounceVertical = true
showsVerticalScrollIndicator = false
register(MyTableViewCell.self, forCellReuseIdentifier: "MyCell")
}
}
然后您需要创建一个tainerView,稍后可以将所有单元格内容放入其中:
private let containerView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
添加contentView.addsubview(containerView)
并将所有单元格内容放入容器视图中,以便单元格可以自动调整自身大小:
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(containerView)
containerView.addSubview(profileImage)
containerView.addSubview(username)
containerView.addSubview(editProfileButton)
addConstraints()
}
addconstraints()
函数:
private func addConstraints() {
profileImage.topToSuperview()
profileImage.centerXToSuperview()
profileImage.widthToSuperview(multiplier: 1/2)
profileImage.height(UIScreen.main.bounds.width / 2)
username.topToBottom(of: profileImage, offset: 10)
username.horizontalToSuperview()
username.height(50)
editProfileButton.height(50)
editProfileButton.widthToSuperview(multiplier: 1/3)
editProfileButton.centerXToSuperview()
editProfileButton.topToBottom(of: username, offset: 10)
containerView.widthToSuperview()
containerView.bottom(to: editProfileButton)
}
希望这对某个人有帮助!如果有人知道如何在不破坏单元格约束的情况下使用动态集合调用reloadData()
ViewCell Height,请让我知道!我试了两个星期,仍然没有找到解决方案:(.
这篇关于自调整大小动态UICollectionViewCell Height在调用reloadData()后不正确地调整自身大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!