在 Stackview 中设置项目的 ID
Posted
技术标签:
【中文标题】在 Stackview 中设置项目的 ID【英文标题】:setting ids on item in Stackview 【发布时间】:2019-08-23 10:24:14 【问题描述】:我有一个用于创建复选框的对象数组。该模型有一个 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)
感谢任何帮助
【问题讨论】:
【参考方案1】:为了回答这个问题,我们首先必须使堆栈视图具有反应性和声明性。这意味着我们必须能够使用单个分配设置视图,并且需要成为观察者。这就像 RxCocoa 库对 UICollectionView、UITableView 和 UIPickerView 所做的一样。
编写函数有点高级。首先,我们从上面的其他视图中获取签名来定义函数的形状。
func items<Sequence: Swift.Sequence, Source: ObservableType>(_ source: Source) -> (_ viewForRow: @escaping (Int, Sequence.Element, UIView?) -> UIView) -> Disposable where Source.Element == Sequence
以上内容可能看起来令人生畏。它是一个函数,它接受序列的源序列并返回一个函数,该函数接受一个用于组装视图的闭包并返回一个 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)
【讨论】:
您好,感谢您的回复。我收到以下错误Generic parameter 'Sequence' is not used in function signature
和 'Element' is not a member type of 'Source'
听起来您缺少where
子句。将我的代码复制/粘贴到您的项目中。
我就是这么做的
同样的事情***.com/questions/57646978/…
收到新错误Cannot convert value of type '(_) -> (@escaping (Int, _.Element, UIView?) -> UIView) -> Disposable' to expected argument type '(Observable<[LandMarkData]?>) -> (_) -> _'
以上是关于在 Stackview 中设置项目的 ID的主要内容,如果未能解决你的问题,请参考以下文章