根据单元格增加TableView高度

17

我需要根据UITableViewCell的内容大小增加UITableView的高度。 我正在使用自定义谷歌自动完成功能。我有一个UITextField。当我在那个UITextField中输入字母时,它将调用shouldChangeCharactersIn范围委托方法。

在该方法中,我将发送动态请求到Google AutoComplete API以获取预测结果。

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    if tableView.numberOfRows(inSection: 0) > 0
    {

    let newLength = (textField.text?.characters.count)! + string.characters.count - range.length
    let enteredString = (textField.text! as NSString).replacingCharacters(in: range, with:string)

    if newLength == 0 {
        tableView.isHidden = true
    }

    if newLength > 0
    {
        address.removeAll()
        self.tableView.isHidden = false

        GetMethod("https://maps.googleapis.com/maps/api/place/autocomplete/json?input=\(enteredString)&key=MYAPIKEY", completion: { (resultDict) in

            let resultArray = resultDict.object(forKey: "predictions")! as! NSArray

            print(resultArray.count)

            for temp in resultArray

            {
                 let newtemp = temp as! NSDictionary
                 let tempAdd = newtemp.value(forKey:"description") as! String
                let placeId = newtemp.value(forKey:"place_id") as! String
                var dict = [String : AnyObject]()
                dict["address"] = tempAdd as AnyObject?
                dict["latlong"] = placeId as AnyObject?
                self.address.append(dict as AnyObject)
                 print(newtemp.value(forKey:"description"))
                 print(self.address.count)
                self.tableView.reloadData()

            }

        })
      }
    return true
}

在我动态将所有的地址存储到地址数组中之后,我需要根据这些地址的内容增加UITableView的高度。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cellIdentifier = "TableViewCell"
    var cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)
    if cell == nil
    {
    cell = UITableViewCell(style: .default, reuseIdentifier: cellIdentifier)
    }

    let addresstoDisp  = address[indexPath.row] as! NSDictionary
    let name = addresstoDisp.value(forKey: "address")
    cell?.textLabel?.numberOfLines = 0
    cell?.translatesAutoresizingMaskIntoConstraints = false

    cell?.textLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping
    cell?.textLabel?.textAlignment = NSTextAlignment.center
    cell?.textLabel?.text = name as! String

    return cell!
}

UITableViewCell的高度正在完美地增加。我还需要增加tableView的高度。


2
为什么你想要增加表视图高度?让表视图覆盖整个页面并在其中设计所有内容,它将自动滚动。 - rptwsthi
我在self.view中有谷歌地图和一个位于地图顶部的textField。如果我的tableView中只有一个单元格,那么我不想让tableView覆盖整个视图控制器。 - Vimalkumar N.M.
在viewDidLoad中使用以下代码:self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; - KAR
它在tableview的页脚中创建了一个UIView并隐藏了地图。如果我将透明颜色设置给那个视图,则地图无法点击/拖动。 - Vimalkumar N.M.
6个回答

37
将这些行添加到单元格创建后。因为在viewDidLoad()中它会返回0高度。
 var frame = tableView.frame
 frame.size.height = tableView.contentSize.height
 tableView.frame = frame

更新

//After Tableviews data source values are assigned
tableView.reloadData()
tableView.layoutIfNeeded()
tableView.heightAnchor.constraint(equalToConstant: tableView.contentSize.height).isActive = true

1
@DilipTiwari 你在使用自动布局吗? - RajeshKumar R
是的,现在我通过添加高度约束并在返回单元格之前添加以下代码解决了问题: "tableViewHeightConstraint.constant = tableView.contentSize.height" - Dilip Tiwari
2
谢谢,这对我很有帮助。但在我的情况下,我正在使用表格视图的高度约束,所以我会增加表格视图的高度约束,代码为 tblViewHeightConstraint.constant = tblView.contentSize.height。 - Arshad Shaik
@DilipTiwari 如何在Swift文件中访问tableViewHeightConstraint。我是iOS开发新手。有什么线索吗? - Gaurav Arora
1
@GauravArora 你应该使用NSLayoutConstraint类型创建tableViewHeightConstraint。 - RajeshKumar R

6
下面的代码适用于具有AutomaticDimension的UITableViewCell。
  1. 为tableViewHeight创建一个插座(outlet)。
@IBOutlet weak var tableViewHeight: NSLayoutConstraint!
var tableViewHeight: CGFloat = 0  // Dynamically calcualted height of TableView.

对于单元格的动态高度,我使用了以下代码:
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return tableView.estimatedRowHeight
}

对于 TableView 的高度,当 TableView Cells 具有动态高度时:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    print(cell.frame.size.height, self.tableViewHeight)
    self.tableViewHeight += cell.frame.size.height
    tableViewBillsHeight.constant = self.tableViewHeight
}

解释:

在创建TableView单元格后,我们获取即将显示的单元格的框架高度,并将该单元格的高度添加到主要的TableView中。


2
在你的viewDidLoad中写入以下内容:
override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    myTable.reloadData()
    myTable.layoutIfNeeded()
}

现在重写viewDidLayoutSubviews方法,以给tableview明确的高度约束:
override func viewDidLayoutSubviews() {
    myTable.heightAnchor.constraint(equalToConstant:
    myTable.contentSize.height).isActive = true
}

这将确保表格视图被加载,并完成任何与约束相关的布局调整。


1

我一直在努力解决的问题是,当表格视图单元加载时必须增加高度,同时表格视图不应该可滚动,因为它应该显示所有单元(滚动由滚动视图处理)。无论如何,您应该使用KeyValueObserver。首先,创建高度约束的outlet:

 @IBOutlet weak var tableViewHeightConstraint: NSLayoutConstraint!

然后您为表格视图添加观察。
 private var tableViewKVO: NSKeyValueObservation?

在此之后,只需将表视图添加到观察中,并随着您的内容大小的变化更改高度约束大小。
 self.tableViewKVO = tableView.observe(\.contentSize, changeHandler: { [weak self] (tableView, _) in
        self?.tableViewHeightConstraint.constant = tableView.contentSize.height
    })

1

不设置和重置高度约束,您可以根据其内容调整表视图的大小,如下所示:

class DynamicHeightTableView: UITableView {
  override open var intrinsicContentSize: CGSize {
    return contentSize
  }
}

它能与使用AutomaticDimension的UITableViewCell一起工作吗?我尝试了但没有成功。 - SThakur

0

这是对我有效的解决方案,非常简单明了:

创建一个新的TableView高度约束的UIElement,并将其连接到视图上。

@IBOutlet weak var tableViewHeightConst: NSLayoutConstraint!

然后在你创建单元格的任何地方添加以下内容,我的情况下我正在使用RxSwift

 if self.tableView.numberOfRows(inSection: 0) > 0 {
            //gets total number of rows
            let rows = self.tableView.numberOfRows(inSection: 0)
            //Get cell desired height
            var cellHeight = 60
            self.tableViewHeightConst.constant = CGFloat(rows * cellHeight)
        }

这应该能解决问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接