Scale tableView cell with CGAffineTransform to cover entire screen

删除回忆录丶 提交于 2020-06-01 05:14:25

问题


I have a tableView where when a user taps on that cell, I want the cell to expand and fill the entire screen with that color. Currently, it does scale to fill the entire screen but the cells above it will also show. The colors come from an API and each cell changes color when the user taps the "Generate" button. Due to how the API's JSON file is structured, I only want 5 colors on the screen at a time.

I can't figure out why the cells above it don't move upwards or how I can move the clicked cell to the top of the screen. I've tried offsetting the coordinates of the tapped cell and changing its frame size to be the height of the tableView tappedCell.bounds.size = CGSize(width: UIScreen.main.bounds.width, height: self.paletteTableView.bounds.height) but when I click the 1st or 2nd cells from the top, the screen doesn't fill all the way to the bottom.

I've also tried animating from a UIView (called colorDetailsView here) but wasn't able to successfully get it to animate from the center of each cell that's tapped on, only from the center of the screen.

The animation happens here:

@objc func userTap(sender: UITapGestureRecognizer) {
        if sender.state == UIGestureRecognizer.State.ended {
            let tapLocation = sender.location(in: self.paletteTableView)
            if let tapIndexPath = self.tableView.indexPathForRow(at: tapLocation) {
                if let tappedCell = self.tableView.cellForRow(at: tapIndexPath) {

                    UIView.animate(withDuration: 0.5, animations: {

                        switch self.currentAnimation {
                        case 0:
                            tappedCell.transform = CGAffineTransform(scaleX: 1, y: 50)
                            //...
                        case 1:
                            tappedCell.transform = .identity
                        default: break
                        }
                    } )

                    currentAnimation += 1
                    if currentAnimation > 1 {
                        currentAnimation = 0
    } } } } }

Full code:

class PaletteController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    let tableView = UITableView()
    var colorPalette = [Color]()
    var currentAnimation = 0

    let colorDetailsView: UIView = {
        let view = UIView()
        return view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        tableView.delegate = self
        tableView.isScrollEnabled = false
        \\...
        view.addSubview(colorDetailsView)
    }

    //Color cell expands to fill the screen of that color when user taps on the cell
    @objc func userTap(sender: UITapGestureRecognizer) {
        if sender.state == UIGestureRecognizer.State.ended {
            let tapLocation = sender.location(in: self.tableView)

            if let tapIndexPath = self.tableView.indexPathForRow(at: tapLocation) {
                if let tappedCell = self.tableView.cellForRow(at: tapIndexPath) {
                    UIView.animate(withDuration: 0.5, animations: {

                        //When user taps on a cell, it is scaled to fill the screen with that color
                        switch self.currentAnimation {
                        case 0:
                            tappedCell.transform = CGAffineTransform(scaleX: 1, y: 50)

                            for i in 0..<self.colorPalette.count {
                                    if tapIndexPath.row == i {
                                        self.colorDetailsView.backgroundColor = UIColor(hexString: self.colorPalette[i])
                                    }
                                }
                        case 1:
                            tappedCell.transform = .identity
                        default: break
                        }
                    } )

                    currentAnimation += 1
                    if currentAnimation > 1 {
                        currentAnimation = 0
                    }
                }
            }
        }
    }

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier:"ColorCell", for: indexPath)

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(userTap(sender:)))
        cell.addGestureRecognizer(tapGesture)
        cell.isUserInteractionEnabled = true

        //Assigns a new color to each row. Colors are converted from HEX to RGB
        for i in 0..<colorPalette.count {
            if tapIndexPath.row == i {
                cell.backgroundColor = UIColor(hexString: colorPalette[i])
            }
        }
        return cell
    }
}

I know the cell is scaling when I set tableView.isScrollEnabled to true, as shown below. Each cell should end up filling the whole screen and not get covered by any other cells, like the top-most cell. Ideally, I'd like the tableView to not scroll, but I'm not sure if the top cells will "move up" if scroll is disable.

Any help is appreciated!


回答1:


The cells are after all sub-views of the table view. You need to bring the tapped cell at the front of the sub-view list.

I would suggest adding

tableView.bringSubviewToFront(tappedCell)

just after the line

if let tappedCell = self.tableView.cellForRow(at: tapIndexPath) {.

See if this works!



来源:https://stackoverflow.com/questions/61847668/scale-tableview-cell-with-cgaffinetransform-to-cover-entire-screen

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!