Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/122.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios RxSwift在选择时修改tableview单元格_Ios_Rx Swift_Rx Cocoa - Fatal编程技术网

Ios RxSwift在选择时修改tableview单元格

Ios RxSwift在选择时修改tableview单元格,ios,rx-swift,rx-cocoa,Ios,Rx Swift,Rx Cocoa,我的应用程序中有一个表视图。我使用以下代码生成了这个表的数据源 struct ContactNameNumberBlockStatus { var contactThumbnail: Data? var contactName : String var contactNumber: String var blockStatus : Bool } class BlockListTableViewCell: UITableViewCell { @IBOutl

我的应用程序中有一个表视图。我使用以下代码生成了这个表的数据源

struct ContactNameNumberBlockStatus {
    var contactThumbnail: Data?
    var contactName : String
    var contactNumber: String
    var blockStatus : Bool
}

class BlockListTableViewCell: UITableViewCell {
    @IBOutlet weak var contactImage: UIImageView!
    @IBOutlet weak var contactName: UILabel!
    @IBOutlet weak var contactNumber: UILabel!
    @IBOutlet weak var blockButton: UIButton!
    var eachCell : ContactNameNumberBlockStatus! {
        didSet {
            // setting ui
        }
    }
}

private func showTableContent(data :   Observable<[ContactNameNumberBlockStatus]>) {
        data.bindTo(tableView.rx.items(
            cellIdentifier: "BlockListTableViewCell")) {
            row, contributor, cell in
            if let cell2 = cell as? BlockListTableViewCell {
                cell2.eachCell = contributor
            }
            }.addDisposableTo(disposeBag)
}
tableView.rx.itemSelected
  .subscribe(onNext: { [weak self]indexPath in

  }).addDisposableTo(disposeBag)
我发现
tableView.rx.itemSelected
与上面的
didSelectRowAt
相同,但我找不到如何使用以下代码更新表视图

struct ContactNameNumberBlockStatus {
    var contactThumbnail: Data?
    var contactName : String
    var contactNumber: String
    var blockStatus : Bool
}

class BlockListTableViewCell: UITableViewCell {
    @IBOutlet weak var contactImage: UIImageView!
    @IBOutlet weak var contactName: UILabel!
    @IBOutlet weak var contactNumber: UILabel!
    @IBOutlet weak var blockButton: UIButton!
    var eachCell : ContactNameNumberBlockStatus! {
        didSet {
            // setting ui
        }
    }
}

private func showTableContent(data :   Observable<[ContactNameNumberBlockStatus]>) {
        data.bindTo(tableView.rx.items(
            cellIdentifier: "BlockListTableViewCell")) {
            row, contributor, cell in
            if let cell2 = cell as? BlockListTableViewCell {
                cell2.eachCell = contributor
            }
            }.addDisposableTo(disposeBag)
}
tableView.rx.itemSelected
  .subscribe(onNext: { [weak self]indexPath in

  }).addDisposableTo(disposeBag)

那么如何更新单元格呢?

您可以像这样访问单元格

tableView.rx.itemSelected
  .subscribe(onNext: { [weak self] indexPath in
    let cell = self?.tableview.cellForRow(at: indexPath) as? SomeCellClass
    cell.button.isEnabled = false
  }).addDisposableTo(disposeBag)

//访问模型

            tableView.rx.modelSelected(Item.self)
            .subscribe(onNext: { [weak self] model in
                guard let self = self else { return }
                self.selectedItem = model
            }).disposed(by: disposeBag)
            
         eg: var names = ["A", "B", "C"]
                tableView.rx.itemSelected
                    .subscribe(onNext: { [weak self] indexPath in
                        guard let self = self else { return }
                        self.selectedName = self.names[indexPath.row]
                        self.performSegue(withIdentifier: "ItemDetail", sender: self)
                    }).disposed(by: disposeBag)

//访问indepath

            tableView.rx.modelSelected(Item.self)
            .subscribe(onNext: { [weak self] model in
                guard let self = self else { return }
                self.selectedItem = model
            }).disposed(by: disposeBag)
            
         eg: var names = ["A", "B", "C"]
                tableView.rx.itemSelected
                    .subscribe(onNext: { [weak self] indexPath in
                        guard let self = self else { return }
                        self.selectedName = self.names[indexPath.row]
                        self.performSegue(withIdentifier: "ItemDetail", sender: self)
                    }).disposed(by: disposeBag)

如果您想获得模型句柄和索引路径,则可以在文件中同时包含这两个属性

我不太喜欢接受的答案,因为在该答案中,没有跟踪块状态的模型。相反,它只是禁用按钮。让您的视图状态遵循模型很重要,而公认的答案忽略了这一点

以下内容显然更为复杂,但它设置了模型,并使视图的状态反映了底层模型,而不是回避模型

enum Input {
    case reset([ContactNameNumberBlockStatus])
    case blockTapped(UUID)
}

struct State {
    var order: [UUID] = []
    var values: [UUID: ContactNameNumberBlockStatus] = [:]
}

let taps = PublishSubject<UUID>()

let state = Observable.merge(
    contacts.map { Input.reset($0) },
    taps.map { Input.blockTapped($0) }
)
.scan(into: State()) { (state, input) in
    switch input {
    case .reset(let contacts):
        state.order = contacts.map { _ in UUID() }
        state.values = Dictionary.init(zip(state.order, contacts), uniquingKeysWith: { lhs, _ in lhs })
    case .blockTapped(let uuid):
        state.values[uuid]!.blockStatus = true
    }
}

state
    .map { $0.order }
    .bind(to: tableView.rx.items(cellIdentifier: "BlockListTableViewCell", cellType: BlockListTableViewCell.self)) { row, uuid, cell in
        let cellState = state.compactMap { $0.values[uuid] }
        cell.disposeBag.insert(
            cellState.map { $0.contactThumbnail.flatMap { UIImage(data: $0) } }.bind(to: cell.contactImage.rx.image),
            cellState.map { $0.contactName }.bind(to: cell.contactName.rx.text),
            cellState.map { $0.contactNumber }.bind(to: cell.contactNumber.rx.text),
            cellState.map { $0.blockStatus }.bind(to: cell.blockButton.rx.isHidden),
            cell.blockButton.rx.tap.map { uuid }.bind(to: taps)
        )

    }
    .disposed(by: disposeBag)
enum输入{
案例重置([ContactNameNumberBlockStatus])
案例分块(UUID)
}
结构状态{
变量顺序:[UUID]=[]
变量值:[UUID:ContactNameNumberBlockStatus]=[:]
}
让taps=PublishSubject()
让state=Observable.merge(
contacts.map{Input.reset($0)},
taps.map{Input.blockTapped($0)}
)
.scan(进入:状态()){(状态,输入)中
开关输入{
案例。复位(让触点复位):
state.order=contacts.map{UUID()中的{uu}
state.values=Dictionary.init(zip(state.order,contacts),uniquingKeysWith:{lhs,u在lhs})
案例。分块分接(让uuid):
state.values[uuid]!.blockStatus=true
}
}
状态
.map{$0.order}
.bind(到:tableView.rx.items(cellIdentifier:“BlockListTableViewCell”,cellType:BlockListTableViewCell.self)){row,uuid,中的单元格
让cellState=state.compactMap{$0.values[uuid]}
cell.disposeBag.insert(
cellState.map{$0.contactThumbnail.flatMap{UIImage(数据:$0)}}.bind(到:cell.contactImage.rx.image),
cellState.map{$0.contactName}.bind(到:cell.contactName.rx.text),
cellState.map{$0.contactNumber}.bind(到:cell.contactNumber.rx.text),
cellState.map{$0.blockStatus}.bind(到:cell.blockButton.rx.ishiden),
cell.blockButton.rx.tap.map{uuid}.bind(到:taps)
)
}
.处置(由:处置人)
上面的代码设置了一个状态机,该状态机跟踪用户并根据需要更新用户模型,从而导致视图更新。它的可扩展性更强;当发现新的用户输入时,只需在
输入
类型中添加一个大小写即可。此外,当发现新状态时,可以将其添加到状态类型中


该守则还有一个额外的好处;更新模型中项目的状态不会导致重新加载整个表视图。只有该单元格将被更改。

是否尝试在
中更改模型并重新加载表视图。subscribe(onNext:{})
方法?我无法更改模型,因为它的
let
类型欢迎使用堆栈溢出:-)请查看。您应该提供一些信息,说明代码解决问题的原因。只写代码的答案对社区没有用处。我之所以对答案投赞成票,仅仅是因为我讨厌仇恨者(即使他们使用友好的词语)。