[英]How to dynamically change the height of a UITableView Cell containing a UICollectionView cell in Swift?
Currently, I have embedded a UICollectionViewCell
in a UITableViewCell
within one of the sections of my UITableView
. 目前,我已经嵌入
UICollectionViewCell
中UITableViewCell
我的部分之一内UITableView
。 I know how to dynamically change the cell's height in another section of my UITableView
because I have a UITextView
in another UITableViewCell
that dynamically changes the height of the cell based on how much text is in the UITextView
. 我知道如何在
UITableView
另一部分中动态更改单元格的高度,因为我在另一个UITableViewCell
中具有一个UITextView
,该UITextView
根据UITextView
文本量来动态更改单元格的高度。
The problem I have is in regards to the UITableViewCell
containing the UICollectionViewCell
. 我
UICollectionViewCell
的问题是关于包含UICollectionViewCell
的UITableViewCell
。 My UICollectionViewCell
has one row of 4 images that the user can add via the camera or photo library using a UIImagePickerController
. 我的
UICollectionViewCell
具有一排4张图像,用户可以使用UIImagePickerController
通过相机或照片库添加这些图像。
Currently as I have it, when the 5th picture is generated, the UITableViewCell
's height remains static, but the user can scroll horizontally in the UICollectionViewCell
like so: 目前,在生成第5张图片时,
UITableViewCell
的高度保持静态,但是用户可以像这样在UICollectionViewCell
水平滚动:
My end goal is this : 我的最终目标是 :
And my storyboard: 而我的故事板:
Pretty self-explanatory but if there is only 4 images, the UITableViewCell
remains the same as in screenshoot 1, but the cell's height will dynamically change if the UICollectionViewCell
's height changes. 不言而喻,但是如果只有4张图像,则
UITableViewCell
与屏幕快照1相同,但是如果UICollectionViewCell
的高度发生变化,则单元格的高度将动态变化。
I have set the UICollectionView
's scroll direction to be vertical only. 我已经将
UICollectionView
的滚动方向设置为仅垂直 。 Before explaining further, here's my partial code: 在进一步解释之前,这是我的部分代码:
class TestViewController: UITableViewController, UITextFieldDelegate, UITextViewDelegate, UIImagePickerControllerDelegate
{
override func viewDidLoad()
{
super.viewDidLoad()
....
tableView.estimatedRowHeight = 40.0
tableView.rowHeight = UITableViewAutomaticDimension
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
var cell: UITableViewCell = UITableViewCell()
if indexPath.section == 1
{
cell = tableView.dequeueReusableCell(withIdentifier: "TextViewCell", for: indexPath)
let textView: UITextView = UITextView()
textView.isScrollEnabled = false
textView.delegate = self
cell.contentView.addSubview(textView)
}
else if indexPath.section == 4
{
if let imagesCell = tableView.dequeueReusableCell(withIdentifier: "ImagesCell", for: indexPath) as? CustomCollectionViewCell
{
if images_ARRAY.isEmpty == false
{
imagesCell.images_ARRAY = images_ARRAY
imagesCell.awakeFromNib()
}
return imagesCell
}
}
return cell
}
....
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
if indexPath.section == 1
{
return UITableViewAutomaticDimension
}
else if indexPath.section == 4
{
//return 95.0
return UITableViewAutomaticDimension
}
return 43.0
}
....
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
if let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage
{
if let cell = tableView.cellForRow(at: IndexPath(row: 0, section: 4) ) as? CustomCollectionViewCell
{
cell.images_ARRAY.append(selectedImage)
cell.imagesCollectionView.reloadData()
}
}
picker.dismiss(animated: true, completion: nil)
}
....
func textViewDidChange(_ textView: UITextView)
{
...
// Change cell height dynamically
tableView.beginUpdates()
tableView.endUpdates()
}
}
class CustomCollectionViewCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
{
@IBOutlet var imagesCollectionView: UICollectionView!
var images_ARRAY = [UIImage]()
var images = [INSPhotoViewable]()
override func awakeFromNib()
{
super.awakeFromNib()
for image in images_ARRAY
{
images.append(INSPhoto(image: image, thumbnailImage: image) )
}
imagesCollectionView.dataSource = self
imagesCollectionView.delegate = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return images_ARRAY.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! ExampleCollectionViewCell
cell.populateWithPhoto(images[(indexPath as NSIndexPath).row]
return cell
}
....
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets
{
return UIEdgeInsetsMake(0.0, 25.0, 0.0, 25.0)
}
}
Originally, my indexPath.section == 4
, which contains the UICollectionViewCell
returned a height of 95 , but I commented that out and replaced it with returning UITableViewAutomaticDimension
. 最初,我的
indexPath.section == 4
(其中包含UICollectionViewCell
返回的高度为95 ,但我对此进行了注释,并用返回的UITableViewAutomaticDimension
替换了它。 I would assume that adjusted the height of the cell to fit the 5th image, but the cell remained a static height even though the UICollectionViewCell
' height changed, allowing me to scroll vertically within that static UITableViewCell
height. 我假设已调整单元格的高度以适合第5张图像,但是即使
UICollectionViewCell
的高度发生了变化,该单元格仍保持静态高度,从而允许我在该静态UITableViewCell
高度内垂直滚动。
I know these are some questions I found very similar to my situation, but they didnt help me resolve my particular issue: 我知道这些问题与我的情况非常相似,但它们并没有帮助我解决特定的问题:
With some of the answers and suggestions, I've added the following: 通过一些答案和建议,我添加了以下内容:
imagesCell.images_ARRAY = images_ARRAY
imagesCell.awakeFromNib()
// Added code
imagesCell.frame = tableView.bounds
tableView.setNeedsLayout()
tableView.layoutIfNeeded()
However, this did not have any effects. 但是,这没有任何效果。 Can anyone point me in the right direction on what code I need and placed where?
谁能指出我需要什么代码并将其放置在正确的方向上?
Thanks! 谢谢!
I am using these type of cells in my code, Not performing excellent performance wise(as affecting scrolling smoothness) but will let you achieve required design. 我在我的代码中使用了这些类型的单元格,不是明智地执行出色的性能(因为它会影响滚动的平滑度),但会让您实现所需的设计。
Here I am attaching some code that may will help: 在这里,我附上一些代码可能会有所帮助:
UITableView Part: UITableView部分:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: xyzTableViewCell.self), for: indexPath) as! xyzTableViewCell
cell.collectionViewHeight.constant = (numberOfCells/5) * cell.cellHeight
return cell
}
UITableViewCell Part: UITableViewCell部分:
@IBOutlet fileprivate weak var collectionView: UICollectionView!
@IBOutlet weak var collectionViewHeight: NSLayoutConstraint
And you will need to reload that particular tableViewCell and reload collectionView inside this tableViewCell so that height function of tableView will be called and height of that tableViewCell will be refreshed, and to handle focused condition of that tableViewCell(when tableViewCell is in focus), I am saying this because if it's not in focus(or say cache, there is difference between them though) then cellForRowAtIndexPath method will be called on scrolling(when this cell is going to come in focus) then tableViewCell height will already be taken care of. 并且您将需要重新加载特定的tableViewCell并在此tableViewCell中重新加载collectionView,以便调用tableView的height函数并刷新该tableViewCell的高度,并处理该tableViewCell的集中条件(当tableViewCell处于焦点时),我之所以这样说是因为,如果它不在焦点上(或者说是缓存,虽然它们之间有区别),那么在滚动时将调用cellForRowAtIndexPath方法(当此单元格将成为焦点时),那么tableViewCell的高度将已经被处理。
Hope this will help to achieve required functionality. 希望这将有助于实现所需的功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.