Reputation: 890
I have encountered strange behavior of UIViews. I have an empty 'container' UIView - WaveformPlot that is expected to be filled with child subviews.
class WaveformPlot: UIView {
var normalColor: UIColor?
var progressColor: UIColor?
var waveforms: [UIView]?
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
waveforms = []
}
//MARK: Populate plot with data
func populateWithData(from dataSet: [Float]){
DispatchQueue.main.async {
var offset: CGFloat = 0
for index in 0..<dataSet.count {
let barView = UIView(frame: CGRect(x: offset,
y: self.frame.height / 2,
width: self.frame.width / CGFloat(dataSet.count),
height: -(CGFloat)((dataSet[index]))))
barView.backgroundColor = self.normalColor
barView.layer.borderColor = UIColor.black.cgColor
barView.layer.borderWidth = 0.25
//Append barView to parent 'container' view
self.addSubview(barView)
//Append barView to an array for future processing
self.waveforms?.append(barView)
offset += self.frame.width / CGFloat(dataSet.count)
}
}
}
func updateColorOfBars(with currentTime: Double, of totalDuration: Double){
let percentagePlayed = currentTime / totalDuration
print("Percerntage played - \((percentagePlayed * 100) / 100)")
let quantityOfBarsToBeUpdated = Double((self.waveforms?.count)!) * percentagePlayed
for item in self.waveforms!{
if (self.waveforms?.index(of: item)!)! <= Int(quantityOfBarsToBeUpdated * percentagePlayed) {
print("index processing - \(self.waveforms?.index(of: item))")
item.backgroundColor = self.progressColor
}
}
}
func clearPlot(){
for item in self.subviews{
item.removeFromSuperview()
}
}
}
Then I initiate this WaveformPlot in ViewController with 64 values in "data" [Float] array:
class ViewController: UIViewController {
var data: [Float] = [13, 37, 2, 3, 64, 62, 31, 50, 60, 17, 48, 56, 24, 25, 45, 8, 32, 1, 39, 26, 42, 10, 4, 27, 51, 40, 11, 12, 35, 41, 46, 21, 55, 36, 20, 14, 34, 47, 6, 9, 5, 59, 30, 54, 23, 49, 19, 0, 58, 61, 57, 28, 29, 15, 44, 16, 63, 18, 22, 43, 7, 33, 53, 38]
@IBOutlet weak var waveformView: WaveformPlot!
@IBOutlet weak var playButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidLayoutSubviews() {
waveformView.normalColor = UIColor.blue
waveformView.progressColor = UIColor.orange
waveformView.populateWithData(from: data)
}
}
This results in this ->
But during visual debugging I have discovered that there are 128 views instead of 64. Under each barView there is another bar. Details on this screenshot.
Please help me deal with this issue. Why additional bar is being attached during original one?
Upvotes: 0
Views: 43
Reputation: 4735
viewDidLayoutSubviews
will be called as many times as is appropriate.
You are create the bars every time it is called.
You should iterate over the views and remove them before create new ones:
for view in waveForms {
view.removeFromSuperview.
}
self.waveForms.removeAll()
Upvotes: 1