Skip to content

Commit

Permalink
Merge pull request #100 from traderepublic/develop
Browse files Browse the repository at this point in the history
Release 1.2.4
  • Loading branch information
richardneitzke authored Sep 5, 2022
2 parents d69e2ca + bead1b5 commit 0792664
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ import UIKit
import SectionKit

internal final class NumbersViewController: UIViewController {
private let viewModel: NumbersViewModelType
private var viewModel: NumbersViewModelType {
didSet {
// `collapsePressed` mutates the viewmodel and thus invokes this `didSet` observer.
// If the viewmodel is a class, the invalidation of the datasource needs to be performed with another solution, e.g. weak delegate.
navigationItem.rightBarButtonItem?.title = viewModel.collapseButtonTitle
collectionViewAdapter.invalidateDataSource()
}
}

private var collectionViewAdapter: CollectionViewAdapter!

Expand Down Expand Up @@ -33,15 +40,32 @@ internal final class NumbersViewController: UIViewController {
override internal func viewDidLoad() {
super.viewDidLoad()
title = viewModel.title
navigationItem.rightBarButtonItem = UIBarButtonItem(
title: viewModel.collapseButtonTitle,
style: .plain,
target: self,
action: #selector(collapsePressed)
)
collectionViewAdapter = ListCollectionViewAdapter(
collectionView: collectionView,
sections: viewModel.sections.map {
Section(
id: $0.sectionId,
model: $0,
controller: NumbersSectionController(model: $0)
)
}
dataSource: self
)
}

@objc
private func collapsePressed() {
viewModel.collapsePressed()
}
}

extension NumbersViewController: ListCollectionViewAdapterDataSource {
internal func sections(for adapter: CollectionViewAdapter) -> [Section] {
viewModel.sections.map {
Section(
id: $0.sectionId,
model: $0,
controller: NumbersSectionController(model: $0)
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,36 @@ import Foundation

internal typealias NumbersViewModelType = NumbersViewModelInputs & NumbersViewModelOutputs

internal protocol NumbersViewModelInputs { }
internal protocol NumbersViewModelInputs {
mutating func collapsePressed()
}

internal protocol NumbersViewModelOutputs {
var title: String { get }
var sections: [NumbersSectionViewModelType] { get }
var collapseButtonTitle: String { get }
}

internal struct NumbersViewModel: NumbersViewModelType {
internal let title = "Numbers"
internal let sections: [NumbersSectionViewModelType]
private let allSections: [NumbersSectionViewModelType]
private var isCollapsed = false
internal var sections: [NumbersSectionViewModelType] {
isCollapsed ? allSections.dropLast() : allSections
}
internal var collapseButtonTitle: String {
isCollapsed ? "Uncollapse" : "Collapse"
}

internal init(navigation: NumbersSectionNavigation) {
sections = [
allSections = [
NumbersSectionViewModel(numbers: Array(0...1), navigation: navigation),
NumbersSectionViewModel(numbers: Array(10...19), navigation: navigation),
NumbersSectionViewModel(numbers: Array(20...24), navigation: navigation)
]
}

internal mutating func collapsePressed() {
isCollapsed.toggle()
}
}
10 changes: 6 additions & 4 deletions SectionKit/Sources/Utility/UICollectionView+Apply.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,15 @@ extension UICollectionView {
}

for batchOperation in update.batchOperations {
if update.shouldReload(batchOperation) {
update.setData(batchOperation.data)
reloadData()
batchOperation.completion?(false)
continue
}
performBatchUpdates({
update.setData(batchOperation.data)

if update.shouldReload(batchOperation) {
return reloadData()
}

let deletes = batchOperation.deletes
if deletes.isNotEmpty {
deleteSections(IndexSet(deletes))
Expand Down
8 changes: 1 addition & 7 deletions SectionKit/Tests/Utility/UICollectionViewApplyTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -361,18 +361,13 @@ internal final class UICollectionViewApplyTests: XCTestCase {
}

internal func testUpdateWithWindowWithSingleBatchOperationWithAlwaysReload() {
let performBatchUpdatesExpectation = expectation(description: "Should invoke performBatchUpdates")
let setDataExpectation = expectation(description: "Should invoke setData")
let reloadDataExpectation = expectation(description: "Should invoke reloadData")
let completionExpectation = expectation(description: "Should invoke completion of batch operation")

let collectionView = MockCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
collectionView._performBatchUpdates = { updates, completion in
performBatchUpdatesExpectation.fulfill()
XCTAssertNotNil(updates)
updates?()
XCTAssertNotNil(completion)
completion?(true)
XCTFail("performBatchUpdates should not be called")
}
collectionView._reloadData = reloadDataExpectation.fulfill

Expand Down Expand Up @@ -403,7 +398,6 @@ internal final class UICollectionViewApplyTests: XCTestCase {

wait(
for: [
performBatchUpdatesExpectation,
setDataExpectation,
reloadDataExpectation,
completionExpectation
Expand Down

0 comments on commit 0792664

Please sign in to comment.