【问题标题】:How to bind array count to replace button image如何绑定数组计数以替换按钮图像
【发布时间】:2023-03-30 01:47:01
【问题描述】:

我正在尝试观察数组变化并将其绑定到按钮的图像。

如果数组为空。设置一个空购物车的图片。

其他设置购物车的图像。

所以我所做的是:

let x = itemsArray.observeNext { [weak self] (v) in
    let image = v.source.isEmpty ? #imageLiteral(resourceName: "emptyCart") : #imageLiteral(resourceName: "cart")
    self?.orderItemsButton.setImage(image, for: .normal)
}

但如果我确实使用这种方式,我必须在 viewWillDisappear 或类似的东西中处理 x...

正确的做法是什么?

【问题讨论】:

  • 这里的 itemsArray 是什么?
  • @TaimoorSuleman 数组

标签: ios swift rx-swift reactivekit


【解决方案1】:

我认为简单的方法可以是这样的

  var itemsArray: [Any] = [] {
        didSet {
            guard oldValue != itemsArray else { return }
            let image = itemsArray.isEmpty ? #imageLiteral(resourceName: "emptyCart") : #imageLiteral(resourceName: "cart")
            orderItemsButton.setImage(image, for: .normal)
        }
    }

每次你设置 itemsArray didSet 都会被调用,并在需要时更改 orderItemsButton 的图像。

编辑:

根据您在 cmets 中所说的,您可以使用委托

protocol CartDelegate: class {
    func setCartImage(isEmpty: Bool)
}


class ViewController: UIViewController, CartDelegate {

    var orderItemsButton: UIButton!
    var someRandomClass: SomeRandomClass!

    func setCartImage(isEmpty: Bool) {
        if isEmpty {
            // set image to empty cart
            orderItemsButton.setImage(nil, for: .normal)
        } else {
            // set image to full cart
            orderItemsButton.setImage(nil, for: .normal)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // initate and set delegate to self
        someRandomClass = SomeRandomClass()
        someRandomClass.delegate = self
    }
}


class SomeRandomClass {
    weak var delegate: CartDelegate?

    var itemsArray: [Any] = [] {
        didSet {
            delegate?.setCartImage(isEmpty: itemsArray.isEmpty)
        }
    }
}

【讨论】:

  • 问题是 itemsArray 在不同的类中声明..不在我的视图控制器中
  • @MarryG 那么你需要委托来解决这个问题。我会为你更新整个答案
【解决方案2】:

您可以用绑定替换观察。在这种情况下,一次性由框架本身(ReactiveKit)处理。

您需要做的就是:

itemsArray.bind(to: self) { me, array in
    let image = array.source.isEmpty ? #imageLiteral(resourceName: "emptyCart") : #imageLiteral(resourceName: "cart")
    me.orderItemsButton.setImage(image, for: .normal)
}

您可以在文档中找到有关绑定的更多信息: https://github.com/ReactiveKit/ReactiveKit#bindings

我几乎总是建议使用bind(to:) 而不是observeNext。它自动处理weak self,处理并确保对象在正确的线程上更新。


另外,您还可以通过将数组信号映射到图像信号然后将其绑定到按钮来解决此问题(假设您使用的是 ReactiveKit+Bond)。

itemsArray
  .map { $0.source.isEmpty ? #imageLiteral(resourceName: "emptyCart") : #imageLiteral(resourceName: "cart") }
  .bind(to: orderItemsButton.reactive.image)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    相关资源
    最近更新 更多