Reputation: 2513
I have a custom UITableViewCell
which has a data model array, and a UILabel
as this:
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
}
Now, the CustomizationData looks like this:
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
}
}
and the PickerOption is:
class PickerOption {
let title: String
let price: String
init(title: String, price: String) {
self.title = title
self.price = price
}
}
My Question is:
I want to listen to customizationData's choosenOption gets set, and get the title to change the UILabel
's text to the choosenOption's price.
I tried to add a didSet to the customizationData but it's not being called as one of its properties is changing. Not the customizationData itself.
Upvotes: 0
Views: 378
Reputation: 2321
I think you can do this using delegation. Create a CustomizationDataDelegate protocol:
protocol CustomizationDataDelegate {
func choosenOptionDidChange(to newValue: PickerOption)
}
Then create a delegate property in the CustomizationData class, for instance:
internal var delegate : CustomizationDataDelegate?
And add a didSet to choosenOption:
var choosenOption : PickerOption? {
didSet{
if let _ = choosenOption {
delegate?.choosenOptionDidChange(to choosenOption!)
}
}
}
Then register the ItemCustomizationCollectionViewCell to the CustomizationDataDelegate protocol, and then when you have some customization data, make sure the delegate is set to the cell's value:
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
}
}
Hope that helps.
Upvotes: 0
Reputation: 26385
What you can do is possible, but to trigger a didSet customizationOptions
of you need to change its value, basically in 2 ways:
customizationOptions
is a reference type, you need to change it with another referencecustomizationOptions
is a value type such as an Array
, the didSet should be called also if you change a value inside it, because the array change the struct completely.To understand better here is an example.
Using a value type:
class Mine {
var list: [String] = ["Hello"] {
didSet {
print("Array changed \(list)")
}
}
}
var mine = Mine()
mine.list.append("World") //Array changed ["Hello", "World"]
Using a reference type:
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
Upvotes: 1