(UILabel) ноль, невозможно вставить текст в метку - PullRequest
0 голосов
/ 26 августа 2018

Добрый день,

Кажется, у меня такая простая проблема, но я просто не могу обернуть голову вокруг нее.

У меня есть вид контейнера внутри контроллера вида. В этом контейнере у меня мало этикеток. Контейнер имеет свой собственный контроллер вида. В контроллере представления для контейнера у меня работает таймер, и я хочу, чтобы эта метка показывала таймер. Но каждый раз, когда я использую этот ярлык, приложение вылетает с «Поток 1: неустранимая ошибка: неожиданно обнаружен ноль при развертывании необязательного значения»

Если я прокомментирую строку с этим ярлыком, то все будет нормально.

    @IBOutlet weak var timeLabel: UILabel!

var counter = 0.0
var timer = Timer()
var isRunning = false


func startStopTimer () {
    if isRunning {
        timer.invalidate()
        isRunning = false
    }else {
        timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true)
        isRunning = true
    }
}

@objc func updateTimer() {
    counter = counter + 0.1

    timeLabel.text = String(counter) 
}

Это первый раз, когда я играю с видом контейнера в Главной раскадровке.

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

Спасибо Jonas


Полный код

    class MainViewController: UIViewController {
@IBOutlet weak var topContainer: UIView!
@IBOutlet weak var informationContainer: UIView!

@IBOutlet weak var startStopButtonOutlet: UIButton!

let informationContainerVC = InformationContainerViewController()

override func viewDidLoad() {
    super.viewDidLoad()

    setupView()
}

func setupView() {
    topContainer.layer.cornerRadius = 5
    topContainer.layer.masksToBounds = true

    informationContainer.layer.cornerRadius = 5
    informationContainer.layer.masksToBounds = true

    startStopButtonOutlet.layer.cornerRadius = 5
    startStopButtonOutlet.layer.masksToBounds = true
}

@IBAction func startStopButton_TouchUpInside(_ sender: UIButton) {
    informationContainerVC.startStopTimer()

    UIButton.animate(withDuration: 0.1, delay: 0.0, options: [.allowUserInteraction, .curveEaseOut], animations: {
        sender.transform = CGAffineTransform.identity

    }, completion: nil)

    if informationContainerVC.isRunning {
        startStopButtonOutlet.setTitle("Push to Pause", for: .normal)
    }else {
        startStopButtonOutlet.setTitle("Push to Start", for: .normal)
    }
}

@IBAction func startStopButton_TouchDown(_ sender: UIButton) {
    UIButton.animate(withDuration: 0.1, delay: 0.0, options: [.allowUserInteraction, .curveEaseIn], animations: {
        sender.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)

        if self.informationContainerVC.isRunning {

            sender.backgroundColor = UIColor.white.withAlphaComponent(0.5)
        }else {
            sender.backgroundColor = UIColor.green.withAlphaComponent(0.8)
        }



    }, completion: nil)
}

@IBAction func startStopButton_TouchUpOutside(_ sender: UIButton) {
    UIButton.animate(withDuration: 0.1, delay: 0.0, options: [.allowUserInteraction, .curveEaseOut], animations: {
        sender.transform = CGAffineTransform.identity

    }, completion: nil)
}
}

Вот код контроллера контейнера

class InformationContainerViewController: UIViewController {

@IBOutlet weak var timeLabel: UILabel!

var counter = 0.0
var timer = Timer()
var isRunning = false


func startStopTimer () {
    if isRunning {
        timer.invalidate()
        isRunning = false
    }else {
        timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true)
        isRunning = true
    }
}

@objc func updateTimer() {
    counter = counter + 0.1

    timeLabel.text = String(counter)

}
}

1 Ответ

0 голосов
/ 26 августа 2018

Когда вы говорите let informationContainerVC = InformationContainerViewController(), вы создаете новый экземпляр InformationContainerViewController, который не связан с раскадровкой, поэтому ни один из выходов не установлен.

Вам необходимо получить ссылку на представлениеэкземпляр контроллера, который на самом деле находится в вашем контейнере.Вы можете сделать это в prepare(for segue:);Если вы посмотрите на свою раскадровку, то увидите, что существует переход для встраивания, который связывает ваш содержащий контроллер представления с содержащимся в нем контроллером представления.

В вашем MainViewController:

var informationContainerVC: InformationContainerViewController?

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if let destVC = segue.destination as? InformationContainerViewController {
        self.informationContainerVC = destVC
    }
}

@IBAction func startStopButton_TouchUpInside(_ sender: UIButton) {
    informationContainerVC?.startStopTimer()

    UIButton.animate(withDuration: 0.1, delay: 0.0, options: [.allowUserInteraction, .curveEaseOut], animations: {
        sender.transform = CGAffineTransform.identity

    }, completion: nil)

    if informationContainerVC?.isRunning {
        startStopButtonOutlet.setTitle("Push to Pause", for: .normal)
    } else {
        startStopButtonOutlet.setTitle("Push to Start", for: .normal)
    }
}

Теперь у вас будетссылка на правильный экземпляр контроллера вида

...