TIL: Swipe Actions and Pull to Refresh

Table of Content

Swipe Actions

In my Poopmaster and RePNCalc apps, I had used table views and implemented a third party library to enable swipe actions on the cells. While there may be advanced functionality baked into this library, I found out today that swipe actions are actually built into UIKit.

Both implementations get a bit ugly, but it’s nicer to not worry about needing an extra dependency if you dont have to!

Implementation

Here’s a rough overview of how to do it using the built in method:

func tableView(_ tableView: UITableView, 
    trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath)
     -> UISwipeActionsConfiguration? {

    let firstAction = UIContextualAction(style: .normal, title: "Delete or Something") { 
        (action, // 1 
        view, // 2 
        handler // 3
        ) in
        // do stuff like deleting the data and then the row here
        print("BELETED.")
        handler(false)
    }
    firstAction.backgroundColor = .red

    //and again easier to read without all the comments
    let secondAction = UIContextualAction(style: .normal, title: "1up") { (action, view, handler) in
        //gamify your app here
        print("You scored a 1-up")
        handler(true)
    }
    secondAction.backgroundColor = UIColor(red: 0.1, green: 0.8, blue: 0.3, alpha: 1.0)

    return UISwipeActionsConfiguration(actions: [firstAction, secondAction])
}
  1. a reference to the action (firstAction in this case)
  2. source view in which action was displayed (apparently a UIButtonLabel – not sure what it is (other than obviously a button variant) or how it’s helpful)
  3. The handler block for you to execute after you have performed the action. This block has no return value and takes the following parameter:
    • actionPerformed:
      • A Boolean value indicating whether you performed the action. Specify true if you performed the action or false if you were unable to perform the action for some reason.
    • I don’t totally understand the handler. You’re supposed to pass it true if whatever your operation is was a success, or false if it failed… but it seems to behave the same either way

Here’s how it looks in the end:
swipe example

Pull to refresh

Unlike swiping a table cell, I’ve never implemented a pull to refresh function in any of my apps. Partly because it looked hard, and partly because I didn’t have any apps that needed it. I also was under the impressio. that it required a third party library, and DID once upon a time, but now it’s available as part of the default UIKit. And it’s easy to use!

Implementation

It’s actually very easy.

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    configureRefresh() //4
}

func configureRefresh() {
    tableView.refreshControl = UIRefreshControl() //1
    tableView.refreshControl?.addTarget(self, action: #selector(refreshMahDatas), for: .valueChanged) //2
}

@objc func refreshMahDatas() { //3
    // simulating a network delay
    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
        self.dataArray = self.dataArray.map { $0 + 3 }
        self.tableView.refreshControl?.endRefreshing()
        self.tableView.reloadData()
    }
}
  1. Initialize the UIRefreshControl on your tableview
  2. Add a target your custom update method
  3. Implement your custom update method
    • It’s important that you run endRefreshing() here so the animation will stop
    • you may safely omit the network delay simulation…
  4. And, be better than me and actually remember to call your configuration before you build it and wonder why it’s not working.

Here’s how it looks in the end:

Further Analysis

If you’d like a copy of the demo project, wander over here and check it out.

Leave a Reply

Your email address will not be published. Required fields are marked *