При добавлении подпредставлений в al oop отображаются все подвиды одновременно. - PullRequest
0 голосов
/ 06 марта 2020

Я пытаюсь добавить 1000 ярлыков пользовательского интерфейса одним нажатием кнопки, но зацикливаюсь 1000 раз и создаю 1000 ярлыков пользовательского интерфейса

    @IBAction func display(_ sender: Any) {
      for i in Range(1...1000) {

                      let label =  self.displayLabel(str: "test \(i)",i: i)

                                        )
                        UIView.animate(withDuration: 2.0, delay: 1.0, options: UIView.AnimationOptions.transitionCrossDissolve,animations: {
                            self.view.addSubview(label)
                            label.alpha = 1.0;
                         label.center.y = self.view.center.y/3},
                                       completion: { (value) in label.removeFromSuperview()} )



                      }

}

И функция displayLabel -

    func displayLabel(str:String,i:Int) -> UILabel {

    let label = UILabel.init(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
    label.tag = i

    label.font = UIFont.preferredFont(forTextStyle: .footnote)
    let screenWidth = self.view.frame.size.width
    let screenHeight = self.view.frame.size.height
    label.textColor = .black
    label.center = CGPoint(x: screenWidth * 0.75, y: screenHeight - (screenHeight/3.0))
    label.textAlignment = .center
    label.text = str
    label.backgroundColor = .white
    label.backgroundColor?.withAlphaComponent(0.5)
    return label


}

Что ожидается?

на экранах отображаются метки один за другим, они движутся вверх и исчезают.

Что на самом деле происходит

Все ярлыки добавляются одновременно, а затем они начинают анимацию, делая ярлык с номером 1000 анимированным и исчезают.

Почему вы думаете, что это происходит?

Это из-за тег или почему он ждет все 1000 ярлыков и добавляет его в подпредставление?

Как мне добиться того, чего я хочу?.

Ответы [ 2 ]

1 голос
/ 06 марта 2020

Согласно вашему коду, это ожидаемое поведение, поскольку вы удаляете объект метки в обработчике completion, а это закрытие @escaping.

Это означает, что выполнение не будет ждать removeFromSuperview , Он будет выполнять операцию addSubview и, не дожидаясь обработчика completion, будет двигаться дальше.

Такое поведение можно проверить, добавив операторы print до и после обработчика completion.

Теперь о вашем требовании можно выполнить следующим образом:

Объявить переменную для хранения метки тега

var tag = 0

Избегайте l oop и используйте здесь рекурсивную функцию, например

  //function to add and remove label until the defined count reached
  func showLabel(withTag: Int) {
    if self.tag != 1000 {
      let label =  self.displayLabel(str: "test \(withTag)",i: withTag)
      UIView.animate(withDuration: 2.0,
                     delay: 1.0,
                     options: UIView.AnimationOptions.transitionCrossDissolve,
                     animations: {
                      self.view.addSubview(label)
                      label.alpha = 1.0;
                      label.center.y = self.view.center.y/3
      }) { (value) in
        label.removeFromSuperview()
        self.tag = self.tag + 1
        self.showLabel(withTag: self.tag)
      }
    }
  }

  //initial function to start the process for each label
  func display() {
    showLabel(withTag: tag)
  }

  //function to provide new label object
  //no changes here
  func displayLabel(str:String,i:Int) -> UILabel {
    let label = UILabel.init(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
    label.tag = i
    label.font = UIFont.preferredFont(forTextStyle: .footnote)
    let screenWidth = self.view.frame.size.width
    let screenHeight = self.view.frame.size.height
    label.textColor = .black
    label.center = CGPoint(x: screenWidth * 0.75, y: screenHeight - (screenHeight/3.0))
    label.textAlignment = .center
    label.text = str
    label.backgroundColor = .white
    label.backgroundColor?.withAlphaComponent(0.5)
    return label
  }
0 голосов
/ 06 марта 2020

Вы должны размещать подпредставления после каждого .addSubview. Поэтому попробуйте сделать это:

UIView.animate(withDuration: 2.0, delay: 1.0, options: UIView.AnimationOptions.transitionCrossDissolve,animations: {
                        self.view.addSubview(label)
                        label.alpha = 1.0;
                        label.center.y = self.view.center.y/3
                        self.view.layoutSubviews() }
...