質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
RxSwift

RxSwiftは、Reactive ExtensionsのSwift向けの実装です。iOS開発に用いられ、リアクティブプログラミングを可能にします。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

解決済

RxSwift TableViewのItem追加時の更新がならない

mogiruri
mogiruri

総合スコア0

RxSwift

RxSwiftは、Reactive ExtensionsのSwift向けの実装です。iOS開発に用いられ、リアクティブプログラミングを可能にします。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

1回答

0評価

1クリップ

72閲覧

投稿2019/06/25 07:35

編集2022/01/12 10:58

こんにちは。RxSwiftの勉強をしており、UITableViewなど多用されるものの扱いはさらっておこうと取り組んでおります。
TodoList的なものを作成し、TabelViewにもともとかかれてある配列情報を表示させるところまではできました。

ですが、アイテムのその配列に追加した際にtableViewがreloadされず(希望通りの表示がされず)に困っております。

tableviewとアイテム追加用のviewをtabViewで分けており、回答してくださる方がなるべくわかりやすいように関係部分のコードを全て掲載いたしますので、少々長いコードになります。

Model

swift

struct Item: Codable { var name = String() var detail = String() var tag = String() var memo = String() var fav = Bool() var cellNo = Int() init(name: String, detail: String, tag: String, memo: String, fav: Bool, celllNo: Int) { self.name = name self.detail = detail self.tag = tag self.memo = memo self.fav = fav self.cellNo = celllNo } init() { self.init( name: "Apple", detail: "red", tag: "fruit", memo: "", fav: false, celllNo: 0 ) } } var items: [Item] = [Item()] { didSet { UserDefault.shared.saveItems(items: items) } } struct SectionModel: Codable { var list: [Item] } extension SectionModel: SectionModelType { var items: [Item] { return list } init(original: SectionModel, items: [Item]) { self = original self.list = items } } var list: [SectionModel] = [SectionModel(list: items)] { didSet { UserDefault.shared.saveList(list: list) } }

View

swift

class MainTabViewController: UIViewController { @IBOutlet weak var tableView: UITableView! private let disposeBag = DisposeBag() private var dataSource: RxTableViewSectionedReloadDataSource<SectionModel>! private lazy var viewModel = MainTabViewModel() override func viewDidLoad() { super.viewDidLoad() setupTableViewDataSource() binding() } func setupTableViewDataSource() { dataSource = RxTableViewSectionedReloadDataSource<SectionModel>(configureCell: {(_, tableView, indexPath, item) in let cell = tableView.dequeueReusableCell(withIdentifier: "ListCell") as! ListCell cell.selectionStyle = .none cell.backgroundColor = .clear cell.configure(item: item) return cell }) } func binding() { tableView.rx.itemDeleted .subscribe { print("delete") } .disposed(by: disposeBag) viewModel._dispItems.asObservable() .bind(to: tableView.rx.items(dataSource: dataSource)) .disposed(by: disposeBag) } }

ViewModel

swift

final class MainTabViewModel { private let userDefault: UserDefaultManager let _dispItems = BehaviorRelay<[SectionModel]>(value: []) init(userDefault: UserDefaultManager = UserDefault()) { self.userDefault = userDefault let newValue = _dispItems.value + list _dispItems.accept(newValue) } }

以下でアイテムの追加を行います。
View

swift

class AddTabViewController: UIViewController { @IBOutlet weak var titleLable: UILabel! @IBOutlet weak var itemTextField: UITextField! @IBOutlet weak var detailTextField: UITextField! @IBOutlet weak var tagTextField: UITextField! @IBOutlet weak var memoTextView: UITextView! @IBOutlet weak var addButton: UIButton! private lazy var viewMdoel = AddTabViewModel( itemLabelObservable: itemTextField.rx.text.asObservable(), detailLabelObservable: detailTextField.rx.text.asObservable(), tagLabelObservable: tagTextField.rx.text.asObservable(), memoLabelObservable: memoTextView.rx.text.asObservable(), addButtonTapped: addButton.rx.tap.asObservable(), validation: Validation() ) private let disposeBag = DisposeBag() override func viewDidLoad() { super.viewDidLoad() uiSetup() bindingViewModel() } func bindingViewModel() { itemTextField.rx.text .bind(to: viewMdoel.itemLabel) .disposed(by: disposeBag) detailTextField.rx.text .bind(to: viewMdoel.detailLabel) .disposed(by: disposeBag) tagTextField.rx.text .bind(to: viewMdoel.tagLabel) .disposed(by: disposeBag) memoTextView.rx.text .bind(to: viewMdoel.memoLabel) .disposed(by: disposeBag) viewMdoel.isEnableButton .bind(to: addButton.rx.isEnabled) .disposed(by: disposeBag) addButton.rx.tap .subscribe(onNext: { _ in self.viewMdoel.addItem() }) .disposed(by: disposeBag) } }

viewModel

swift

final class AddTabViewModel { let validatedItem: Observable<Bool> let validatedDetail: Observable<Bool> let validatedTag: Observable<Bool> let isEnableButton: Observable<Bool> let itemLabel = BehaviorRelay<String?>(value: "") let detailLabel = BehaviorRelay<String?>(value: "") let tagLabel = BehaviorRelay<String?>(value: "") let memoLabel = BehaviorRelay<String?>(value: "") init( itemLabelObservable: Observable<String?>, detailLabelObservable: Observable<String?>, tagLabelObservable: Observable<String?>, memoLabelObservable: Observable<String?>, addButtonTapped: Observable<Void>, validation: TextValidate ) { validatedItem = itemLabelObservable .flatMapLatest { (input) -> Observable<Bool> in return validation .validate(text: input) .catchErrorJustReturn(false) } .share() validatedDetail = detailLabelObservable .flatMapLatest { (input) -> Observable<Bool> in return validation .validate(text: input) .catchErrorJustReturn(false) } .share() validatedTag = tagLabelObservable .flatMapLatest { (input) -> Observable<Bool> in return validation .validate(text: input) .catchErrorJustReturn(false) } .share() isEnableButton = Observable.combineLatest( validatedItem, validatedDetail, validatedTag ) { $0 && $1 && $2 } .share() } func addItem() { let item = Item( name: itemLabel.value!, detail: detailLabel.value!, tag: tagLabel.value!, memo: memoLabel.value!, fav: false, celllNo: items.count ) list[0].list.append(item) print(list) } }

確認してみたこと

とりあえずprintでcellの作成で使用する配列をみてみたところ、ここには追加されたものは入っているようでした。

そもそも、RxSwiftでtableViewを作成する場合、reloadData()がどこでどう呼ばれて更新されるのか把握していないのですが、(監視しているので、変更があれば自動的に更新されると今は解釈しています)
ViewにUIButtonを配置し、プッシュしたらreloadData()を走らせるという流れも行ったのですが、リロードしてもデータが変わることはありませんでした。

問題の部分をなかなか見つけられず先へ進めずにいます。どうか助けていただけると幸いです。
よろしくお願いいたします。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

RxSwift

RxSwiftは、Reactive ExtensionsのSwift向けの実装です。iOS開発に用いられ、リアクティブプログラミングを可能にします。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています