在 Stackview 中设置项目的 id [英] setting ids on item in Stackview

查看:60
本文介绍了在 Stackview 中设置项目的 id的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用于创建复选框的对象数组.该模型有一个 id,名称.我创建了一个 stackView 来处理带有 id 的复选框,现在我想将选定复选框的项目附加到一个数组中,并且能够在取消选择时删除它们.我能够展示所有的观点,而且效果很好

I have an array of object which I used to create a checkbox. The model has an id, name. I created a stackView to handle checkbox with id now I want to append items of selected checkbox to an array and be able to remove them when deselected. I am able to present all the views and it works well

下面是我的代码

NetworkAdapter.instance.getFeaturesAmeneities()
            .subscribe(onNext: {feat in
                guard let data  = feat.data else {return}
                self.features.append(contentsOf: data)

                self.stackFeature.axis = .vertical
                self.stackFeature.distribution = .fill
                self.stackFeature.spacing = 8

                data.forEach {
                    print($0.id)
                    self.stv = CheckboxStackView()
                    self.stv?.label.text = $0.name
                    self.stv?.checkBox.tag = $0.id ?? 0
                    self.stackFeature.addArrangedSubview(self.stv!)
                }

            }).disposed(by: disposeBag)

感谢任何帮助

推荐答案

为了回答这个问题,我们首先必须使堆栈视图具有反应性和声明性.这意味着我们必须能够使用单个赋值来设置视图,并且需要是观察者.这就像 RxCocoa 库为 UICollectionView、UITableView 和 UIPickerView 所做的一样.

In order to answer this question, we first have to make the stack view reactive and declarative. This means that we have to be able to set the view using a single assignment and that needs to be an observer. This is just like what the RxCocoa library does for UICollectionView, UITableView and UIPickerView.

写函数有点高级.首先我们从上面的其他视图中获取签名来定义函数的形状.

Writing the function is a bit advanced. First we take the signature from the other views above to define the shape of the function.

func items<Sequence: Swift.Sequence, Source: ObservableType>(_ source: Source) -> (_ viewForRow: @escaping (Int, Sequence.Element, UIView?) -> UIView) -> Disposable where Source.Element == Sequence

以上内容可能看起来令人生畏.这是一个函数,它接受序列的源序列并返回一个函数,该函数接受一个用于组装视图的闭包并返回一个 Dispoable.

The above probably looks daunting. It's a function that takes a source sequence of sequences and returns a function that takes a closure for assembling the views and returns a Dispoable.

完成的功能如下:

extension Reactive where Base: UIStackView {

    func items<Sequence: Swift.Sequence, Source: ObservableType>(_ source: Source) -> (_ viewForRow: @escaping (Int, Sequence.Element, UIView?) -> UIView) -> Disposable where Source.Element == Sequence {
        return { viewForRow in
            return source.subscribe { event in
                switch event {
                case .next(let values):
                    let views = self.base.arrangedSubviews
                    let viewsCount = views.count
                    var valuesCount = 0
                    for (index, value) in values.enumerated() {
                        if index < viewsCount {
                            // update views that already exist
                            _ = viewForRow(index, value, views[index])
                        }
                        else {
                            // add new views if needed
                            let view = viewForRow(index, value, nil)
                            self.base.addArrangedSubview(view)
                        }
                        valuesCount = index
                    }
                    if valuesCount + 1 < viewsCount {
                        for index in valuesCount + 1 ..< viewsCount {
                            // remove extra views if necessary
                            self.base.removeArrangedSubview(views[index])
                            views[index].removeFromSuperview()
                        }
                    }
                case .error(let error):
                    fatalError("Errors can't be allowed: \(error)")
                case .completed:
                    break
                }
            }
        }
    }
}

上面可以这样使用:

self.stackFeature.axis = .vertical
self.stackFeature.distribution = .fill
self.stackFeature.spacing = 8

let features = NetworkAdapter.instance.getFeaturesAmeneities()
    .map { $0.data }
    .share(replay: 1)

features
    .bind(onNext: { [weak self] in self?.features.append(contentsOf: $0) })
    .disposed(by: disposeBag)

features
    .bind(to: stackFeature.rx.items) { (row, element, view) in
        let myView = (view as? CheckboxStackView) ?? CheckboxStackView()
        myView.label.text = element.name
        myView.checkBox.tag = element.id ?? 0
        return myView
    }
    .disposed(by: disposeBag)

这篇关于在 Stackview 中设置项目的 id的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