I have a UITableViewCell
that has a horizontal UIStackView
inside it. Creating and adding in the UIViews
to the stack view is causing a bit of a performance issue. There's a definite blip in the scrolling of the table view. I've profiled it in instruments and the call out to update the stack view is the second heaviest in the whole app.
The setup is as follows. I'm using MVP and in my presenter for the cell, I make a call out to updateStackView(with items: [Any])
when I setup the cell, and I setup the cell in the cellForRowAtIndexPath
method.
My original updateStackView(with items: [Any])
was as follows:
func updateStackView(_ items: [Any]) {
items.forEach { item in
if let customViewModel = item as? CustomViewModel {
myStackView.addArrangedSubview(CustomView(customViewModel))
} else if item is Spacing {
myStackView.addArrangedSubview(PipeSpacerView())
}
}
}
So this was the bottleneck, and I decided to move some stuff to the background as follows:
func updateStackView(_ items: [Any]) {
DispatchQueue.global(qos: .background).async {
items.forEach { item in
if let customViewModel = item as? CustomViewModel {
DispatchQueue.main.async {
self.myStackView.addArrangedSubview(CustomView(customViewModel))
}
} else if item is Spacing {
DispatchQueue.main.async {
self.myStackView.addArrangedSubview(PipeSpacerView())
}
}
}
}
}
Kinda ugly as it has some deep nesting, but made a big performance impact.
I was happy with this until I had scrolled down to the bottom of my table view and started scrolling back up. I noticed that some of the CustomViews
were in the stack view twice when the cell was being scrolled into view. Once the cell was fully in view the stack view corrected itself most of the time back to the correct number.
In my prepareForReuse
I do specifically make a call out to the following function:
func resetDescriptionStackView() {
descriptionStackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
}
which had always worked before fine was it was all on the main thread.
Any help greatly appreciated. I'm pretty certain it's a threading issue as it's only started to rear its head as I moved stuff to the background.