Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add method for reloading menu #312

Merged
merged 1 commit into from
Mar 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions Parchment/Classes/PagingViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,22 @@ open class PagingViewController<T: PagingItem>:

// MARK: Public Methods

/// Reload the data for the menu items. This method will not reload
/// the view controllers.
open func reloadMenu() {
let previouslySelected = state.currentPagingItem
let items = generateItemsForIndexedDataSource()
indexedDataSource?.items = items

if let pagingItem = items.first(where: { $0 == previouslySelected }) {
resetItems(around: pagingItem)
} else if let firstItem = items.first {
resetItems(around: firstItem)
} else {
stateMachine.fire(.removeAll)
}
}

/// Reload data for all the menu items. This will keep the
/// previously selected item if it's still part of the updated data.
/// If not, it will select the first item in the list. This method
Expand All @@ -344,8 +360,10 @@ open class PagingViewController<T: PagingItem>:

if let pagingItem = items.first(where: { $0 == previouslySelected }) {
resetItems(around: pagingItem)
resetViewControllers(around: pagingItem)
} else if let firstItem = items.first {
resetItems(around: firstItem)
resetViewControllers(around: firstItem)
} else {
stateMachine.fire(.removeAll)
}
Expand All @@ -363,6 +381,7 @@ open class PagingViewController<T: PagingItem>:
open func reloadData(around pagingItem: T) {
indexedDataSource?.items = generateItemsForIndexedDataSource()
resetItems(around: pagingItem)
resetViewControllers(around: pagingItem)
}

/// Selects a given paging item. This need to be called after you
Expand Down Expand Up @@ -787,11 +806,13 @@ open class PagingViewController<T: PagingItem>:
stateMachine.fire(.reset(pagingItem: pagingItem))
collectionView.reloadData()

configureSizeCache(for: pagingItem)
}

private func resetViewControllers(around pagingItem: T) {
pageViewController.removeAllViewControllers()
selectViewController(pagingItem, direction: .none, animated: false)

configureSizeCache(for: pagingItem)

// Reloading the data triggers the didFinishScrollingFrom delegate
// to be called which in turn means the wrong item will be selected.
// For now, we just fix this by selecting the correct item manually.
Expand Down
66 changes: 66 additions & 0 deletions ParchmentTests/PagingViewControllerSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,72 @@ class PagingViewControllerSpec: QuickSpec {

describe("PagingViewController") {

describe("reloading menu") {

let dataSource = ReloadingDataSource()
var pagingViewController: PagingViewController<PagingIndexItem>!
var viewController0: UIViewController!
var viewController1: UIViewController!

beforeEach {
viewController0 = UIViewController()
viewController1 = UIViewController()

dataSource.viewControllers = [
viewController0,
viewController1
]

dataSource.items = [
PagingIndexItem(index: 0, title: "0"),
PagingIndexItem(index: 1, title: "1")
]

pagingViewController = PagingViewController()
pagingViewController.menuItemSize = .fixed(width: 100, height: 50)
pagingViewController.dataSource = dataSource

UIApplication.shared.keyWindow!.rootViewController = pagingViewController
let _ = pagingViewController.view

pagingViewController.collectionView.bounds = CGRect(x: 0, y: 0, width: 1000, height: 50)
pagingViewController.viewDidLayoutSubviews()
}

it("reload the menu items") {
let item2 = PagingIndexItem(index: 0, title: "2")
let item3 = PagingIndexItem(index: 1, title: "3")

dataSource.items = [item2, item3]
pagingViewController.reloadMenu()
pagingViewController.view.layoutIfNeeded()

let cell2 = pagingViewController.collectionView.cellForItem(
at: IndexPath(item: 0, section: 0)
) as? PagingTitleCell
let cell3 = pagingViewController.collectionView.cellForItem(
at: IndexPath(item: 1, section: 0)
) as? PagingTitleCell

expect(pagingViewController.collectionView.numberOfItems(inSection: 0)).to(equal(2))
expect(cell2?.titleLabel.text).to(equal("2"))
expect(cell3?.titleLabel.text).to(equal("3"))
}

it("does not reload the view controllers") {
let viewController2 = UIViewController()
let viewController3 = UIViewController()

dataSource.viewControllers = [viewController2, viewController3]
pagingViewController.reloadMenu()

let pageViewController = pagingViewController.pageViewController
expect(pageViewController.selectedViewController).to(be(viewController0))
expect(pageViewController.afterViewController).to(be(viewController1))
}

}

describe("reloading data") {

let dataSource = ReloadingDataSource()
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,12 @@ func reloadData()
This will keep the previously selected item if it's still part of the
updated data. If not, it will select the first item in the list. It
will also reload the view controllers displayed in the page view
controller.
controller. If you only want to reload the menu items, you can use
this method:

```Swift
func reloadMenu()
```

Calling `reloadData()` will not work when using
`PagingViewControllerInfiniteDataSource`, as we then need to know what
Expand Down