首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在持有时逐渐增大tableview单元格的大小

如何在持有时逐渐增大tableview单元格的大小
EN

Stack Overflow用户
提问于 2018-02-14 09:53:02
回答 2查看 333关注 0票数 2

我想做的事情(逐字):在指定的时间内保存一个tableview单元格。当细胞到达那个时期后,细胞高度逐渐增大。当我松开手指,细胞高度就停止增长。

我拥有的:,我有几个tableViewCells。在对单元格按下指定的时间后,使用:

代码语言:javascript
复制
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: Selector("longPress:"))
longPressRecognizer.minimumPressDuration = 1.0s
longPressRecognizer.delegate = self
self.view.addGestureRecognizer(longPressRecognizer)

我想增加细胞高度。但是,如果不知道触点在哪一行,我就无法做到这一点,所以我走到这里:

代码语言:javascript
复制
func longPress(longPressGestureRecognizer: UILongPressGestureRecognizer) {
    if longPressGestureRecognizer.state == UIGestureRecognizerState.began {
        let touchPoint = longPressGestureRecognizer.location(in: self.tableView)
        if let indexPath = tableView.indexPathForRow(at: touchPoint) {
            //let cell = tableView.cellForRow(at: indexPath)
        }
    }
}

我考虑过控制rowHeight,但这仅仅是在tableView函数中,所以我不知道如何调用它。

,我不知道该怎么做,和我不想要和.beginUpdates和.endUpdates有任何关系,因为我希望细胞生长是渐进的,最好是充满活力的。

任何帮助都是非常感谢的,因为我已经为这个具体的问题寻找了很长时间的答案。

包含rowHeight声明的代码:

代码语言:javascript
复制
     override func viewDidLoad() {
            super.viewDidLoad()

    //        let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: Selector("longPress:"))
    //        longPressRecognizer.minimumPressDuration = 1.0 // 1 second press
    //        longPressRecognizer.delegate = self
    //        self.view.addGestureRecognizer(longPressRecognizer)

            tableView.delegate = self
            tableView.dataSource = self
            tableView.allowsSelection = false

            self.tableView.reorder.delegate = self

            view.backgroundColor = UIColor(red:0.64, green:0.93, blue:0.78, alpha:1.0)
            tableView.backgroundColor = UIColor.clear

            tableView.rowHeight = 84
            tableView.rowHeight = UITableViewAutomaticDimension


            // Do any additional setup after loading the view.
        }

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

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-14 19:59:51

我不喜欢用语言来解释细节,所以我将只包含一个相对较短的代码(也可以作为要旨),它包含了解释基本知识的注释,而不是冗长的答案。我并没有真正关注架构和干净的代码,我只是专注于完成任务。以代码为例--试着在代码库中使其更好。

不管怎么说,代码应该是非常清晰和不言自明的,但我想在你深入研究它之前,先为你画一幅大图。在解决方案中,我将高度保留在CGFloat数组中(变量cellHeights),并通过更改数组中相应的高度来修改给定行的高度。该数组作为heightForRowAt实现的基础。

当长按开始时,我启动一个计时器,每0.1秒通过修改cellHeights数组中的高度并告诉tableView重新绘制自己来更新所选行的高度。这种情况一直发生,直到对给定的行达到限制,然后我简单地取消(使定时器失效)。

如果长按压在达到极限高度之前结束,我只是显式地取消计时器,这样当用户释放按压时,单元格就会停止放大。

就是这样。我建议您使用EnlargingCellsOnLongPressController 要旨 (或下面的代码,它是相同的代码),在您自己的设备上尝试它,阅读代码和注释,我相信您应该能够在自己的情况下实现它。

代码语言:javascript
复制
import UIKit

class EnlargingCellsOnLongPressController: UITableViewController {
    // this will hold the indexPath of the cell we are currently enlarging
    var enlargingIndexPath: IndexPath?
    // dummy data model
    var modelItems: [String] = []

    // we will need to keep the heights for each particular cell (since any can be resized)
    var cellHeights: [CGFloat] = []

    // some height limit, I will set it for myself to 200
    let limitHeight = CGFloat(200)

    // the enlarging itself will be done by a timer
    weak var timer: Timer?

    override func viewDidLoad() {
        super.viewDidLoad()
        // nothing special here
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        tableView.estimatedRowHeight = 100
        tableView.allowsSelection = false

        // creating some dummy data, 30 items, and for each a cell height that will start at 100
        for index in 0..<30 {
            modelItems.append("Item \(index)")
            // by default we will start with 100
            cellHeights.append(CGFloat(100))
        }

        // please, use swift 4 and the new #selector syntax
        let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPress(longPressGestureRecognizer:)))
        longPressRecognizer.minimumPressDuration = 1
        self.view.addGestureRecognizer(longPressRecognizer)
    }

    // following three methods should be clear
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return modelItems.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = modelItems[indexPath.row]
        return cell
    }

    // for height for row we will return a specific height from cellHeights array
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return cellHeights[indexPath.row]
    }

    @objc func longPress(longPressGestureRecognizer: UILongPressGestureRecognizer) {
        if longPressGestureRecognizer.state == UIGestureRecognizerState.began {
            let touchPoint = longPressGestureRecognizer.location(in: self.tableView)
            if let indexPath = tableView.indexPathForRow(at: touchPoint) {
                //when the press starts on a cell, we will keep the indexPath for the cell
                self.enlargingIndexPath = indexPath
                // and turn on enlarging
                self.startEnlarging()
            }
        } else if longPressGestureRecognizer.state == .ended {
            // when the press is ended, we can stop enlarging
            stopEnlarging()
        }
    }

    func startEnlarging() {
        // interval 0.1 second seems smooth enough (redraw seems to be animated anyway)
        timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true, block: { [weak self] (timer) in
            guard let strongSelf = self, let enlargingIndexPath = self?.enlargingIndexPath else { return }

            let oldHeight = strongSelf.cellHeights[enlargingIndexPath.row]
            // since the timer repeats every 0.1 second, this will enlarge the cell 20 points per second till limit
            // in one cycle I will enlarge the cell by two points
            let newHeight = oldHeight + 2
            if newHeight < strongSelf.limitHeight {
                // if the newHeight did not reach limit,
                // update height and redraw tableView
                strongSelf.cellHeights[enlargingIndexPath.row] = newHeight
                strongSelf.tableView.beginUpdates()
                strongSelf.tableView.setNeedsLayout()
                strongSelf.tableView.endUpdates()
            } else {
                // reached maximum size, just cancel the timer
                strongSelf.stopEnlarging()
            }
        })
    }

    func stopEnlarging() {
        // this just cancels the timer
        timer?.invalidate()
    }
}

更新

为了完整起见,我已经使用autolayout和UITableViewAutomaticDimension创建了一个UITableViewAutomaticDimension,如果您决定使用它而不是heightForRowAt的话。但原则是一样的。

票数 0
EN

Stack Overflow用户

发布于 2018-02-14 12:05:03

代码语言:javascript
复制
Declare property for height of the cell and return this property in the tableviews's delegate method heightForRowAtIndexPath method

var heightForCell = 100

func longPress(longPressGestureRecognizer: UILongPressGestureRecognizer) {
if longPressGestureRecognizer.state == UIGestureRecognizerState.began {
    let touchPoint = longPressGestureRecognizer.location(in: self.tableView)
    if let indexPath = tableView.indexPathForRow(at: touchPoint) {

          self. heightForCell = // height you want to set 
          // now reload cell again
    }
} 
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48784134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档