Предположим, я пишу клон Twitter, где пользователи могут публиковать сообщения и фотографии.Я рендерим твиты в UITableView.Для твитов, в которых есть фотографии, я помещу эти фотографии в UICollectionView, назову его photoCollectionView
, и этот UICollectionView является подпредставлением ячейки.Проблема в том, что если в твите нет фотографии?Как я могу скрыть photoCollectionView
и динамически установить высоту ячейки?Я могу представить себе два варианта:
Вариант 1: Используйте раскадровку и автоматическое расположение.В любом случае, добавьте photoCollectionView
в мою историю, но сделайте его height = 0
.Однако я должен установить ограничения, потому что именно так я смогу использовать tweetTableView.rowHeight = UITableViewAutomaticDimension
.Поэтому я установил ограничение сверху, слева, справа и по высоте для photoCollectionView
.Тогда в TweetCell
классе у меня есть:
class TweetCell: UITableViewCell {
@IBOutlet weak var photoCollectionView: UICollectionView!
var photos: [UIImage]? {
didSet {
if let assets = photos {
photoCollectionView.delegate = self
photoCollectionView.frame.size.height = <Some number>
} else {
photoCollectionView.frame.size.height = 0
}
}
}
override func prepareForReuse() {
photoCollectionView.delegate = nil
photoCollectionView.frame.size.height = 0
}
}
extension TweetCell: UICollectionViewDelegate, UICollectionViewDataSource {
...
}
Вариант 2: Не добавляйте его в раскадровку:
class TweetCell: UICollectionViewCell {
private var photoCollectionView: UICollectionView?
var photos: [UIImage]? {
didSet {
if let assets = photos {
photoCollectionView = UICollectionView.init(...)
photoCollectionView.delegate = self
}
}
}
// Then pretty much the same as above
}
Потом, позже, в моем TweetTableViewController
где я отображаю все твиты, мне нужно вручную настроить высоту строки:
override func cellHeightForRowAt (indexPath: IndexPath) -> CGFloat {
let cell = tweetTableView.cellForRow(at: indexPath) as? TweetCell
if let photos = cell?.photos {
return <Some number>
}
return 20 // Suppose default height is 20, to display other info
}
Обе опции дают мне то, что я хочу, но есть ли лучший способ сделать это?Этот способ не очень эффективен:
Вариант 1 использует prepareForReuse
, согласно Руководству разработчика , я должен сбрасывать только атрибуты, которые не являютсясвязанные с контентом.
Вариант 2 добавляет UICollectionView на лету, что, если пользователь быстро прокручивает?