当其中一个属性发生更改时,侦听数据模型数组中的更新

时间:2017-09-25 11:54:41

标签: ios swift didset property-observer

我有一个自定义UITableViewCell,它有一个数据模型数组,UILabel就是这样:

class ItemCustomizationCollectionViewCell: UITableViewCell {

    var customizationData: CustomizationData?

    let priceLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont.boldSystemFont(ofSize: 18)
        label.textAlignment = .left
        label.textColor = UIColor.gray
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }() 

    //other init and constraints
}

现在,CustomizationData如下所示:

class CustomizationData {
    let title: String
    var customizationOptions: [PickerOption]
    var choosenOption: PickerOption?

    init(title: String, customizationOptions: [PickerOption], choosenOption: PickerOption?) {
        self.title = title
        self.customizationOptions = customizationOptions
        self.choosenOption = choosenOption
    }
}

并且PickerOption是:

class PickerOption {
    let title: String
    let price: String

    init(title: String, price: String) {
        self.title = title
        self.price = price
    }
}

我的问题是:

我想收听customizationData的selectosenOption设置,并获取标题以将UILabel的文本更改为choosenOption的价格。

我尝试将didSet添加到customizationData,但由于其中一个属性正在更改,因此未调用它。不是customizationData本身。

2 个答案:

答案 0 :(得分:1)

你可以做什么,但要触发一个didSet customizationOptions,你需要改变它的值,基本上有两种方式:

  • 如果customizationOptions是参考类型,则需要使用其他参考
  • 进行更改
  • 如果customizationOptions是值类型,例如Array,则如果更改其中的值,也应调用didSet,因为数组会完全更改结构。

为了更好地理解这里是一个例子 使用值类型:

class Mine {
    var list: [String] = ["Hello"] {
        didSet {
            print("Array changed \(list)")
        }
    }
}

var mine = Mine()

mine.list.append("World") //Array changed ["Hello", "World"]

使用引用类型:

class Mine {
    var list: NSArray = ["Hello"] {
        didSet {
            print("Array changed \(list)")
        }
    }
}

var mine = Mine()
mine.list.adding("World")
 //Doesn't print nothing
mine.list = ["World"]
//print World

答案 1 :(得分:0)

我认为你可以使用委托来做到这一点。创建CustomizationDataDelegate协议:

protocol CustomizationDataDelegate {
    func choosenOptionDidChange(to newValue: PickerOption)
}

然后在CustomizationData类中创建一个委托属性,例如:

internal var delegate : CustomizationDataDelegate?

并添加一个didSet给choosenOption:

var choosenOption : PickerOption? {
    didSet{
           if let _ = choosenOption {
              delegate?.choosenOptionDidChange(to choosenOption!)
         }
    }
}

然后将ItemCustomizationCollectionViewCell注册到CustomizationDataDelegate协议,然后当您有一些自定义数据时,请确保将委托设置为单元格的值:

class ItemCustomizationCollectionViewCell: UITableViewCell, CustomizationDataDelegate {

    var customizationData: CustomizationData? {
        didSet {

            if let _ = customizationData {
                if let _ = customizationData!.choosenOption {
                    // You need this in case the choosenOption has already been set
                    choosenOptionDidChange(to: customizationData!.choosenOption)
                }

                // You need this to listen for future changes
                customizationData!.delegate = self
            }
        }
    }

    let priceLabel: UILabel = {
    // ...

    // In your class' function declarations...

    //# MARK:- CustomizationDataDelegate methods 

    func choosenOptionDidChange(to newValue: PickerOption) -> Void {
        // Update the label's value here based on newValue
    }
}

希望有所帮助。