[英]Create dynamic collectionView inside tableview cell
I'm trying to create a horizontal collection view inside a tableviewcell, with a dynamic size uiimageview inside, which will be the mandatory view.我正在尝试在 tableviewcell 内创建一个水平集合视图,里面有一个动态大小的 uiimageview,这将是强制视图。
I created a UIView :我创建了一个 UIView :
public class CardImage: UIView {
private var imageView: UIImageView?
private var titleLabel: UILabel?
private var descriptionLabel: UILabel?
private var subtitleLabel: UILabel?
private var icon: UIImage?
private var imageURL: String?
private var screenPercentage: CGFloat = 1.0
override public func layoutSubviews() {
super.layoutSubviews()
layer.cornerRadius = 4
}
public override func awakeFromNib() {
super.awakeFromNib()
setup()
layoutSubviews()
}
public init() {
super.init(frame: .zero)
setup()
layoutSubviews()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
layoutSubviews()
}
public func fill(dto: SomeDTO) {
setupImage(icon: dto.image, imageUrl: dto.imageURL)
descriptionLabel?.text = dto.description
titleLabel?.text = dto.title
subtitleLabel?.text = dto.subtitle
screenPercentage = dto.screenPercentage
}
private func setup() {
isUserInteractionEnabled = true
translatesAutoresizingMaskIntoConstraints = false
backgroundColor = .red
titleLabel = UILabel()
titleLabel?.textColor = .white
titleLabel?.numberOfLines = 1
addSubview(titleLabel!)
descriptionLabel = UILabel()
descriptionLabel?.textColor = .white
descriptionLabel?.numberOfLines = 2
addSubview(descriptionLabel!)
subtitleLabel = UILabel()
subtitleLabel?.textColor = .white
subtitleLabel?.numberOfLines = 1
addSubview(subtitleLabel!)
imageView = UIImageView(frame: .zero)
imageView?.backgroundColor = .red
addSubview(imageView!)
setupConstraints()
}
private func setupImage(icon: UIImage?, imageUrl: String?) {
if let url = imageURL {
return
}
guard let image = icon else {
return
}
imageView?.image = image
imageView?.contentMode = .scaleAspectFit
setNeedsDisplay()
setNeedsLayout()
}
private func setupConstraints() {
imageView?.translatesAutoresizingMaskIntoConstraints = false
imageView?.topAnchor.constraint(equalTo: topAnchor).isActive = true
imageView?.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
imageView?.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
let screenSize = UIScreen.main.bounds
let computedWidth = screenSize.width * screenPercentage
imageView?.widthAnchor.constraint(equalToConstant: computedWidth).isActive = true
//the image should be 16:9
imageView?.heightAnchor.constraint(equalTo: widthAnchor, multiplier: 9.0/16.0).isActive = true
titleLabel?.translatesAutoresizingMaskIntoConstraints = false
titleLabel?.topAnchor.constraint(equalTo: imageView!.bottomAnchor, constant: 16).isActive = true
titleLabel?.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16).isActive = true
titleLabel?.heightAnchor.constraint(equalToConstant: 18).isActive = true
subtitleLabel?.translatesAutoresizingMaskIntoConstraints = false
subtitleLabel?.topAnchor.constraint(equalTo: titleLabel!.topAnchor).isActive = true
subtitleLabel?.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16).isActive = true
titleLabel?.widthAnchor.constraint(equalTo: subtitleLabel!.widthAnchor).isActive = true
titleLabel?.trailingAnchor.constraint(equalTo: subtitleLabel!.leadingAnchor, constant: 6).isActive = true
descriptionLabel?.translatesAutoresizingMaskIntoConstraints = false
descriptionLabel?.topAnchor.constraint(equalTo: titleLabel!.bottomAnchor, constant: 16).isActive = true
descriptionLabel?.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16).isActive = true
descriptionLabel?.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16).isActive = true
descriptionLabel?.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -16).isActive = true
}
}
Which will be inside a CollectionViewCell:这将在 CollectionViewCell 内:
public class CardImageCollectionViewCell: UICollectionViewCell {
private let view: CardImage = CardImage()
override public func awakeFromNib() {
super.awakeFromNib()
translatesAutoresizingMaskIntoConstraints = false
//this only pin the view to the four anchors of the uicollectionview
view.pinToBounds(of: self.contentView)
backgroundColor = .clear
AccessibilityManager.setup(self, log: true)
}
public func fill(dto: SomeDTO) {
view.fill(dto: dto)
}
}
And then the CollectionViewCell, inside a tableviewcell, which has a collectionview:然后是 CollectionViewCell,在 tableviewcell 内,它有一个 collectionview:
public class CardImageCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
@IBOutlet private weak var collectionView: UICollectionView!
private var dto: [SomeDTO] = []
public override func awakeFromNib() {
super.awakeFromNib()
setup()
}
private func setup() {
backgroundColor = .blue
collectionView.backgroundColor = .clear
collectionView.delegate = self
collectionView.dataSource = self
if let flowLayout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout {
flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
}
registerCells()
}
func fill(dto: [SomaImageCardDTO]) {
self.dto = dto
DispatchQueue.main.async {
self.collectionView.reloadData()
self.collectionView.layoutIfNeeded()
}
}
private func registerCells() {
collectionView.register(UINib(nibName: String(describing: CardImageCollectionViewCell.self), bundle: nil), forCellWithReuseIdentifier: String(describing: CardImageCollectionViewCell.self))
}
public func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dto.count
}
//this should not be setted since the sizing is automatic
// public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
// return CGSize(width: 304, height: 238)
// }
//
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: CardImageCollectionViewCell.self), for: indexPath) as! CardImageCollectionViewCell
cell.fill(dto: dto[indexPath.row])
return cell
}
}
The two problems I'm facing is, the image cannot assume any size, since the collection view doesn't have any size until it's filled with some info.我面临的两个问题是,图像不能假设任何大小,因为集合视图在填充一些信息之前没有任何大小。
And then, even if I set the image size, I cannot pass the info to the UITableViewcell size.然后,即使我设置了图像大小,也无法将信息传递给 UITableViewcell 大小。
If I understand your problem correctly, you have more than one rows in an UITableView which have horizontal UICollectionViews.如果我正确理解您的问题,那么您在 UITableView 中有不止一行具有水平 UICollectionViews。 Those collection views have cells which have dynamic size based on the images inside them.
这些集合视图具有基于其中的图像具有动态大小的单元格。
So the width of the UITableView is fixed, but the height for the row depends on the height of the UICollectionView, correct?所以 UITableView 的宽度是固定的,但是行的高度取决于 UICollectionView 的高度,对吗?
I would recommend using self-sizing cells in the UITableView.我建议在 UITableView 中使用自动调整大小的单元格。 See the reference here: https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithSelf-SizingTableViewCells.html
请参阅此处的参考: https : //developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithSelf-SizingTableViewCells.html
After that, you need to find a way to calculate the height of the UICollectionView correctly, so the UITableView cell can determine the correct height.之后需要想办法正确计算UICollectionView的高度,这样UITableView单元格才能确定正确的高度。 There are several ways to do it, for example by overriding the
intrinsicContentSize
property of the UICollectionView and returning the largest height of the images.有几种方法可以做到这一点,例如通过覆盖 UICollectionView 的
intrinsicContentSize
属性并返回图像的最大高度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.