合并发布者以更改 UIStackView 的排列子视图数组



我有一个基本的视图控制器子类,它包含一个UIStackView和一个UIButton。我想运行一些代码,每次从堆栈视图的arrangedSubviews数组使用组合添加或删除视图。这是我失败的尝试:

import Combine
import UIKit
class ViewController: UIViewController {
@IBOutlet var stackView: UIStackView!
@IBOutlet var button: UIButton!
var cancelables = Set<AnyCancellable>()
override func viewDidLoad() {
super.viewDidLoad()
stackView.publisher(for: .arrangedSubviews).sink { views in
button.isEnabled = views.count < 5
}
.store(in: &cancelables)
}
@IBAction func addTapped(_ sender: UIButton) {
let customView = CustomView()
stackView.addArrangedSubview(customView)
}
}

每次我点击按钮,一个新的视图被添加到堆栈视图,但对arrangedSubviews的更改没有发布,这不会触发sink块中的代码。在上述情况下,即使arrangedSubviews.count大于5,按钮仍然启用。

我如何解决这个问题,以便我可以正确地发布更改每当一个新的视图被添加或从arrangedSubviews数组删除?

谢谢你的帮助。

感谢Fabio Felici的评论,我猜UIStackView.arrangedSubviews不是kvo兼容的,这一定是导致我的尝试不工作的原因。

我设法以不同的方式处理这个问题,通过子类化UIStackView并添加Published计数器,该计数器包含每次调用插入和删除函数时arrangedSubviews.count的更新值。

class CountReactableStackView: UIStackView {
@Published var numberOfArrangedSubviews = 0

override func addArrangedSubview(_ view: UIView) {
super.addArrangedSubview(view)
numberOfArrangedSubviews = arrangedSubviews.count
}

override func removeArrangedSubview(_ view: UIView) {
super.removeArrangedSubview(view)
numberOfArrangedSubviews = arrangedSubviews.count
}

override func insertArrangedSubview(_ view: UIView, at stackIndex: Int) {
super.insertArrangedSubview(view, at: stackIndex)
numberOfArrangedSubviews = arrangedSubviews.count
}
}

然后订阅并响应numberOfArrangedSubviews

由于arrangedSubviews是只读的,只能通过上述函数更改,这个简单的解决方案回答了我的问题。我仍然很好奇是否有一种方法可以直接观察和响应arrangedSubviews的插入和删除。

最新更新