在设计应用时,您常常需要根据状态展示不同的视图。使用UIViewController包含是重用视图代码和storyboards的好方法,但管理它们的插入和删除,以及正确执行过渡和内存管理可能变得繁琐。这正是MultiplexerController可以提供帮助的地方,它通过创建一个容器来展示其内容作为状态的函数。
- 它调用
addChild
、removeChild
和所有需要的回调 - 处理视图的插入和删除
- 如果您想要,可以展示一个美丽的淡入效果
- 根据需要处理内存管理
- 体积小,小于200行,因此您可以帮助检查它做什么
要求
- iOS 10.0+
- Swift 4.2+
安装
CocoaPods
要使用CocoaPods将MultiplexerController集成到您的Xcode项目中,请在您的Podfile
中指定它
pod 'MultiplexerController', '~> 1.0.0'
Carthage
要使用Carthage将MultiplexerController集成到Xcode项目中,请在使用Cartfile
github "mobiten/MultiplexerController" "1.0.0"
用法
此库的常见用法是展示加载界面和错误状态。以下示例中将使用此枚举:
enum State {
case loading
case loaded(WeatherForecast)
case error(Error)
}
首先,创建一个带有初始状态的MultiplexerController。然后,向它提供一个数据源,它可以是自我或任何实现MultiplexerControllerDataSource协议的类。
let multiplexer = MultiplexerController(initialState: State.loading)
multiplexer.setDataSource(self)
其次,在您的数据源中实现该协议。
extension HomeController: MultiplexerControllerDataSource {
func controller(for controller: MultiplexerController<State>, inState state: State) -> UIViewController {
switch state {
case .loading:
return LoadingController()
case .error(let error):
return ErrorController(error)
case .loaded(let forecast):
return WeatherForecastController(forecast)
}
}
}
第三,在需要时更改状态!
func didFetch(forecast: WeatherForecast) {
multiplexer.set(.loaded(forecast), animated: true)
}
常见问题解答
为什么我不能从MultiplexerController派生子类?
尽可能的情况下,您应该始终更喜欢组合(composite)而不是继承(inheritance)。如果您想使用MultiplexerController,可以在另一个容器中嵌入它或直接将其推送到您的导航堆栈中。
为什么数据源协议强制我使用与初始状态相同的类型?
通过强制您使用相同的类型(枚举推荐使用),您始终可以知道可以期望什么。作为一个副作用,如果您使用详尽的switch语句,当您为可能的状态添加新情况时,编译器将提供美丽的编译错误,提醒您在应用中对它进行优雅的处理。