Skip to content

ItemView

WooSeok Suh edited this page Jul 14, 2021 · 6 revisions

2021-07-06

by Seok

Step.1

ItemViewModel, Storage 생성

  • Protocol로 메서드 구현하여 테스트에 용이하도록 구현
  • Dummy Data 만들어서 추후 View에 bind예정
  • 추후 필요시 Delete 메서드 추가
  • 임의로 3개의 unit data 특정 시간마다 변경 로직 필요
import Foundation
import RxSwift

class ItemStorage: ItemStorageType {
    
    private var storage:[Unit] = [
        //Dummy Data
        Unit(uuid: 0, image: .cPlusPlus, level: 1, count: 1),
        Unit(uuid: 1, image: .java, level: 1, count: 1),
        Unit(uuid: 2, image: .kotlin, level: 1, count: 1),
        Unit(uuid: 3, image: .swift, level: 1, count: 1)
    ]
    
    private lazy var unitStorage = BehaviorSubject(value: storage)
    
    @discardableResult
    func create(item: Unit) -> Observable<Unit> {
        storage.append(item)
        unitStorage.onNext(storage)
        return Observable.just(item)
    }
    
    @discardableResult
    func list() -> Observable<[Unit]> {
        return unitStorage.asObservable()
    }
    
    @discardableResult
    func update(previous: Unit, new: Unit) -> Observable<Unit> {
        if let index = storage.firstIndex(where: { $0.uuid == previous.uuid}) {
            storage.remove(at: index)
            storage.insert(new, at: index)
        }
        unitStorage.onNext(storage)
        return Observable.just(new)
    }
}

2021-07-07

by Seok

Step.2

ItemCell 클릭하면 해당 정보 mainView에 표시

  • 추후 name, level, money 정보가 필요하여 mainImageView custom으로 수정 예정
  • UICollectionViewDelegateFlowLayout 처리 객체 설정(self)
private func setupDelegate() {
    itemCollectionView.rx.setDelegate(self).disposed(by: rx.disposeBag)
        
    itemCollectionView.rx.modelSelected(Unit.self)
        .subscribe(onNext: { [unowned self] unit in
            self.mainItemImageView.image = UIImage(named: unit.image)
        }).disposed(by: rx.disposeBag)
}

2021-07-08

by Seok

Step.3

ItemViewModel 로직구현

func bindViewModel() {
        
    viewModel.itemStorage
        .drive(itemCollectionView.rx.items(cellIdentifier: ItemCell.identifier, cellType: ItemCell.self)) { [unowned self] row, unit, cell in
            if row == 0 { self.setupItemInfomation(from: unit) }
            cell.configure(unit: unit)
        }.disposed(by: rx.disposeBag)
        
    viewModel.isPossibleToLevelUp
        .subscribe(onNext: { [unowned self] levelUp in
            self.observeLevelUpButton(levelUp)
        }).disposed(by: rx.disposeBag)
        
    cancelButton.rx.action = viewModel.cancelAction
}

Step4.

MainItemCustomView 생성(xib)

  • background image는 임의로 지정
import UIKit

final class MainItemView: UIView {
    
    @IBOutlet var contentView: UIView!
    @IBOutlet weak var backgroundImageView: UIImageView!
    @IBOutlet weak var itemImageView: UIImageView!
    @IBOutlet weak var levelLabel: UILabel!
    @IBOutlet weak var nameLabel: UILabel!

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        loadXib()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        loadXib()
    }
    
    func configure(_ info: Unit) {
        itemImageView.image = UIImage(named: info.image)
        nameLabel.text = info.image
        levelLabel.text = "\(info.level)"
    }
    
    private func loadXib() {
        let name = String(describing: type(of: self))
        Bundle.main.loadNibNamed(name, owner: self, options: nil)
        addSubview(contentView)
        contentView.frame = self.bounds
        contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    }
}

2021-07-14

by Seok

Step.5

  • ViewController Update 이슈 수정완료
  • ViewModel 중복 코드 삭제
  • ViewModel -> ViewController Observer 코드 수정
func bindViewModel() {
        
    viewModel.itemStorage
        .drive(itemCollectionView.rx.items(cellIdentifier: ItemCell.identifier, cellType: ItemCell.self)) { _, unit, cell in
            cell.configure(unit: unit)
        }.disposed(by: rx.disposeBag)
        
    viewModel.isPossibleToLevelUp
        .subscribe(onNext: { [unowned self] levelUp in
            self.observeLevelUpButton(levelUp)
        }).disposed(by: rx.disposeBag)
        
    viewModel.selectedUnit
        .subscribe(onNext: { [unowned self] unit in
            self.setupItemInfomation(from: unit)
        }).disposed(by: rx.disposeBag)
        
    viewModel.money
        .map {String($0)}
        .drive(mainItemView.availableMoneyLabel.rx.text)
        .disposed(by: rx.disposeBag)
                
    cancelButton.rx.action = viewModel.cancelAction
}
Clone this wiki locally