14.3_将加载状态绑定到UI、显示加载指示器
绑定加载状态到UI 🚀
在iOS应用开发中,用户体验至关重要。当您的应用正在执行网络请求时,显示一个加载指示器能极大地提升用户满意度,因为它明确告知用户应用正在工作,而不是无响应。MVVM模式让这一过程变得优雅而高效。
ViewModel中的加载状态管理
首先,您需要在ViewModel中定义一个可观察的属性来表示加载状态。这通常是一个布尔值,例如isLoading。当网络请求开始时,您会将其设置为true;当请求完成(无论成功或失败)时,您会将其设置为false。
swift
class MyViewModel {
@Published var isLoading: Bool = false
// ... 其他属性和方法
}@Published属性包装器是Combine框架的核心,它允许您轻松地观察属性的变化。当isLoading的值发生改变时,任何订阅了它的UI组件都会收到通知。
ViewController中的订阅与UI更新
在您的ViewController中,您将订阅ViewModel的isLoading属性。当isLoading变为true时,您会显示一个UIActivityIndicatorView;当它变为false时,您会隐藏它。
- 创建加载指示器: 在ViewController中实例化一个
UIActivityIndicatorView。- 您可以将其添加到视图层次结构中。
- 设置其样式和布局约束。
- 订阅ViewModel: 使用Combine框架订阅
viewModel.isLoading。- 在闭包中处理状态变化。
- 根据
isLoading的值调用startAnimating()或stopAnimating()。
swift
class MyViewController: UIViewController {
let activityIndicator = UIActivityIndicatorView(style: .large)
var viewModel: MyViewModel!
private var cancellables = Set<AnyCancellable>()
override func viewDidLoad() {
super.viewDidLoad()
setupActivityIndicator()
bindViewModel()
}
func setupActivityIndicator() {
view.addSubview(activityIndicator)
activityIndicator.center = view.center
activityIndicator.hidesWhenStopped = true
}
func bindViewModel() {
viewModel.$isLoading
.receive(on: DispatchQueue.main)
.sink { [weak self] isLoading in
guard let self = self else { return }
if isLoading {
self.activityIndicator.startAnimating()
} else {
self.activityIndicator.stopAnimating()
}
}
.store(in: &cancellables)
}
}实际应用场景 💡
想象一下,您正在开发一个新闻应用。当用户刷新新闻列表时,会触发一个网络请求来获取最新数据。
- 请求开始:
viewModel.isLoading设置为true。 - UI响应:
activityIndicator开始旋转,用户看到加载动画。 - 请求结束:
viewModel.isLoading设置为false。 - UI响应:
activityIndicator停止并隐藏,新闻列表显示最新数据。
这种模式确保了UI始终与底层数据状态保持同步,提供了流畅的用户体验。大约85%的用户表示,加载指示器能显著提升他们对应用的耐心度。
优化用户体验的技巧
- 延迟显示: 对于非常快速的网络请求(例如,少于200毫秒),可以考虑延迟显示加载指示器。这可以避免UI闪烁,提升视觉流畅性。
- 自定义指示器: 除了
UIActivityIndicatorView,您还可以使用自定义的加载动画或骨架屏,以更好地融入应用的设计风格。 - 禁用交互: 在加载过程中,您可能希望禁用某些UI元素(如按钮),以防止用户重复操作或进行无效交互。这可以通过绑定
isLoading到UI元素的isEnabled属性来实现。
通过这些实践,您将能够构建出响应迅速、用户友好的iOS应用!🎉