在 addSubview 期间奇怪的重复 UIView

Posted

技术标签:

【中文标题】在 addSubview 期间奇怪的重复 UIView【英文标题】:Strange duplicating UIView during addSubview 【发布时间】:2017-03-18 11:11:13 【问题描述】:

我遇到了 UIViews 的奇怪行为。我有一个空的“容器”UIView - WaveformPlot 预计将填充子子视图。

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()
      
    
  
  

然后我在 ViewController 中使用“data”[Float] 数组中的 64 个值启动此 WaveformPlot:

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)
    
  

这会导致这个 ->

但在可视化调试过程中,我发现有 128 个视图而不是 64 个。每个 barView 下还有另一个 bar。 此屏幕截图的详细信息。

请帮我解决这个问题。为什么在原来的时候要附加额外的酒吧?

【问题讨论】:

viewDidLayoutSubviews 可能会被多次调用。您应该在添加新视图之前删除现有视图,或者检查它们是否已添加。 【参考方案1】:

viewDidLayoutSubviews 将被调用多次。 每次调用它时,您都会创建条形图。 您应该在创建新视图之前迭代视图并删除它们:

for view in waveForms view.removeFromSuperview. self.waveForms.removeAll()

【讨论】:

以上是关于在 addSubview 期间奇怪的重复 UIView的主要内容,如果未能解决你的问题,请参考以下文章

[self.view addSubview:myView.view];奇怪的行为

如果在 addSubView 之后调用 UIButton 不会移动

未收到 addSubview 通知

UIPickerView 自定义视图奇怪的行为

视差映射期间奇怪的分层效果

使用带有径向渐变的 CAGradientLayer 时出现奇怪的渐变。