こんにちは。RxSwiftの勉強をしており、UITableViewなど多用されるものの扱いはさらっておこうと取り組んでおります。
TodoList的なものを作成し、TabelViewにもともとかかれてある配列情報を表示させるところまではできました。
ですが、アイテムのその配列に追加した際にtableViewがreloadされず(希望通りの表示がされず)に困っております。
tableviewとアイテム追加用のviewをtabViewで分けており、回答してくださる方がなるべくわかりやすいように関係部分のコードを全て掲載いたしますので、少々長いコードになります。
Model
swift
1 2struct Item: Codable { 3 var name = String() 4 var detail = String() 5 var tag = String() 6 var memo = String() 7 var fav = Bool() 8 var cellNo = Int() 9 10 init(name: String, detail: String, tag: String, memo: String, fav: Bool, celllNo: Int) { 11 self.name = name 12 self.detail = detail 13 self.tag = tag 14 self.memo = memo 15 self.fav = fav 16 self.cellNo = celllNo 17 } 18 19 init() { 20 self.init( 21 name: "Apple", 22 detail: "red", 23 tag: "fruit", 24 memo: "", 25 fav: false, 26 celllNo: 0 27 ) 28 } 29} 30 31var items: [Item] = [Item()] { 32 didSet { 33 UserDefault.shared.saveItems(items: items) 34 } 35} 36 37struct SectionModel: Codable { 38 var list: [Item] 39} 40extension SectionModel: SectionModelType { 41 var items: [Item] { 42 return list 43 } 44 45 init(original: SectionModel, items: [Item]) { 46 self = original 47 self.list = items 48 } 49 50} 51 52var list: [SectionModel] = [SectionModel(list: items)] { 53 didSet { 54 UserDefault.shared.saveList(list: list) 55 } 56} 57
View
swift
1class MainTabViewController: UIViewController { 2 3 @IBOutlet weak var tableView: UITableView! 4 5 private let disposeBag = DisposeBag() 6 private var dataSource: RxTableViewSectionedReloadDataSource<SectionModel>! 7 private lazy var viewModel = MainTabViewModel() 8 9 override func viewDidLoad() { 10 super.viewDidLoad() 11 setupTableViewDataSource() 12 binding() 13 } 14 15 func setupTableViewDataSource() { 16 dataSource = RxTableViewSectionedReloadDataSource<SectionModel>(configureCell: {(_, tableView, indexPath, item) in 17 let cell = tableView.dequeueReusableCell(withIdentifier: "ListCell") as! ListCell 18 cell.selectionStyle = .none 19 cell.backgroundColor = .clear 20 cell.configure(item: item) 21 return cell 22 }) 23 } 24 25 func binding() { 26 27 tableView.rx.itemDeleted 28 .subscribe { 29 print("delete") 30 } 31 .disposed(by: disposeBag) 32 33 viewModel._dispItems.asObservable() 34 .bind(to: tableView.rx.items(dataSource: dataSource)) 35 .disposed(by: disposeBag) 36 } 37}
ViewModel
swift
1final class MainTabViewModel { 2 3 private let userDefault: UserDefaultManager 4 let _dispItems = BehaviorRelay<[SectionModel]>(value: []) 5 6 init(userDefault: UserDefaultManager = UserDefault()) { 7 self.userDefault = userDefault 8 let newValue = _dispItems.value + list 9 _dispItems.accept(newValue) 10 } 11} 12
以下でアイテムの追加を行います。
View
swift
1class AddTabViewController: UIViewController { 2 3 @IBOutlet weak var titleLable: UILabel! 4 @IBOutlet weak var itemTextField: UITextField! 5 @IBOutlet weak var detailTextField: UITextField! 6 @IBOutlet weak var tagTextField: UITextField! 7 @IBOutlet weak var memoTextView: UITextView! 8 @IBOutlet weak var addButton: UIButton! 9 10 private lazy var viewMdoel = AddTabViewModel( 11 itemLabelObservable: itemTextField.rx.text.asObservable(), 12 detailLabelObservable: detailTextField.rx.text.asObservable(), 13 tagLabelObservable: tagTextField.rx.text.asObservable(), 14 memoLabelObservable: memoTextView.rx.text.asObservable(), 15 addButtonTapped: addButton.rx.tap.asObservable(), 16 validation: Validation() 17 ) 18 19 private let disposeBag = DisposeBag() 20 21 override func viewDidLoad() { 22 super.viewDidLoad() 23 uiSetup() 24 bindingViewModel() 25 } 26 27 func bindingViewModel() { 28 29 itemTextField.rx.text 30 .bind(to: viewMdoel.itemLabel) 31 .disposed(by: disposeBag) 32 33 detailTextField.rx.text 34 .bind(to: viewMdoel.detailLabel) 35 .disposed(by: disposeBag) 36 37 tagTextField.rx.text 38 .bind(to: viewMdoel.tagLabel) 39 .disposed(by: disposeBag) 40 41 memoTextView.rx.text 42 .bind(to: viewMdoel.memoLabel) 43 .disposed(by: disposeBag) 44 45 viewMdoel.isEnableButton 46 .bind(to: addButton.rx.isEnabled) 47 .disposed(by: disposeBag) 48 49 addButton.rx.tap 50 .subscribe(onNext: { _ in 51 self.viewMdoel.addItem() 52 }) 53 .disposed(by: disposeBag) 54 } 55}
viewModel
swift
1final class AddTabViewModel { 2 3 let validatedItem: Observable<Bool> 4 let validatedDetail: Observable<Bool> 5 let validatedTag: Observable<Bool> 6 let isEnableButton: Observable<Bool> 7 let itemLabel = BehaviorRelay<String?>(value: "") 8 let detailLabel = BehaviorRelay<String?>(value: "") 9 let tagLabel = BehaviorRelay<String?>(value: "") 10 let memoLabel = BehaviorRelay<String?>(value: "") 11 12 init( 13 itemLabelObservable: Observable<String?>, 14 detailLabelObservable: Observable<String?>, 15 tagLabelObservable: Observable<String?>, 16 memoLabelObservable: Observable<String?>, 17 addButtonTapped: Observable<Void>, 18 validation: TextValidate 19 ) { 20 21 validatedItem = itemLabelObservable 22 .flatMapLatest { (input) -> Observable<Bool> in 23 return validation 24 .validate(text: input) 25 .catchErrorJustReturn(false) 26 } 27 .share() 28 29 validatedDetail = detailLabelObservable 30 .flatMapLatest { (input) -> Observable<Bool> in 31 return validation 32 .validate(text: input) 33 .catchErrorJustReturn(false) 34 } 35 .share() 36 37 validatedTag = tagLabelObservable 38 .flatMapLatest { (input) -> Observable<Bool> in 39 return validation 40 .validate(text: input) 41 .catchErrorJustReturn(false) 42 } 43 .share() 44 45 isEnableButton = Observable.combineLatest( 46 validatedItem, 47 validatedDetail, 48 validatedTag 49 50 ) { 51 $0 && $1 && $2 52 } 53 .share() 54 55 } 56 57 func addItem() { 58 let item = Item( 59 name: itemLabel.value!, 60 detail: detailLabel.value!, 61 tag: tagLabel.value!, 62 memo: memoLabel.value!, 63 fav: false, 64 celllNo: items.count 65 ) 66 list[0].list.append(item) 67 print(list) 68 } 69 70}
確認してみたこと
とりあえずprintでcellの作成で使用する配列をみてみたところ、ここには追加されたものは入っているようでした。
そもそも、RxSwiftでtableViewを作成する場合、reloadData()
がどこでどう呼ばれて更新されるのか把握していないのですが、(監視しているので、変更があれば自動的に更新されると今は解釈しています)
ViewにUIButtonを配置し、プッシュしたらreloadData()
を走らせるという流れも行ったのですが、リロードしてもデータが変わることはありませんでした。
問題の部分をなかなか見つけられず先へ進めずにいます。どうか助けていただけると幸いです。
よろしくお願いいたします。
追記 解決コード
swift
1// Model に以下を追加 2let dispItems = BehaviorRelay<[SectionModel]>(value: []) 3 4 5// mainTabViewModel 6final class MainTabViewModel { 7 8 private let userDefault: UserDefaultManager 9 var _dispItems = BehaviorRelay<[SectionModel]>(value: []) 10 11 init(userDefault: UserDefaultManager = UserDefault()) { 12 13 self.userDefault = userDefault 14 let newValue = list 15 dispItems.accept(newValue) 16 17 // とりあえずイコール 18 _dispItems = dispItems 19 } 20} 21 22// addTabViewModel 23 24func addItem() { 25 let item = Item( 26 name: itemLabel.value!, 27 detail: detailLabel.value!, 28 tag: tagLabel.value!, 29 memo: memoLabel.value!, 30 fav: false, 31 celllNo: items.count 32 ) 33 list[0].list.append(item) 34 print(list) 35 // Modelに定義しているものに変更した値を入れる 36 dispItems.accept(list) 37 } 38
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/06/26 07:27
2019/06/26 10:28 編集
2019/06/27 04:27