Contents 非表示
実装
Model
struct Pokemon {
var name: String
var type: String // Typeはお好みでEnumにしても良い気がする
var level: Int
}
ViewController
import UIKit
import RxSwift
import RxCocoa
final class HomeViewController: UIViewController {
// MARK: - Properties
@IBOutlet private weak var tableView: UITableView! {
didSet {
tableView.register(UINib(nibName: "HomeTableViewCell", bundle: nil), forCellReuseIdentifier: "HomeTableViewCell")
}
}
private let disposeBag = DisposeBag()
private let viewModel = HomeViewModel()
// MARK: - View Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
bind(to: viewModel)
}
}
// MARK: - Bind
private extension HomeViewController {
func bind(to viewModel: HomeViewModelType) {
viewModel.outputs.pokemon
.drive(tableView.rx.items) { tableView, row, element in
let indexPath = IndexPath(row: row, section: 0)
guard let cell = tableView.dequeueReusableCell(withIdentifier: "HomeTableViewCell", for: indexPath) as? HomeTableViewCell else {
return UITableViewCell()
}
cell.configure(with: element)
return cell
}
.disposed(by: disposeBag)
}
}
ViewModel
import RxSwift
import RxCocoa
protocol HomeViewModelInputs: AnyObject {
}
protocol HomeViewModelOutputs: AnyObject {
var pokemon: Driver<[Pokemon]> { get }
}
protocol HomeViewModelType: AnyObject {
var inputs: HomeViewModelInputs { get }
var outputs: HomeViewModelOutputs { get }
}
final class HomeViewModel: HomeViewModelType, HomeViewModelInputs, HomeViewModelOutputs {
// MARK: - Properties
var inputs: HomeViewModelInputs { return self }
var outputs: HomeViewModelOutputs { return self }
// MARK: - Input Sources
// MARK: - Output Sources
let pokemon: Driver<[Pokemon]>
// MARK: - Properties
// 模擬データ、本番ではAPIからデータ持ってくるとかになりそう。
private let pokemonArray: [Pokemon] = [
Pokemon(name: "Pikachu", type: "Electric", level: 10),
Pokemon(name: "Charmander", type: "Fire", level: 8),
Pokemon(name: "Bulbasaur", type: "Grass", level: 7),
Pokemon(name: "Squirtle", type: "Water", level: 9),
Pokemon(name: "Jigglypuff", type: "Fairy", level: 6),
Pokemon(name: "Geodude", type: "Rock", level: 12),
Pokemon(name: "Abra", type: "Psychic", level: 11),
Pokemon(name: "Machop", type: "Fighting", level: 10),
Pokemon(name: "Gastly", type: "Ghost", level: 8),
Pokemon(name: "Snorlax", type: "Normal", level: 15)
]
private let _pokemon = BehaviorRelay<[Pokemon]>(value: [])
private let disposeBag = DisposeBag()
// MARK: - Initialize
init() {
_pokemon.accept(pokemonArray)
pokemon = _pokemon.asDriver(onErrorDriveWith: .empty())
}
}
TableViewCell
import UIKit
final class HomeTableViewCell: UITableViewCell {
// MARK: - Properties
@IBOutlet private weak var nameLabel: UILabel!
@IBOutlet private weak var typeLabel: UILabel!
@IBOutlet private weak var levelLabel: UILabel!
// MARK: - Initialize
override func prepareForReuse() {
super.prepareForReuse()
nameLabel.text = nil
typeLabel.text = nil
levelLabel.text = nil
}
// MARK: - Setup
func configure(with pokemon: Pokemon) {
nameLabel.text = pokemon.name
typeLabel.text = pokemon.type
levelLabel.text = "Level: \(pokemon.level)"
}
}