Strange behavior of UITextView in UITableViewCell

后端 未结 2 590
一整个雨季
一整个雨季 2021-01-23 06:31

I have a cell that contains a few stackviews, bottom stackView contains a textView and a custom separator.

I want to create an option, when user tap on cell, it

2条回答
  •  無奈伤痛
    2021-01-23 06:44

    Dynamically Resize UITableViewCell upon Selection

    Playing with individual selection indexes is dangerous business. Not only are you likely to miss corner case conditions in didSelectRowAtIndexPath, it cannot possibly work for multiple selections.
    You should split the cell expansion/compression notification into 2 distinct blocks (no need to keep track of selectedIndexPath, more robust code):

    Expand

    override func tableView(_ tableView: UITableView,
                            didSelectRowAt indexPath: IndexPath) {
        self.reloadRowsAtIndexPaths(tableView,
                                    indexPath:indexPath)
    }
    

    Contract

    override func tableView(_ tableView: UITableView,
                            didDeselectRowAt indexPath: IndexPath) {
        self.reloadRowsAtIndexPaths(tableView,
                                    indexPath:indexPath)
    }
    

    Selection is destroyed by selectRowAtIndexPath

    This prevents didDeselectRowAtIndexPath from ever being invoked. A workaround is to cache the entire selection, not individual indexes, and to restore such selection after reload.

    Complete code:

    Notice when and how cacheSelectedRows is maintained. This uses a plain UITableViewCell. All it needs is a reuseIdentifier.

    class TableViewController: UITableViewController {
        var cacheSelectedRows:[IndexPath]? = nil
    
        override func viewDidLoad() {
            super.viewDidLoad()
            tableView.estimatedRowHeight = 160
            tableView.rowHeight = UITableViewAutomaticDimension
        }
    
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 8
        }
    
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
    
            if let textLabel = cell.textLabel {
                textLabel.backgroundColor = UIColor.clear
    
                textLabel.numberOfLines = 1
                if let cacheSelectedRows = cacheSelectedRows {
                    textLabel.numberOfLines = (cacheSelectedRows.contains(indexPath)) ? 0 : 1
                }
                textLabel.text = "\(1 + indexPath.row), Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
            }
            return cell
        }
    
        override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            self.reloadRowsAtIndexPaths(tableView, indexPath:indexPath)
        }
    
        override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
             self.reloadRowsAtIndexPaths(tableView, indexPath:indexPath)
        }
    
        func reloadRowsAtIndexPaths(_ tableView: UITableView, indexPath: IndexPath) {
            cacheSelectedRows = tableView.indexPathsForSelectedRows
    
            tableView.reloadRows(at: [indexPath], with: .fade)
    
            // Restore selection
            if let cacheSelectedRows = cacheSelectedRows {
                for path in cacheSelectedRows {
                    self.tableView.selectRow(at: path, animated: false, scrollPosition: .none)
                }
            }
        }
    }
    

    Demo


    ► Find this solution on GitHub and additional details on Swift Recipes.

提交回复
热议问题