RxSwiftCommunity / RxDataSources

UITableView and UICollectionView Data Sources for RxSwift (sections, animated updates, editing ...)
MIT License
3.1k stars 495 forks source link

Some UITableView Delegate methods not called #215

Closed yairsz closed 6 years ago

yairsz commented 6 years ago

Hello, I'm finding that after setting a delegate through rx, some methods in UITableViewControllerDelegate are not called while others are. I took this code from the "Customization using tableview delegate" example on this repo. While the heightForRowAt method is called, none of the actions methods are called. I'd appreciate any help figuring this out. It seems like a bug to me.

//  CustomizationUsingTableViewDelegate.swift
//  RxDataSources
//
//  Created by Krunoslav Zaher on 4/19/16.
//  Copyright © 2016 kzaher. All rights reserved.
//

import Foundation
import UIKit
import RxSwift
import RxCocoa
import RxDataSources
import Differentiator

struct MySection {
    var header: String
    var items: [Item]
}

extension MySection : AnimatableSectionModelType {
    typealias Item = Int

    var identity: String {
        return header
    }

    init(original: MySection, items: [Item]) {
        self = original
        self.items = items
    }
}

class CustomizationUsingTableViewDelegate : UIViewController {
    @IBOutlet var tableView: UITableView!

    let disposeBag = DisposeBag()

    var dataSource: RxTableViewSectionedAnimatedDataSource<MySection>?

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")

        let dataSource = RxTableViewSectionedAnimatedDataSource<MySection>(
            configureCell: { ds, tv, ip, item in
                let cell = tv.dequeueReusableCell(withIdentifier: "Cell") ?? UITableViewCell(style: .default, reuseIdentifier: "Cell")
                cell.textLabel?.text = "Item \(item)"

                return cell
            },
            titleForHeaderInSection: { ds, index in
                return ds.sectionModels[index].header
            }
        )

        self.dataSource = dataSource

        let sections = [
            MySection(header: "First section", items: [
                1,
                2
            ]),
            MySection(header: "Second section", items: [
                3,
                4
            ])
        ]

        Observable.just(sections)
            .bind(to: tableView.rx.items(dataSource: dataSource))
            .disposed(by: disposeBag)

        tableView.rx.setDelegate(self)
            .disposed(by: disposeBag)
    }
}

extension CustomizationUsingTableViewDelegate : UITableViewDelegate {
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        // you can also fetch item
        guard let item = dataSource?[indexPath],
        // .. or section and customize what you like
            let _ = dataSource?[indexPath.section]
            else {
            return 0.0
        }

        return CGFloat(40 + item * 10)
    }

    public func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
        let responding = UITableViewRowAction(style: .default, title: "Action 1") { (action, indexPath) in

        }
        return [responding]
    }

    public func tableView(_ tableView: UITableView, canPerformAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
        return true
    }

    @available(iOS 11.0, *)
    public func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let responding = UIContextualAction(style: .normal, title: "Action 1") { (action: UIContextualAction, view: UIView, success :(Bool) -> Void) in }
        responding.backgroundColor = UIColor.orange
        return UISwipeActionsConfiguration(actions: [responding])
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == UITableViewCellEditingStyle.delete {
        }
    }

    func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
            return UITableViewCellEditingStyle.insert
    }
}
HHuckebein commented 6 years ago

try to add canEditRowAtIndexPath: { _, _ in true }) to your RxTableViewSectionedAnimatedDataSource initializer. You might also set the controller in editing mode too.

102301007 commented 2 years ago

Hello, I'm finding that after setting a delegate through rx, some methods in UITableViewControllerDelegate are not called while others are. I took this code from the "Customization using tableview delegate" example on this repo. While the heightForRowAt method is called, none of the actions methods are called. I'd appreciate any help figuring this out. It seems like a bug to me.

//  CustomizationUsingTableViewDelegate.swift
//  RxDataSources
//
//  Created by Krunoslav Zaher on 4/19/16.
//  Copyright © 2016 kzaher. All rights reserved.
//

import Foundation
import UIKit
import RxSwift
import RxCocoa
import RxDataSources
import Differentiator

struct MySection {
    var header: String
    var items: [Item]
}

extension MySection : AnimatableSectionModelType {
    typealias Item = Int

    var identity: String {
        return header
    }

    init(original: MySection, items: [Item]) {
        self = original
        self.items = items
    }
}

class CustomizationUsingTableViewDelegate : UIViewController {
    @IBOutlet var tableView: UITableView!

    let disposeBag = DisposeBag()

    var dataSource: RxTableViewSectionedAnimatedDataSource<MySection>?

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")

        let dataSource = RxTableViewSectionedAnimatedDataSource<MySection>(
            configureCell: { ds, tv, ip, item in
                let cell = tv.dequeueReusableCell(withIdentifier: "Cell") ?? UITableViewCell(style: .default, reuseIdentifier: "Cell")
                cell.textLabel?.text = "Item \(item)"

                return cell
            },
            titleForHeaderInSection: { ds, index in
                return ds.sectionModels[index].header
            }
        )

        self.dataSource = dataSource

        let sections = [
            MySection(header: "First section", items: [
                1,
                2
            ]),
            MySection(header: "Second section", items: [
                3,
                4
            ])
        ]

        Observable.just(sections)
            .bind(to: tableView.rx.items(dataSource: dataSource))
            .disposed(by: disposeBag)

        tableView.rx.setDelegate(self)
            .disposed(by: disposeBag)
    }
}

extension CustomizationUsingTableViewDelegate : UITableViewDelegate {
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        // you can also fetch item
        guard let item = dataSource?[indexPath],
        // .. or section and customize what you like
            let _ = dataSource?[indexPath.section]
            else {
            return 0.0
        }

        return CGFloat(40 + item * 10)
    }

    public func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
        let responding = UITableViewRowAction(style: .default, title: "Action 1") { (action, indexPath) in

        }
        return [responding]
    }

    public func tableView(_ tableView: UITableView, canPerformAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
        return true
    }

    @available(iOS 11.0, *)
    public func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let responding = UIContextualAction(style: .normal, title: "Action 1") { (action: UIContextualAction, view: UIView, success :(Bool) -> Void) in }
        responding.backgroundColor = UIColor.orange
        return UISwipeActionsConfiguration(actions: [responding])
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == UITableViewCellEditingStyle.delete {
        }
    }

    func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
            return UITableViewCellEditingStyle.insert
    }
}

Hello, did you manage to solve this problem? I faced the same issue. Can you help me?