はじめに
WWDC23(2023 Apple Worldwide Developers Confere)でUIKitの新機能が色々発表され、その中でも今後よく使っていくであろうEmpty State(UIContentUnavailableConfiguration)について備忘録としてまとめました。
公式ドキュメント
Empty Stateの概要
機能概要
以下公式発表ではEmpty Stateとして紹介されていますが、UIContentUnavailableConfigurationというUIKitのストラクチャです。Stateに応じて画面に画像/ラベル/ボタンを表示・切り替えることができます。
特性と使い方
ViewControllerのcontentUnavailableConfigurationに対し様々なUIContentUnavailableConfigurationのStateを設定することにより、画面に画像/ラベル/ボタンを表示したり切り替えたりすることができます。
画像等を非表示にするためには明示的にnilを設定する必要があります。
実装例
import UIKit
class SecondViewController: UIViewController {
// Stateを用意
enum UnavailableState {
case normal
case empty
case loading
case error
}
@IBOutlet weak var tableView: UITableView!
var screenState: UnavailableState = .loading
override func viewDidLoad() {
super.viewDidLoad()
// 使用するセルをテーブルビューに登録する
self.tableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: "tableViewCell")
// ステータスを指定
self.setupUnavailableConfiguration(state: .normal)
}
private func setupUnavailableConfiguration(state: UnavailableState) {
self.screenState = state
switch state {
case .normal:
// 画像・テキスト・ボタンを非表示
self.contentUnavailableConfiguration = nil
case .empty:
var config = UIContentUnavailableConfiguration.search()
config.text = "No Data"
config.secondaryText = "Please try again"
var buttonConfig = UIButton.Configuration.filled()
buttonConfig.title = "Retry"
config.button = buttonConfig
config.buttonProperties.primaryAction = UIAction(handler: { _ in
// button action
})
self.contentUnavailableConfiguration = config
case .loading:
var config = UIContentUnavailableConfiguration.loading()
config.text = "Please wait..."
config.textProperties.font = .boldSystemFont(ofSize: 18)
self.contentUnavailableConfiguration = config
case .error:
var config = UIContentUnavailableConfiguration.empty()
config.image = UIImage(systemName: "exclamationmark.triangle")
config.imageProperties.tintColor = .red
config.text = "Error"
config.textProperties.color = .red
self.contentUnavailableConfiguration = config
}
}
}
extension SecondViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// 用意するセルの個数
return self.screenState == .normal ? 50 : 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// テーブルビューの枠内に表示するセルを指定する
guard let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell") as? TableViewCell else {
return UITableViewCell()
}
// セルのレイアウト設定
cell.setCellLabel(cellIndex: indexPath.row.description)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// セル押下時の挙動
let storyboard = UIStoryboard(name: "ThirdView", bundle: nil)
guard let thirdViewController = storyboard.instantiateViewController(withIdentifier: "thirdView") as? ThirdViewController else {
return
}
guard let cell = tableView.cellForRow(at: indexPath) as? TableViewCell else {
return
}
thirdViewController.randomString = cell.cellLabel.text ?? ""
self.navigationController?.pushViewController(thirdViewController, animated: true)
}
}
画面キャプチャ
State | 正常 | Loading | Empty | Error |
---|---|---|---|---|
画面 |
まとめ
UIContentUnavailableConfigurationを使用するとローディング中やエラーの場合などに専用のビューを作成する必要がないのでとても魅力的ですね。アプリ開発において必須というわけではなさそうですが、知っておいて損は無い技術だと感じました。
WWDCではいくつもの新しい項目が発表され、追いつけていないどころか1年周回遅れになりそうですが、空き時間にコツコツ勉強していきたいところです。