当我在 CollectionView 中向下滚动时,图片消失了
Posted
技术标签:
【中文标题】当我在 CollectionView 中向下滚动时,图片消失了【英文标题】:Pictures disappear when I scroll down in CollectionView 【发布时间】:2019-03-02 10:35:37 【问题描述】:我有一个用于显示帖子的 collectionView,我有 3 种不同的帖子类型(文本、图像和视频)。我已经向单元格添加了一个图像视图,并且我在 cellForItemAt 函数中使用 if else 代码来显示图像和视频帖子的图像视图,或者使用 heightAnchor = 0 隐藏它来显示文本帖子。
它在开始时加载正确,但是当我向下滚动并再次向上滚动时,每个帖子的图像 heightAnchor 重置为“0”。我该如何解决这个问题?
帖子加载时
当我向下滚动并再次向上滚动时
TimelinePosts CollectionViewCell
class TimelinePosts: UICollectionViewCell
let avatar: UIImageView =
let avatar = UIImageView()
avatar.contentMode = .scaleAspectFill
avatar.clipsToBounds = true
avatar.layer.cornerRadius = 24
avatar.translatesAutoresizingMaskIntoConstraints = false
return avatar
()
let name: UILabel =
let name = UILabel()
name.numberOfLines = 1
name.translatesAutoresizingMaskIntoConstraints = false
return name
()
let content: ActiveLabel =
let content = ActiveLabel()
content.numberOfLines = 0
content.font = UIFont.systemFont(ofSize: 15)
content.translatesAutoresizingMaskIntoConstraints = false
return content
()
let image: UIImageView =
let image = UIImageView()
image.contentMode = .scaleAspectFill
image.clipsToBounds = true
image.layer.cornerRadius = 12
image.translatesAutoresizingMaskIntoConstraints = false
return image
()
let time: UILabel =
let time = UILabel()
time.numberOfLines = 1
time.textColor = .gray
time.font = UIFont.systemFont(ofSize: 14)
time.textAlignment = .center
time.translatesAutoresizingMaskIntoConstraints = false
return time
()
let moreButton: UIButton =
let button = UIButton()
let image = UIImage(named: "arrow")
button.setImage(image, for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
return button
()
let favoriteButton: FaveButton =
let button = FaveButton(frame: CGRect(x:0, y:0, width: 28, height: 28), faveIconNormal: UIImage(named: "favorite"))
button.normalColor = UIColor(hexString: "#CBCBCB")
button.selectedColor = UIColor(hexString: "#FFBE00")
button.translatesAutoresizingMaskIntoConstraints = false
return button
()
let boostButton: FaveButton =
let button = FaveButton(frame: CGRect(x:0, y:0, width: 28, height: 28), faveIconNormal: UIImage(named: "boost-pressed"))
button.normalColor = UIColor(hexString: "#CBCBCB")
button.selectedColor = UIColor(hexString: "#6e00ff")
button.translatesAutoresizingMaskIntoConstraints = false
return button
()
let actions: UILabel =
let view = UILabel()
view.numberOfLines = 1
view.textAlignment = .left
view.translatesAutoresizingMaskIntoConstraints = false
return view
()
override init(frame: CGRect)
super.init(frame: frame)
addViews()
setupViews()
func addViews()
addSubview(avatar)
addSubview(moreButton)
addSubview(time)
addSubview(name)
addSubview(content)
addSubview(image)
addSubview(favoriteButton)
addSubview(boostButton)
addSubview(actions)
func setupViews()
avatar.leftAnchor.constraint(equalTo: leftAnchor, constant: 15).isActive = true
avatar.topAnchor.constraint(equalTo: topAnchor, constant: 15).isActive = true
avatar.widthAnchor.constraint(equalToConstant: 48).isActive = true
avatar.heightAnchor.constraint(equalToConstant: 48).isActive = true
moreButton.rightAnchor.constraint(equalTo: rightAnchor, constant: -18).isActive = true
moreButton.topAnchor.constraint(equalTo: topAnchor, constant: 15).isActive = true
moreButton.widthAnchor.constraint(equalToConstant: 14).isActive = true
moreButton.heightAnchor.constraint(equalToConstant: 14).isActive = true
time.leftAnchor.constraint(equalTo: leftAnchor, constant: 15).isActive = true
time.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -10).isActive = true
time.widthAnchor.constraint(equalToConstant: 48).isActive = true
time.heightAnchor.constraint(equalToConstant: 20).isActive = true
name.leftAnchor.constraint(equalTo: avatar.rightAnchor, constant: 10).isActive = true
name.rightAnchor.constraint(equalTo: moreButton.leftAnchor, constant: -14).isActive = true
name.topAnchor.constraint(equalTo: topAnchor, constant: 15).isActive = true
name.heightAnchor.constraint(equalToConstant: 20).isActive = true
content.leftAnchor.constraint(equalTo: leftAnchor, constant: 73).isActive = true
content.rightAnchor.constraint(equalTo: rightAnchor, constant: -46).isActive = true
content.topAnchor.constraint(equalTo: name.bottomAnchor, constant: 5).isActive = true
image.leftAnchor.constraint(equalTo: leftAnchor, constant: 73).isActive = true
image.rightAnchor.constraint(equalTo: rightAnchor, constant: -46).isActive = true
image.topAnchor.constraint(equalTo: content.bottomAnchor, constant: 5).isActive = true
image.heightAnchor.constraint(equalToConstant: ((UIScreen.main.bounds.width - 120) * 2) / 3).isActive = true
actions.leftAnchor.constraint(equalTo: avatar.rightAnchor, constant: 10).isActive = true
actions.rightAnchor.constraint(equalTo: moreButton.leftAnchor, constant: -14).isActive = true
actions.topAnchor.constraint(equalTo: image.bottomAnchor, constant: 10).isActive = true
actions.heightAnchor.constraint(equalToConstant: 20).isActive = true
actions.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -10).isActive = true
favoriteButton.rightAnchor.constraint(equalTo: rightAnchor, constant: -14).isActive = true
favoriteButton.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -10).isActive = true
favoriteButton.widthAnchor.constraint(equalToConstant: 20).isActive = true
favoriteButton.heightAnchor.constraint(equalToConstant: 20).isActive = true
boostButton.rightAnchor.constraint(equalTo: rightAnchor, constant: -14).isActive = true
boostButton.bottomAnchor.constraint(equalTo: favoriteButton.topAnchor, constant: -12).isActive = true
boostButton.widthAnchor.constraint(equalToConstant: 20).isActive = true
boostButton.heightAnchor.constraint(equalToConstant: 20).isActive = true
/* name.backgroundColor = .yellow
content.backgroundColor = .red
image.backgroundColor = .green */
required init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
还有cellForItemAt函数
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TimelinePosts", for: indexPath) as! TimelinePosts
if indexPath.row < id.count
cell.avatar.sd_setImage(with: URL(string: avatars[indexPath.row]))
cell.time.text = hours[indexPath.row]
cell.favoriteButton.isSelected = isLike[indexPath.row]
cell.favoriteButton.isUserInteractionEnabled = true
cell.favoriteButton.tag = indexPath.row
cell.boostButton.isSelected = isBoost[indexPath.row]
cell.boostButton.isUserInteractionEnabled = true
cell.boostButton.tag = indexPath.row
let selectedArrowTap = UITapGestureRecognizer(target: self, action: #selector(self.selectedArrow))
selectedArrowTap.numberOfTapsRequired = 1
cell.moreButton.isUserInteractionEnabled = true
cell.moreButton.tag = indexPath.row
cell.moreButton.addGestureRecognizer(selectedArrowTap)
cell.content.customize label in
label.text = content[indexPath.row]
label.hashtagColor = UIColor(hexString: "#6e00ff")
label.mentionColor = UIColor(hexString: "#6e00ff")
label.URLColor = UIColor(hexString: "#0366d6")
cell.content.handleHashtagTap hashtag in
print("Success. You just tapped the \(hashtag) hashtag")
cell.content.handleURLTap url in
let urlString = url.absoluteString
if urlString.hasPrefix("http://")
let openURL = URL(string: urlString)!
let svc = SFSafariViewController(url: openURL)
self.present(svc, animated: true, completion: nil)
else if urlString.hasPrefix("https://")
let openURL = URL(string: urlString)!
let svc = SFSafariViewController(url: openURL)
self.present(svc, animated: true, completion: nil)
else
let openURL = URL(string: "https://" + urlString)!
let svc = SFSafariViewController(url: openURL)
self.present(svc, animated: true, completion: nil)
if types[indexPath.row] == 2
cell.image.sd_setImage(with: URL(string: images[indexPath.row]))
let selectedImageTap = UITapGestureRecognizer(target: self, action: #selector(self.photoZoom))
selectedImageTap.numberOfTapsRequired = 1
cell.image.isUserInteractionEnabled = true
cell.image.tag = indexPath.row
cell.image.addGestureRecognizer(selectedImageTap)
else if types[indexPath.row] == 3
cell.image.sd_setImage(with: URL(string: "https://i.ytimg.com/vi/\(self.extractYoutubeIdFromLink(link: videos[indexPath.row])!)/mqdefault.jpg"))
let playBtn = UIImageView()
playBtn.image = UIImage(named: "youtube-play")
playBtn.tag = indexPath.row
playBtn.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.videoPlay)))
playBtn.isUserInteractionEnabled = true
playBtn.translatesAutoresizingMaskIntoConstraints = false
cell.image.isUserInteractionEnabled = true
cell.image.addSubview(playBtn)
playBtn.centerXAnchor.constraint(equalTo: cell.image.centerXAnchor).isActive = true
playBtn.centerYAnchor.constraint(equalTo: cell.image.centerYAnchor).isActive = true
playBtn.widthAnchor.constraint(equalToConstant: 74).isActive = true
playBtn.heightAnchor.constraint(equalToConstant: 52).isActive = true
else
cell.image.heightAnchor.constraint(equalToConstant: 0).isActive = true
return cell
【问题讨论】:
我建议你制作两个不同的单元格。一种用于带图像的文本,另一种用于仅文本。然后根据数据源中的数据进行双端队列。它会让你的生活更轻松,你的 cellForItem 也会变得更干净。 @GaloTorresSevilla 谢谢,我按照你说的做了,但我想也许会有最简单的方法来做到这一点。再次感谢:) 这实际上是最简单的方法。这似乎是不必要的额外编码,但实际上是值得的 :)。祝你好运! @GaloTorresSevilla,谢谢你的信息:) 【参考方案1】:你不应该修改图片高度
cell.image.heightAnchor.constraint(equalToConstant: 0).isActive = true
在你TimelinesPosts
中创建一个新变量imageHeightConstraint
,
在setupViews()
中设置这个变量
imageHeightConstraint = image.heightAnchor.constraint(equalToConstant: ((UIScreen.main.bounds.width - 120) * 2) / 3).isActive = true
然后通过这个改变高度
// don't miss this code.
imageHeightConstraint.constant = ((UIScreen.main.bounds.width - 120) * 2) / 3
if types[indexPath.row] == 2
//***************
else if types[indexPath.row] == 3
//***************
else
imageHeightConstraint.constant = 0
【讨论】:
感谢您的回答,@GaloTorresSevilla 说“您必须为每种类型创建不同的单元格,该方法是最干净和最简单的方法。”所以,我创建了新的单元格,它现在运行良好。再次感谢:)【参考方案2】:UIScrollView 是父 UICollectionView。您使用 UIScrollView 和 UIScrollViewDelegate 来设置带有 va scrollOffset 的图像:CGFloat follow .y (referent code)
extension ViewController: UIScrollViewDelegate
func scrollViewDidScroll(_ scrollView: UIScrollView)
var scrollOffset : CGFloat = scrollView.contentOffset.y
// process with scrollOffset
【讨论】:
感谢您的回答,@GaloTorresSevilla 说“您必须为每种类型创建不同的单元格,该方法是最干净和最简单的方法。”所以,我创建了新的单元格,它现在运行良好。再次感谢:)以上是关于当我在 CollectionView 中向下滚动时,图片消失了的主要内容,如果未能解决你的问题,请参考以下文章
带有插图的 UICollectionView 不会一直向下滚动
在快速滚动collectionview时,第一行数据在最后一行重复
向上向下滚动时,collectionViewCell 图像发生变化