ios 展开和折叠 tableview 单元格

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36917030/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 08:58:31  来源:igfitidea点击:

Expand and Collapse tableview cells

iosswiftuitableview

提问by Ahmet Alsan

I'm able to expand and collapse cells but i wanna call functions (expand and collapse) inside UITableViewCell to change button title.

我可以展开和折叠单元格,但我想调用 UITableViewCell 中的函数(展开和折叠)来更改按钮标题。

Iphone 5

iphone 5

import UIKit

class MyTicketsTableViewController: UITableViewController {

    var selectedIndexPath: NSIndexPath?
    var extraHeight: CGFloat = 100

    override func viewDidLoad() {
        super.viewDidLoad()
    }

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

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! MyTicketsTableViewCell
        return cell
    }

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        if(selectedIndexPath != nil && indexPath.compare(selectedIndexPath!) == NSComparisonResult.OrderedSame) {
            return 230 + extraHeight
        }

        return 230.0
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        if(selectedIndexPath == indexPath) {
            selectedIndexPath = nil
        } else {
            selectedIndexPath = indexPath
        }

        tableView.beginUpdates()
        tableView.endUpdates()
    }
}

import UIKit

class MyTicketsTableViewCell: UITableViewCell {

    @IBOutlet weak var expandButton: ExpandButton!
    @IBOutlet weak var detailsHeightConstraint: NSLayoutConstraint!

    var defaultHeight: CGFloat!

    override func awakeFromNib() {
        super.awakeFromNib()

        defaultHeight = detailsHeightConstraint.constant

        expandButton.button.setTitle("TAP FOR DETAILS", forState: .Normal)
        detailsHeightConstraint.constant = 30
    }

    func expand() {
        UIView.animateWithDuration(0.3, delay: 0.0, options: .CurveLinear, animations: {
            self.expandButton.arrowImage.transform = CGAffineTransformMakeRotation(CGFloat(M_PI * 0.99))
            self.detailsHeightConstraint.constant = self.defaultHeight
            self.layoutIfNeeded()

            }, completion: { finished in
                self.expandButton.button.setTitle("CLOSE", forState: .Normal)
        })
    }

    func collapse() {
        UIView.animateWithDuration(0.3, delay: 0.0, options: .CurveLinear, animations: {
            self.expandButton.arrowImage.transform = CGAffineTransformMakeRotation(CGFloat(M_PI * 0.0))
            self.detailsHeightConstraint.constant = CGFloat(30.0)
            self.layoutIfNeeded()

            }, completion: { finished in
                self.expandButton.button.setTitle("TAP FOR DETAILS", forState: .Normal)
        })
    }

}

回答by Sean Lintern

If you want the cell to get physically bigger, then where you have your store IndexPath, in heightForRow:use:

如果您希望单元格在物理上变得更大,那么您所在的 storeIndexPath正在heightForRow:使用中:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    if selectedIndexPath == indexPath {
      return 230 + extraHeight
    }
    return 230.0
}

Then when you want to expand one in the didSelectRow:

然后当你想在 didSelectRow 中扩展一个时:

selectedIndexPath = indexPath
tableView.beginUpdates
tableView.endUpdates

Edit

编辑

This will make the cells animate themselves getting bigger, you dont need the extra animation blocks in the cell.

这将使单元格动画自己变得更大,您不需要单元格中的额外动画块。

Edit 2

编辑 2

 override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        if(selectedIndexPath == indexPath) {
          selectedIndexPath = nil

          if let cell = tableView.cellForRowAtIndexPath(indexPath) as? MyTicketsTableViewCell {
            cell.collapse()
          }
          if let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow:indexPath.row+1, section: indexPath.section) as? MyTicketsTableViewCell {
            cell.collapse()
          }
        } else {
          selectedIndexPath = indexPath

          if let cell = tableView.cellForRowAtIndexPath(indexPath) as? MyTicketsTableViewCell {
              cell.expand()
          }

          if let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow:indexPath.row+1, section: indexPath.section) as? MyTicketsTableViewCell {
             cell.expand()
          }
        }

        tableView.beginUpdates()
        tableView.endUpdates()
    }

回答by Alex Kosyakov

All you need is implement UITableViewDelegate this way:

您所需要的只是以UITableView这种方式实现Delegate:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

By default, estimatedHeightis CGRectZero, when you set some value for it, it enables autoresizing (the same situation with UICollectionView), you can do even also so:

默认情况下,estimatedHeightis CGRectZero,当您为其设置一些值时,它会启用自动调整大小(与 相同的情况UICollectionView),您甚至可以这样做:

tableView?.estimatedRowHeight = CGSizeMake(50.f, 50.f); 

Then you need to setup you constraints inside your cell.

然后,您需要在单元格内设置约束。

Check this post: https://www.hackingwithswift.com/read/32/2/automatically-resizing-uitableviewcells-with-dynamic-type-and-ns

检查这篇文章:https: //www.hackingwithswift.com/read/32/2/automatically-resizing-uitableviewcells-with-dynamic-type-and-ns

Hope it helps)

希望能帮助到你)

回答by Jeyamahesan

In MyTicketsTableViewControllerclass, inside cellForRowAtIndexPathdatasource method add target for the button.

MyTicketsTableViewController类中,在cellForRowAtIndexPath数据源方法中为按钮添加目标。

cell.expandButton.addTarget(self, action: "expandorcollapsed:", forControlEvents: UIControlEvents.TouchUpInside)

回答by Gasper J.

I tried to implement lots of the given examples on this and other pages with similar questions, but none worked for me since I had to perform some logic in my custom cell (eg. hide unneeded UILables in CustomCell.swift when the cell is collapsed).

我试图在这个页面和其他页面上实现许多具有类似问题的给定示例,但没有一个对我有用,因为我必须在我的自定义单元格中执行一些逻辑(例如,当单元格折叠时,在 CustomCell.swift 中隐藏不需要的 UILables) .

Here is the implementation that worked for me:

这是对我有用的实现:

  1. Create a dictionary:

    private var _expandedCells: [IndexPath:Bool] = [:]
    
  2. Implement the heightForRowAt method:

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return _expandedCells[indexPath] == nil ? 70 : _expandedCells[indexPath]! ? 150 : 70
    }
    
  3. Implement the didSelectRowAt method:

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
        _expandedCells[indexPath] = _expandedCells[indexPath] == nil ? true : !_expandedCells[indexPath]!
    
        tableView.reloadRows(at: [indexPath], with: .fade)
    }
    
  4. Adjust your customCell:

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    
        guard let cell = cell as? YourCustomTableViewCell, let isExpanded = _expandedCells[indexPath] else { return }
    
        cell.set(expanded: isExpanded)
    }
    
  1. 创建字典:

    private var _expandedCells: [IndexPath:Bool] = [:]
    
  2. 实现 heightForRowAt 方法:

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return _expandedCells[indexPath] == nil ? 70 : _expandedCells[indexPath]! ? 150 : 70
    }
    
  3. 实现 didSelectRowAt 方法:

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
        _expandedCells[indexPath] = _expandedCells[indexPath] == nil ? true : !_expandedCells[indexPath]!
    
        tableView.reloadRows(at: [indexPath], with: .fade)
    }
    
  4. 调整您的 customCell:

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    
        guard let cell = cell as? YourCustomTableViewCell, let isExpanded = _expandedCells[indexPath] else { return }
    
        cell.set(expanded: isExpanded)
    }