Skip to content
This repository has been archived by the owner on Nov 15, 2020. It is now read-only.

Commit

Permalink
#4 Fixes for assertion in TableDirector update. Use performBatchUpdat…
Browse files Browse the repository at this point in the history
…es in iOS 11+
  • Loading branch information
malcommac committed Aug 22, 2018
1 parent f11a470 commit f1b3036
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 29 deletions.
30 changes: 17 additions & 13 deletions ExampleApp/Table Example/TableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,7 @@ class TableViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()

let articleAdpt = TableAdapter<Article,TableArticleCell>()
articleAdpt.on.dequeue = { ctx in
ctx.cell?.titleLabel?.text = ctx.model.title
ctx.cell?.subtitleLabel?.text = ctx.model.text
}
articleAdpt.on.tap = { ctx in
print("Tapped on article \(ctx.model.id)")
return .deselectAnimated
}
self.tableView?.director.register(adapter: articleAdpt)



self.tableView?.director.register(adapter: ArticleAdapter())
self.tableView?.director.add(section: self.getWinnerSection())

self.tableView?.director.rowHeight = .autoLayout(estimated: 100)
Expand Down Expand Up @@ -82,6 +70,22 @@ class TableViewController: UIViewController {

}

public class ArticleAdapter: TableAdapter<Article,TableArticleCell> {

init() {
super.init()
self.on.dequeue = { ctx in
ctx.cell?.titleLabel?.text = ctx.model.title
ctx.cell?.subtitleLabel?.text = ctx.model.text
}
self.on.tap = { ctx in
print("Tapped on article \(ctx.model.id)")
return .deselectAnimated
}
}

}

public class Article: ModelProtocol, Hashable {
public var hashValue: Int {
return self.id.hashValue
Expand Down
44 changes: 28 additions & 16 deletions Sources/Flow/Table/TableDirector.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ public class TableDirector: NSObject, UITableViewDelegate, UITableViewDataSource
return
}


// Keep a reference to removed items in order to perform diff and animation
let oldSections: [TableSection] = Array.init(self.sections)
var oldItemsInSections: [String: [ModelProtocol]] = [:]
Expand All @@ -162,26 +163,37 @@ public class TableDirector: NSObject, UITableViewDelegate, UITableViewDataSource
// Execute callback and return animations to perform
let animationsToPerform = (t(self) ?? TableReloadAnimations.default())

// Execute reload for sections
let changesInSection = SectionChanges.fromTableSections(old: oldSections, new: self.sections)
changesInSection.applyChanges(toTable: self.tableView, withAnimations: animationsToPerform)

self.tableView?.beginUpdates()
self.sections.enumerated().forEach { (idx,newSection) in
if let oldSectionItems = oldItemsInSections[newSection.UUID] {
guard let oldItems = oldSectionItems as? [AnyHashable], let newItems = newSection.models as? [AnyHashable] else {
debugPrint("Malfunction: models in table must be conform to Hashable protocol in order to perform automatic diff")
return
func executeDiffAndUpdate() {
// Execute reload for sections
let changesInSection = SectionChanges.fromTableSections(old: oldSections, new: self.sections)
changesInSection.applyChanges(toTable: self.tableView, withAnimations: animationsToPerform)

self.sections.enumerated().forEach { (idx,newSection) in
if let oldSectionItems = oldItemsInSections[newSection.UUID] {
guard let oldItems = oldSectionItems as? [AnyHashable], let newItems = newSection.models as? [AnyHashable] else {
debugPrint("Malfunction: models in table must be conform to Hashable protocol in order to perform automatic diff")
return
}
// models must conform to Hashable otherwise we are not able to perform diff
let diffData = diff(old: oldItems, new: newItems)
let itemChanges = SectionItemsChanges.create(fromChanges: diffData, section: idx)
itemChanges.applyChangesToSectionItems(ofTable: self.tableView, withAnimations: animationsToPerform)
}
// models must conform to Hashable otherwise we are not able to perform diff
let diffData = diff(old: oldItems, new: newItems)
let itemChanges = SectionItemsChanges.create(fromChanges: diffData, section: idx)
itemChanges.applyChangesToSectionItems(ofTable: self.tableView, withAnimations: animationsToPerform)
}
}

self.tableView?.endUpdates()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25, execute: { onEnd?() })
if #available(iOS 11.0, *) {
self.tableView?.performBatchUpdates({
executeDiffAndUpdate()
}, completion: { end in
if end { onEnd?() }
})
} else {
self.tableView?.beginUpdates()
executeDiffAndUpdate()
self.tableView?.endUpdates()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25, execute: { onEnd?() })
}
}

/// Change the content of the table.
Expand Down

0 comments on commit f1b3036

Please sign in to comment.