Почему функция в моем приложении iOS вызывается дважды? - PullRequest
0 голосов
/ 29 сентября 2018

Я сделал свое самое первое приложение для iOS.Но есть две досадные ошибки, от которых я не могу избавиться.Я надеюсь, что кто-нибудь может мне помочь!

Приложение должно обучаться читать музыкальные записи.Пользователь указывает свой инструмент и уровень (на предыдущем контроллере представления) и на основании этого он помещает случайные ноты в музыкальные записи на экране.Пользователь должен сопоставить эти заметки в текстовых полях, а приложение отслеживает оценку и повышает уровень после десяти правильных ответов.

Однако у меня почему-то возникают проблемы с функцией, которая генерирует случайные заметки.По какой-то причине функция вызывается дважды, при первом создании заметок, сохранении их в глобальной переменной и создании меток с заметками.Во второй раз он изменяет глобальную переменную, но не метки.На этот раз он возвращает следующее сообщение об ошибке: 2018-09-29 23:08:37.279170+0200 MyProject[57733:4748212] Warning: Attempt to present <MyProject.ThirdViewController: 0x7fc709125890> on <MyProject.SecondViewController: 0x7fc70900fcd0> whose view is not in the window hierarchy! Из-за этого пользователь отвечает на вопрос на экране, но приложение считает, что это неправильный ответ, поскольку у него хранится второй ответ.

ВторойКогда пользователь отвечает на вопрос, функция вызывается только один раз, но показания из текстовых полей не обновляются до новых значений, но остаются такими же, как и в первом вопросе.

Вот код, который дает проблемы:

import UIKit

class ThirdViewController: UIViewController
{

// snip

func setupLabels() {
    // snip
    // here the random notes are created, this is function is called multiple times for some reason
    let antwoord = Noten()
    let antwoordReturn = antwoord.generateNoten(instrument: instrument, ijkpunt: ijkpunt, aantalNoten: aantalNoten-1)
    let sleutel = antwoordReturn.0
    let heleOpgave = antwoordReturn.1
    print(heleOpgave)
    print(PassOpgave.shared.category)
    let heleOpgaveNummers = antwoordReturn.2
    // snip
    var a = 0
    while a < aantalNoten {
        // the labels are created, no problems there
        let myTekstveld = UITextField(frame: CGRect(x: labelX, y: labelY + 150, width: labelWidth, height: labelHeight / 2))
        myTekstveld.backgroundColor = UIColor.white
        myTekstveld.textAlignment = .center
        myTekstveld.placeholder = "?"
        myTekstveld.keyboardType = UIKeyboardType.default
        myTekstveld.borderStyle = UITextField.BorderStyle.line
        myTekstveld.autocorrectionType = .no
        myTekstveld.returnKeyType = UIReturnKeyType.done
        myTekstveld.textColor = UIColor.init(displayP3Red: CGFloat(96.0/255.0), green: CGFloat(35.0/255.0), blue: CGFloat(123.0/255.0), alpha: 1)
        myTekstveld.delegate = self as? UITextFieldDelegate
        myTekstveld.tag = a + 1
        view.addSubview(myTekstveld)

        a += 1
        labelX += labelWidth
    }

    // the button is created
}

override func viewDidLoad()
{
    super.viewDidLoad()
    // snip
    setupLabels()
}

@objc func buttonAction(sender: UIButton!) {
    // snip
    // here the text from the text fields is read, but this only works the first time the buttonAction is called, the next times, it simply returns the first user input.
    while a <= aantalNoten {
        if let theLabel = view.viewWithTag(a) as? UITextField {
            let tekstInput = theLabel.text!
            userInput.append(tekstInput)
        }
        a += 1
    }

    // snip 

    setupLabels()
    return
}

// snip

Ответы [ 3 ]

0 голосов
/ 30 сентября 2018

У вас есть два случая ThirdViewController, когда вы не хотите этого.

Эта ошибка очень показательна:

2018-09-29 23:08:37.279170+0200 MyProject[57733:4748212] Warning: Attempt to present <MyProject.ThirdViewController: 0x7fc709125890> on <MyProject.SecondViewController: 0x7fc70900fcd0> whose view is not in the window hierarchy!

Это говорит о том, что SecondViewController пытаетсясоздать ThirdViewController, когда SecondViewController даже не на экране.Это говорит о том, что ошибка в SecondViewController (возможно, наблюдение за уведомлениями или другими действиями, когда они не на экране).Конечно, возможно, что у вас также есть два экземпляра SecondViewController.

Я подозреваю, что вы пытаетесь собрать все это вручную, вместо того, чтобы раскадровки делали всю работу за вас.Это нормально, но такого рода ошибки в этом случае встречаются немного чаще.Лучший способ отладить это далее - установить несколько точек останова и тщательно проверить адрес объектов (например, 0x7fc709125890).Вам нужно будет выследить, где вы создаете дополнительный.

0 голосов
/ 30 сентября 2018

Мне удалось частично решить мою вторую проблему (что показания текстовых полей не обновлялись до второго ответа), не создавая их снова.Я добавил код в функцию setupLabels, чтобы создавать текстовые поля, только если они еще не были введены:

let myTekstveld = UITextField()
if (view.viewWithTag(a+1) as? UITextField) != nil {  
}
else {
myTekstveld.frame = CGRect(x: labelX, y: labelY + 100, width: labelWidth, height: labelHeight / 2)
// snip
myTekstveld.tag = a + 1
view.addSubview(myTekstveld)
}

Приложение работает, как и ожидалось, единственная проблема заключается в том, что текстовые поля не очищаются после каждого вопроса.

0 голосов
/ 29 сентября 2018

Ваш genreteNoten метод вызывается несколько раз, потому что он вызывается из setupLabels , который в свою очередь вызывается из viewDidLoad .

viewDidLoad может вызываться несколько раз, и ваш код должен это учитывать.Как сказано в , этот ответ на аналогичный вопрос:

Если у вас есть код, который нужно запустить только один раз для вашего контроллера, используйте -awakeFromNib.

...