RxSwift для кнопки "удаления" в tableView секции


#1

пытаюсь rx прикрутить к кнопке, которая в секции таблицы. Кнопка - это удаление всей секции. После нажатия на неё, subscribe выдаёт элементы, но из них нужен последний… С Rx только начал заниматься, нужен совет.
В данном случае пытался удалить 6-ю секцию.

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let headerView = tableView.dequeue(SectionHeaderView.self)
        headerView.titleLabel.text = (dataSource?.viewModel[section].sectionType.rawValue)! + " " + String(section)
        
        headerView.deleteButton.rx
            .tap
            .subscribe(onNext: { [weak self] in
                print("element: ", section)
                self?.dataSource?.viewModel.remove(at: section)
                self?.tableView.reloadData()
            })
            .disposed(by: headerView.rx_disposeBag)
        
        return headerView
    }

console:

element:  1
element:  1
element:  1
element:  1
element:  1
element:  2
element:  4
element:  6


#2

А что у вас за dispose такой, это что-то стандартное?)

На самом деле, если я все правильно понял, то у вас будет очень много подписок на кнопку, при каждом tableView.dequeue


#3

да, отписка стандартная, она находится в “UITableViewHeaderFooterView”

var rx_disposeBag = DisposeBag()

#4

Вы используете реактивщину внутри одно VC? или вы биндите к VM?

Просто к чему такое использование как у вас сейчас не очень понятно


#5

Кнопка находится в “SectionHeaderView”
ну и всё поделено на классы

import UIKit
import RxSwift
import RxCocoa

class SectionHeaderView: UITableViewHeaderFooterView {

    var rx_disposeBag = DisposeBag()

    var deleteButton: UIButton = {
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setImage(UIImage.imageIcon(name: "trash", pointSize: 20, tintColor: #colorLiteral(red: 0.7450980544, green: 0.1568627506, blue: 0.07450980693, alpha: 1)), for: UIControl.State.normal)
        return button
    }()
}


class ModalController: UIViewController, UITableViewDelegate {

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let headerView = tableView.dequeue(SectionHeaderView.self)
        headerView.titleLabel.text = (dataSource?.viewModel[section].sectionType.rawValue)! + " " + String(section)
        
        headerView.deleteButton.rx
            .tap
            .subscribe(onNext: { [weak self] in
                print("element: ", section)
                self?.dataSource?.viewModel.remove(at: section)
                self?.tableView.reloadData()
            })
            .disposed(by: headerView.rx_disposeBag)
        
        return headerView
    }
}

class ModalTableViewDataSource: NSObject, UITableViewDataSource {
    
    var viewModel: [Section] = []
}

#6

Вот можете посмотреть хороший пример использования rx) я по крайним мерам смотрел здесь в свое время)


#7

спасибо, посмотрю :ok_hand:


#8

Смотрел примеры отсуда, получается мне takeLast нужен, вот пример.
Но у меня похоже это не Array, а подписки.

let bag = DisposeBag()

let array = [1, 1, 1, 2, 3, 3, 5, 5, 6]

let observable = Observable<Int>.from(array)

let takeLastObservable = observable.takeLast(1)        

_ = takeLastObservable.subscribe { (e) in
    print(e)
}.disposed(by: bag)
next(6)
completed

#9

Ну я не практикую биндить табличные элементы с VM, обычно кидаю callBack а из него в приватный PublishSubject

protocol ViewModelType {
    associatedtype Input
    associatedtype Output
    
    func transform(input: Input) -> Output
}

Потом это subject внутри func transform обрабатывает ивенты и выдает новый dataSource


#11

Проблему решил, вот источник, если кому понадобится.