Created
August 31, 2019 19:59
-
-
Save drewag/f6bc7582637aad18274ba80d47820115 to your computer and use it in GitHub Desktop.
Playground to Illustrate a Likable Table Cell
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import PlaygroundSupport | |
// ----------------------------------------------------- | |
// Model | |
// | |
// Types having to do with the storing and processing of | |
// data should be a part of the "Model" layer. | |
// ----------------------------------------------------- | |
struct Post { | |
let text: String | |
var isLiked: Bool | |
} | |
// ----------------------------------------------------- | |
// View | |
// | |
// Types having to do with displaying to the user and | |
// recieving their interactions should be a part of the | |
// "View" layer. | |
// ----------------------------------------------------- | |
class PostCell: UITableViewCell { | |
let toggleLike = UIButton() | |
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { | |
super.init(style: .subtitle, reuseIdentifier: reuseIdentifier) | |
// Set up a bare bones cell programatically | |
self.toggleLike.setTitle("👍 Like", for: .normal) | |
self.toggleLike.setTitleColor(UIColor.black, for: .normal) | |
self.toggleLike.sizeToFit() | |
// Must put toggleLike in container view because the default | |
// table view logic overwrites the alpha of the accessory view | |
let accessory = UIView(frame: self.toggleLike.bounds) | |
accessory.addSubview(self.toggleLike) | |
self.accessoryView = accessory | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
override func prepareForReuse() { | |
super.prepareForReuse() | |
// Reset attributes that may be set when the cell is used. They will | |
// be set back to the correct values in tableView(:cellForRowAt:) | |
// Reset the alpha to 1 by default | |
self.toggleLike.alpha = 1 | |
// Reset the text to being empty | |
self.textLabel?.text = "" | |
// Remove all of the actions from the toggleLike button | |
self.toggleLike.removeTarget(self.toggleLike.allTargets, action: nil, for: .allEvents) | |
} | |
} | |
// ----------------------------------------------------- | |
// Controller | |
// | |
// The "Controller" is a thin layer to communicate between | |
// the View and the Model | |
// ----------------------------------------------------- | |
class MyViewController: UITableViewController { | |
// Static data for this example | |
var posts: [Post] = (1 ... 50).map({ index in | |
return Post(text: "Post \(index)", isLiked: false) | |
}) | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
// Register that the PostCell class should be used when dequeing a cell for "PostCellIdentifier" | |
self.tableView.register(PostCell.self, forCellReuseIdentifier: "PostCellIdentifier") | |
} | |
@IBAction func toggleLike(sender: UIButton) { | |
// First, toggle the isLiked state on the model | |
self.posts[sender.tag].isLiked = !self.posts[sender.tag].isLiked | |
// Now animate the alpha change | |
UIView.animate(withDuration: 0.3) { | |
if self.posts[sender.tag].isLiked { | |
sender.alpha = 0.5 | |
} | |
else { | |
sender.alpha = 1 | |
} | |
} | |
} | |
} | |
// UITableViewControllerDataSource | |
// | |
/// It is often a good idea to separate responsbilities, even within | |
/// a single class u sing extensions | |
extension MyViewController { | |
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
return self.posts.count | |
} | |
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
// Now that we registerd PostCell as the cell for "PostCellIdentifier", we can retrieve an instance by dequeing it | |
let cell = tableView.dequeueReusableCell(withIdentifier: "PostCellIdentifier", for: indexPath) as! PostCell | |
// Get the post this cell is representing | |
let post = self.posts[indexPath.row] | |
// Configure the display | |
cell.textLabel?.text = post.text | |
if post.isLiked { | |
cell.toggleLike.alpha = 0.5 | |
} | |
else { | |
cell.toggleLike.alpha = 1 | |
} | |
// Set the tag on the toggle button so that we know which post to toggle | |
cell.toggleLike.tag = indexPath.row | |
// Set the toggleLike button to call "toggleLike" action on touch up inside | |
cell.toggleLike.addTarget(self, action: #selector(toggleLike), for: .touchUpInside) | |
return cell | |
} | |
} | |
PlaygroundPage.current.liveView = MyViewController() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment