【问题标题】:Dynamically heights for when having multiple UITableViewCells based on the content of the each cell基于每个单元格的内容具有多个 UITableViewCells 时的动态高度
【发布时间】:2017-09-23 16:37:25
【问题描述】:

我是 Swift 新手,正在 Swift 3.0 中开发一个项目,其中我有一个带有三个自定义单元格的 UITableView。在第一个中,我只有一个图像、按钮和一个标签。在第二个中,我有一个图像和一个标签以及可扩展和可折叠的标题。因此,我为第二个单元格设置了三个不同的部分。最后第三个也只包含一个标签。在第一个单元格中,UILabel 设置在图像下方,其中包含关于人的描述(已设置约束)。我的要求只是对第一个单元格根据描述的大小动态调整单元格大小。不胜感激,代码如下。

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    print("Number of Sections: \(section)")
    return arrayForTableView[section]
}

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    let headerView : UITableViewHeaderFooterView = view as! UITableViewHeaderFooterView
    headerView.contentView.backgroundColor = UIColor.yellow.withAlphaComponent(1.0)
}

func tapped(sender: UITapGestureRecognizer)
{
    if let tag = sender.view?.tag{
        expanedSections[tag] = !expanedSections[tag]
    }
    tableView.reloadData()
}

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    let headerView = UITableViewHeaderFooterView()
    headerView.tag = section

    let tapRecog = UITapGestureRecognizer(target: self, action: #selector(tapped))

    tapRecog.numberOfTapsRequired = 1
    tapRecog.numberOfTouchesRequired = 1
    tapRecog.delegate = self
    headerView.addGestureRecognizer(tapRecog)
    return headerView
}

func numberOfSections(in tableView: UITableView) -> Int {
    return arrayForTableView.count
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    switch section {
    case 0:
        return 1
    case 1:
        return expanedSections[section] ? getItemsForSection(self.tableData.freeGifts): 0
    case 2:
        return expanedSections[section] ? getItemsForSection(self.tableData.exclusiveOffers) : 0
    case 3:
        return expanedSections[section] ? getItemsForSection(self.tableData.allAudios) : 0
    case 4:
        return expanedSections[section] ? getItemsForSection(self.tableData.testamonials) : 0
    default:
        return  0
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   // var cell: UITableViewCell?

    print("Section : \(indexPath.section) : \(indexPath.row)")

    switch indexPath.section {
    case 0:
      let cell =  tableView.dequeueReusableCell(withIdentifier: "HealerDetailsCell", for: indexPath) as! HealerDetailsTableViewCell

      //cell.aboutLabel.preferredMaxLayoutWidth = (tableView.bounds)
          cell.aboutLabel.sizeToFit()
        populateHealerDetails.populateTable(cell, self.tableData.healerDetails)
        return cell
    case 1:

        if tableData.freeGifts.count > 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "OffersCell",for: indexPath)
        PopulateHealerDetailsAndOffers.populateTable(cell, self.tableData.freeGifts[indexPath.row] as! NSDictionary)
            return cell
        } else {
        let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
        cell.textLabel?.text = "No Free Gifts At This Time"
            return cell
        }
    case 2:

        if tableData.exclusiveOffers.count > 0 {
         let cell = tableView.dequeueReusableCell(withIdentifier: "OffersCell",for: indexPath)
        PopulateHealerDetailsAndOffers.populateTable(cell, self.tableData.exclusiveOffers[indexPath.row] as! NSDictionary)
            return cell
        }else {
        let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
         cell.textLabel?.text = "No Exclusive Offers At This Time"
            return cell
        }
    case 3:

        if tableData.allAudios.count > 0{
        let cell = tableView.dequeueReusableCell(withIdentifier: "OffersCell",for: indexPath)
        PopulateHealerDetailsAndOffers.populateTable(cell, self.tableData.allAudios[indexPath.row] as! NSDictionary)
            return cell
        }else{
            let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
            cell.textLabel?.text = "NO Audios To Display"
            return cell
        }
    case 4:

       if tableData.testamonials.count > 0 {
          let  cell = tableView.dequeueReusableCell(withIdentifier: "TestamonialsCell", for: indexPath)
          return cell
       }else{
        let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
        cell.textLabel?.text = "No Testamonials"
        return cell
        }
    default:
         let  cell = tableView.dequeueReusableCell(withIdentifier: "TestamonialsCell", for: indexPath)
          return cell
    }

}


func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    //let indexPath = tableView.indexPathForSelectedRow!
    //let currentCellValue = tableView.cellForRow(at: indexPath)! as UITableViewCell
}

