Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Advanced TableView/CollectionView Design

Advanced TableView/CollectionView Design

This document describes a new design method of TableView which is the foundation of iOS.

1amageek

June 05, 2017
Tweet

More Decks by 1amageek

Other Decks in Technology

Transcript

  1. Things to think about Mock UI Network Model API Sort

    ActionCount Scheme Pull to reload REST Background Kingfisher SDWebImage APIKit Session Cache
  2. 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
  3. 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
  4. Without REST API 1. Use mock until API is created

    2. Parsing JSON / Model Mapping 3. AFNetworking / Alamofire / APIKit 4. Server engineer
  5. Without REST API 1. Use mock until API is created

    2. Parsing JSON / Model Mapping 3. AFNetworking / Alamofire / APIKit 4. Server engineer
  6. Reactive Cell Layout 1. Create an API for user action

    2. Parsing JSON / Model Mapping 3. Latency 4. Consistency ※ Firebase Realtime Databaseͱ͸ͳΜͳͷ͔ʁ
  7. Reactive Cell Layout 1. Create an API for user action

    2. Parsing JSON / Model Mapping 3. Latency 4. Consistency ※ Firebase Realtime Databaseͱ͸ͳΜͳͷ͔ʁ
  8. 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> = [] }
  9. 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 } }
  10. // 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) }) }) }
  11. 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) } })
  12. 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 } }) }
  13. 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 }
  14. 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