我有一个用于创建复选框的对象数组。该模型有一个ID,名称。我创建了一个 stackView 来处理带有 id 的复选框,现在我想将所选复选框的项目附加到一个数组,并能够在取消选择时删除它们。我能够呈现所有的观点并且效果很好
下面是我的代码
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)
感谢任何帮助
最佳答案
为了回答这个问题,我们首先必须使堆栈 View 具有反应性和声明性。这意味着我们必须能够使用单个赋值来设置 View ,并且它需要是一个观察者。这就像 RxCocoa 库为 UICollectionView、UITableView 和 UIPickerView 所做的一样。
写函数有点高级。首先,我们从上面的其他 View 中获取签名来定义函数的形状。
func items<Sequence: Swift.Sequence, Source: ObservableType>(_ source: Source) -> (_ viewForRow: @escaping (Int, Sequence.Element, UIView?) -> UIView) -> Disposable where Source.Element == Sequence
以上内容可能看起来令人生畏。它是一个函数,它接受序列的源序列并返回一个函数,该函数接受一个用于组装 View 的闭包并返回一个 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)
关于ios - 在 Stackview 中设置项目的 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57624344/