【问题讨论】:

  • 你在使用自动布局约束吗?
  • 是的,我正在使用自动布局约束,有没有办法以编程方式完成这项工作。因为我在我的代码中使用了“UITableViewAutomaticDimension”
  • @danu 只需像 self.YOURTABLENAME.reloadSections(NSIndexSet(index: index.section), withRowAnimation: UITableViewRowAnimation.Automatic) 一样重新加载您的表格
  • 你设置了 self.tableView.estimatedRowHeight 吗?

标签: ios swift uitableview


【解决方案1】:

1.设置标签的约束。

2.Put numberOflines 等于 0(通过情节提要或编程方式)

  1. 将此代码添加到viewDidLoad:

    tableView.estimatedRowHeight = 300
    tableView.rowHeight = UITableViewAutomaticDimension
    

【讨论】:

  • 我这样做了,但仍然没有结果
【解决方案2】:

使用这个委托方法

   func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }

【讨论】:

  • 已经绑定了这个但没有帮助,因为我有三个自定义单元格
  • 在 viewDidLoad 方法中添加这一行 1. self.tableView.rowHeight = UITableViewAutomaticDimension 2. self.tableView.estimatedRowHeight = 44.0
  • 如果您使用标签,请检查您的约束,使行数为零并且不对标签进行高度约束,只需从顶部、底部、左侧和右侧保持标签。
【解决方案3】:

对于版本 >= iOS 8

override func viewDidLoad()
{
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 44.0; // set to whatever your "average" cell height is
}

在情节提要上设置约束的步骤:here

重要

  • 如果多行标签,不要忘记将numberOfLines设置为0。
  • 别忘了 label.preferredMaxLayoutWidth = CGRectGetWidth(tableView.bounds)

【讨论】:

  • 没有CGRectGetWidth这样的参数
  • 不要使用这一行
  • 这不会工作,因为我有三个不同的自定义单元格
【解决方案4】:

我认为您想根据每个单元格在运行时拥有的数据来扩展/跳过 UITableViewCell。我想,您已经在 swift 中实现了有关 UITableView 的所有急救选项。

请试试这个方法,当你的每个单元格被加载时,它总是会被调用。

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    //CellAnimator.animateCell(cell: cell, withTransform: CellAnimator.TransformWave, andDuration: 1)
   //This commented line possibly might not be your requirement.
  //But this is actually used to animate cell while loading.
  //You can try some constraints or cell height related stuff here which would definitely work for each cell differently.


  //Try calling cell specific loads either.
  tableView.scrollToRow(at: indexPath as IndexPath, at: .none, animated: true)

        /*let indexPath = IndexPath(item: (selectedCellIndexPath?.row)!, section: 0)
        tableView.reloadRows(at: [indexPath], with: .none)
        checkTrue = true
        */


}

请查看:

   import UIKit

   class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet weak var tableView: UITableView!
var tableViewDataSource = ["fewhf wfh wf wfw h dfw \n\n wufhw f ewfw  wf w \n\n  f wefe wfef w","fewhf wfh wf wfw h dfw \n\n wufhw f ewfw  wf w \n\n  f wefe wfef w",
"fewhf wfh wf wfw h dfw \n\n wufhw f ewfw  wf w \n\n  f wefe wfef w",
"fewhf wfh wf wfw h dfw \n\n wufhw f ewfw  wf w \n\n  f wefe wfef w"
]

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.


    tableView.delegate = self
    tableView.dataSource = self
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


//Tableview 
func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
   return tableViewDataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "CellHere") as! TableViewCellHere

    cell.cellHere.text = tableViewDataSource[indexPath.row]
    cell.cellHere.textAlignment = .justified
    return cell
}

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {


    if indexPath.row == 0 || indexPath.row == 1
    {
        return 120.0
    }
    else
    {
        return 50.0
    }


}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if indexPath.row == 0 || indexPath.row == 1
    {
        return 120.0
    }
    else
    {
        return 50.0
    }

  }

    }

这对我来说是这样的: enter image description here

【讨论】:

  • 是的,实际上我所有的代码都可以正常工作,只是内容只是部分可见。我也尝试了上面的代码,但仍然没有区别。
  • 先生,如果您阅读我的代码,您会发现第 0 部分只有一行,这是我的第一个单元格。忘记可扩展和可折叠的概念,在该单元格中,我在显示段落的图像下方设置了 UILable。现在我只看到几行。我希望这个单元格根据内容大小进行调整
猜你喜欢
  • 2012-05-04
  • 1970-01-01
  • 1970-01-01
  • 2018-09-30
  • 1970-01-01
  • 1970-01-01
  • 2021-08-18
  • 2016-08-16
  • 2020-10-21
相关资源
最近更新 更多