I have been working with UITableView for some time and the one of it’s aspect that I think should be more obvious is how to animate, delete and reload rows.

Shown below is some code that I wrote for Xcode playground. This code programmatically constructs a UIButton, UITableView, adds them to a view and styles them using auto layout constraints. Then, it randomly generates a number between 1 and 3 and shows how to either,

  1. Animate inserting a new row (UITableViewCell) into a UITableView
  2. How to delete and animate removal of a row (UITableViewCell) from a UITableView
  3. How to animate reloading a section of a UITableViewRow

The code also has the necessary comments that explains some of the things.

UITableView

You can also find the Xcode Playground project on Github.

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController, UITableViewDelegate, UITableViewDataSource {
    var data = ["One", "Two", "Three"]
    /*
     Our initial implementation needs a little more setup
     therefore we should initialise it with a closure
     look at it. We are setting a lot of things here
     */
    let roundButton:UIButton = {
        let btn = UIButton(frame: CGRect(x: 0, y: 0, width: 70, height: 50))
        //to programmatically control auto-layout
        btn.translatesAutoresizingMaskIntoConstraints = false
        btn.backgroundColor = UIColor.purple
        //round the button
        btn.layer.cornerRadius = 5.0
        btn.layer.masksToBounds = true
        return btn
    }()
    var tableView = UITableView()
    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white

        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.delegate = self
        tableView.dataSource = self

        let attr:[NSAttributedString.Key: Any] = [
            .font: UIFont.boldSystemFont(ofSize: 18),
            .foregroundColor: UIColor.white
        ]
        let attrStr = NSAttributedString(string: "Animate cells", attributes: attr)
        roundButton.setAttributedTitle(attrStr, for: .normal)
        roundButton.addTarget(self, action: #selector(animateCell), for: .touchUpInside)

        view.addSubview(roundButton)
        view.addSubview(tableView)
        self.view = view

        NSLayoutConstraint.activate([
            roundButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            roundButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 10),

            tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            tableView.topAnchor.constraint(equalTo: roundButton.bottomAnchor, constant: 15),
            tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])
    }
    /*
     When you animate cell is clicked, either
     delete a row
     add a row
     or reset and reload tableRows with
     original data
     randomly pick between 1 and 3
     */
    @objc func animateCell() {
        let rand = Int.random(in: 1...3)
        print("Rand value -> \(rand)")
        switch rand {
        case 1: //add
            let newText = "New data@\(Date().timeIntervalSince1970)"
            data.append(newText)
            //here we append a value and animate adding row
            //and the UITableView operates on a 0 index
            //i.e. the first row has index position of 1
            let indexSetArr = [IndexPath(row: (data.count - 1), section: 0)]
            tableView.insertRows(at: indexSetArr, with: .fade)
            break
        case 2: //delete
            if data.count > 1 {
                data.remove(at: 0)
                let path = IndexPath(row: 0, section: 0)
                tableView.deleteRows(at: [path], with: .left)
            } else {
                let msg = """
                            No data or rows to remove. Keep tapping
                            animate to eventually randomly add a value
                        """
                print(msg)
            }
            break
        case 3: //reset and reload everything
            data = ["One", "Two", "Three"]
            let set = IndexSet(integersIn: 0...0)
            tableView.reloadSections(set, with: .middle)
            break
        default:
            print("We shouldn't be here")
        }
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell") else {
            return UITableViewCell()
        }
        let element = data[indexPath.row]
        cell.textLabel?.text = element
        return cell
    }
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

Get updates?

As usual, if you find any of my posts useful support me by  buying or even trying one of my apps on the App Store. 

https://mydaytodo.com/apps/

Also, if you can leave a review on the App Store or Google Play Store, that would help too.

Categories: iOSSwift

0 Comments

Leave a Reply

Avatar placeholder