When I used FlexLayout to set constraints for a UITableViewCell, I removed the dataSource of a UITableView and then refreshed the UITableView, which caused a crash. The version of FlexLayout is 2.0.10, and I wonder if this issue is related to YogaKit.
I have obtained the following error log.
terminating due to uncaught exception of type std::logic_error: Cannot set measure function: Nodes with measure functions cannot have children.
Could you share a reproducible project or code?
I fixed it. The reason was that I called markdirty after dynamically adding a view to a container.
But I think it's difficult to locate and resolve the issue this way. Could it be more specific?
Finally, I just commented out ”flex.markDirty()” and that worked.
self.insuranceContainer.subviews.forEach({$0.removeFromSuperview()})
self.insuranceContainer.flex.define { flex in
details.forEach { info in
let label = YYLabel().then {
$0.numberOfLines = 0
$0.font = 12.design.font()
$0.lineHeight = 18.design
}
label.setText(info)
flex.addItem().direction(.row).justifyContent(.start).alignItems(.start).define { flex in
flex.addItem(UIImageView(image: UIImage(named: "icons_16pt_insurance_checked"))).size(CGSize(width: 16.design, height: 16.design)).marginTop(1.design)
flex.addItem(label).grow(1)
}
}
}
// self.insuranceContainer.flex.markDirty()
class TestView: UIView {
override init(frame: CGRect) {
super.init(frame: .zero)
self.flex.addItem(UIView())
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.subviews.forEach {
$0.removeFromSuperview()
}
self.flex.markDirty()
}
}
}
In the code above, while YogaKit's markDirty handling is possible, it seems that an error occurs in Yoga setMeasureFunc because the child nodes are not empty.
I think the YogaKit logic needs to be changed to be a bit more safe.
The current options are to either
remove the container’s flex markDirty, or
call flex.layout() when the view changes dynamically (which updates the Node tree based on the current UIView hierarchy).
self.subviews.forEach {
$0.removeFromSuperview()
}
self.flex.layout()
self.flex.markDirty()