- December 17, 2024
- Mins Read
As mobile developers we all have to handle displaying collections of data. But is it always as simple as it sounds?
Looks like spaghetti? It is a common situation that application displays data / placeholders (which may be different depending for example on loading state) and some of us end up with defining states and tangling everything together.
Stefan is a framework that helps you to manage states in your collection views. Basically it is a middleman between data source and the view itself. Of course it supports UITableView and UICollectionView out of box, but it is up to you to decide what is your ReloadableView and what is PlaceholderView. It contains most commonly used states that might occur when loading data collection.
Stefan
object, the best solution is to define one Stefan
per one ReloadableView
.reloadableView
and placeholderPresenter
(which both might be nil
).stefan.load(newState: ...)
Example of setup:
private func setupStefan() {
viewModel.stefan.reloadableView = self.tableView
viewModel.stefan.placeholderPresenter = self
viewModel.stefan.load(newState: .noContent) // initial state
}
For reading current items just call
try stefan.state.items()
LoadableStatePlaceholderView
and also implement ItemsLoadableStateBindable
protocol. To display custom placeholder view just implement your own version of function customPlaceholderView
that is handled by Stefan’s placeholderPresenter
.Example for customization:
public func customPlaceholderView() -> LoadableStatePlaceholderView {
let view = LoadingPlaceholderView.instanceFromNib()
view.dataSource = self.viewModel
return view
}
To make Stefan fully generic we provided delegate by common closures pattern. Following delegate closures are available:
public var shouldReload: ((ReloadableView!) -> Bool)
public var didChangeState: ((ItemsLoadableState<ItemType>) -> Void)
public var shouldDisplayPlaceholder: ((ItemsLoadableState<ItemType>) -> Bool)
Stefan provides default implementation of differring function which result should be ItemReloadingResult
. This result tells Stefan what should be reloaded (or maybe there is nothing to do for him). You can provide your own implementation by defining
stefan.statesDiffer = ...
Please remember that this is a weak object so you have to handle retaining it.
Stefan has a Differ
dependency which is needed for performing fast operations on collections while comparing. When initializing Stefan you are able to provide reloading type which might be animated
or basic
. By default animations are disabled, but when you’ll enable it Stefan will handle collection animation automatically by himself.
We’ve added some RxSwift extensions for Stefan please follow this repo.
Add the following entry in your Cartfile:
github “appunite/Stefan”
Then run carthage update
.
Add the following entry in your Podfile
pod ‘Stefan’
Then run pod install
.
A vertical stackview which takes subviews with different widths and adds them to it's rows with paddings, spacings etc.
AudioManager is a Swift package that provides a modular and easy-to-use interface for implementing audio feedback in your applications. It ...