Share
Embed
Advanced TableView/CollectionView Design
This document describes a new design method of TableView which is the foundation of iOS.
1amageek
June 05, 2017
Transcript
28 slides
-
Advanced TableView / CollectionView Design nori Jun 2017 @1amageek Hello.
#WWDC2017 Thank you Yahoo Japan -
About 1amageek System Device Technology LSI design engineer iOS engineer
iOS engineer 2017.5 ~ 2015.10 ~ 2009.4 ~ Bio -
Things to think about Mock UI Network Model API Sort
ActionCount Scheme Pull to reload REST Background Kingfisher SDWebImage APIKit Session Cache -
Design flow UI Network Model Load and Reload Bad network
REST API Scheme Data Populate Version Migration Cache Non Blocking Frame rate Easy & Simple Latency -
Design flow UI Network Model Load and Reload Bad network
REST API Scheme Data Populate Version Migration Cache Non Blocking Frame rate Easy & Simple Latency -
Reactive Cell Layout Without REST API Realtime reload TableView Design
with AutoSync Database -
Without REST API 1. Use mock until API is created
2. Parsing JSON / Model Mapping 3. AFNetworking / Alamofire / APIKit 4. Server engineer -
Without REST API 1. Use mock until API is created
2. Parsing JSON / Model Mapping 3. AFNetworking / Alamofire / APIKit 4. Server engineer -
Reactive Cell Layout 1. Create an API for user action
2. Parsing JSON / Model Mapping 3. Latency 4. Consistency ※ Firebase Realtime DatabaseͱͳΜͳͷ͔ʁ -
Reactive Cell Layout 1. Create an API for user action
2. Parsing JSON / Model Mapping 3. Latency 4. Consistency ※ Firebase Realtime DatabaseͱͳΜͳͷ͔ʁ -
class User: Object { dynamic var name: String? dynamic var
profileImage: File? dynamic var bio: String? dynamic var feedIDs: Set<String> = [] dynamic var photoIDs: Set<String> = [] } -
class Photo: Object { dynamic var data: File? dynamic var
text: String? } -
class Feed: Object { @objc enum ContentType: Int { case
unknown case photo case movie } dynamic var userID: String? dynamic var contentType: ContentType = .unknown dynamic var contentID: String? dynamic var likeCount: Int = 0 override func encode(_ key: String, value: Any?) -> Any? { if key == "contentType" { return self.contentType.rawValue as Int } return nil } override func decode(_ key: String, value: Any?) -> Any? { if key == "contentType" { if let type: Int = value as? Int { self.contentType = ContentType(rawValue: type)! return self.contentType } } return nil } } -
// Make photo sample (0..<6).forEach { (index) in let name:
String = "\(index)" let image: UIImage = UIImage(named: name)! let data: Data = UIImageJPEGRepresentation(image, 0.7)! let file: File = File(data: data) let photo: Photo = Photo() photo.text = "This picture \(index) is very beautiful " photo.data = file photo.save({ (ref, error) in if let error = error { debugPrint(error) return } // relationship to user user.photoIDs.insert(ref!.key) // Make Feed sample let feed: Feed = Feed() feed.userID = user.key feed.contentType = .photo feed.contentID = ref!.key feed.save({ (ref, error) in if let error = error { debugPrint(error) return } // relationship to user user.feedIDs.insert(ref!.key) }) }) } -
let options: SaladaOptions = SaladaOptions() options.limit = 10 options.ascending =
false self.datasource = DataSource(parentKey: userID, referenceKey: "feedIDs", options: options, block: { [weak self](changes) in guard let tableView: UITableView = self?.tableView else { return } switch changes { case .initial: tableView.reloadData() case .update(let deletions, let insertions, let modifications): tableView.beginUpdates() tableView.insertRows(at: insertions.map { IndexPath(item: 0, section: $0) }, with: .automatic) tableView.deleteRows(at: deletions.map { IndexPath(item: 0, section: $0) }, with: .automatic) tableView.reloadRows(at: modifications.map { IndexPath(item: 0, section: $0) }, with: .automatic tableView.insertSections(IndexSet(insertions), with: .automatic) tableView.deleteSections(IndexSet(deletions), with: .automatic) tableView.reloadSections(IndexSet(modifications), with: .automatic) tableView.endUpdates() case .error(let error): print(error) } }) -
func configure(cell: TableViewCell, at indexPath: IndexPath) { self.datasource?.observeObject(at: indexPath.section, block:
{ (feed) in guard let feed: Feed = feed else { return } // Get user data User.observeSingle(feed.userID!, eventType: .value, block: { (user) in guard let user: User = user else { return } cell.titleView.titleLabel.text = user.name cell.titleView.dateLabel.text = self.dateFormatter.string(from: feed.updatedAt) if let ref: StorageReference = user.profileImage?.ref { cell.titleView.imageView.sd_setImage(with: ref, placeholderImage: nil) } }) // Switch content type switch feed.contentType { // Photo case .photo: // Get photo data Photo.observeSingle(feed.contentID!, eventType: .value, block: { (photo) in guard let photo: Photo = photo else { return } cell.detailView.detailLabel.text = photo.text cell.setNeedsLayout() if let ref: StorageReference = photo.data?.ref { cell.photoView.imageView.sd_setImage(with: ref, placeholderImage: nil) } }) // TODO: hide content default: break } }) } -
var likeCount: Int = feed.likeCount cell.actionView.likeCountLabel.text = String(likeCount) cell.actionView.actionBlock =
{ likeCount += 1 cell.actionView.likeCountLabel.text = String(likeCount) feed.likeCount = likeCount } -
Ads PXL Your photos will be born again as a
wonderful art. This photo collage is what makes you feel more happy and pleased. Let's share the pixel art to all over the world. $0.99