2017-09-04 79 views
0

我得到一个索引超出界限的错误,但我不明白为什么。代码编译正常,但出现错误在以下行(动画):UIView动画方法的索引超出界限错误

import UIKit 

class MenuViewController: UIViewController { 

    private let contentView = UIView() 
    private let logoView = UIImageView() 
    private let buttonView = UIView() 
    private var gameButtons = [RoundedButton]() 
    private let scoreView = UIView() 
    private let titleLabel = UILabel() 
    private let recentScoreLabel = UILabel() 
    private let highscoreLabel = UILabel() 

    private let titles = [ 
     "Multiple Choice", 
     "Image Quiz", 
     "Right or wrong", 
     "Emoji Riddle" 

    ] 

    private var recentScores = [Int]() 
    private var highscores = [Int]() 
    private var scoreIndex = 0 
    private var timer = Timer() 

    private var midXConstraints: [NSLayoutConstraint]! 
    private var leftConstraints: [NSLayoutConstraint]! 
    private var rightConstraints: [NSLayoutConstraint]! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     navigationController?.navigationBar.barStyle = .blackTranslucent 
     navigationController?.navigationBar.tintColor = UIColor.white 
     view.backgroundColor = UIColor(red: 41/255, green: 128/255, blue: 185/255, alpha: 1.0) 
     layoutView() 
    } 

    override func viewWillAppear(_ animated: Bool) { 
     navigationController?.navigationBar.isHidden = true 
    } 

    func updateScores() { 
     recentScores = [ 
      UserDefaults.standard.integer(forKey: multipleChoiceRecentscoreIdentifier), 
      UserDefaults.standard.integer(forKey: imageQuizRecentscoreIdentifier), 
      UserDefaults.standard.integer(forKey: rightWrongRecentscoreIdentifier), 
      UserDefaults.standard.integer(forKey: emojiRecentscoreIdentifier) 
     ] 

     highscores = [ 
      UserDefaults.standard.integer(forKey: multipleChoiceHighScoreIdentifier), 
      UserDefaults.standard.integer(forKey: imageQuizHighScoreIdentifier), 
      UserDefaults.standard.integer(forKey: rightWrongHighscoreIdentifier), 
      UserDefaults.standard.integer(forKey: emojiHighscoreIdentifier) 
     ] 
    } 

    func layoutView() { 
     contentView.translatesAutoresizingMaskIntoConstraints = false 
     view.addSubview(contentView) 

     logoView.translatesAutoresizingMaskIntoConstraints = false 
     contentView.addSubview(logoView) 
     logoView.image = UIImage(named: "logo") 

     buttonView.translatesAutoresizingMaskIntoConstraints = false 
     contentView.addSubview(buttonView) 

     for (index,title) in titles.enumerated() { 
      let button = RoundedButton() 
      button.translatesAutoresizingMaskIntoConstraints = false 
      buttonView.addSubview(button) 
      button.backgroundColor = UIColor(red: 52/255, green: 152/255, blue: 219/255, alpha: 1.0) 
      button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20) 
      button.setTitle(title, for: .normal) 
      button.tag = index 
      gameButtons.append(button) 
     } 

     scoreView.translatesAutoresizingMaskIntoConstraints = false 
     contentView.addSubview(scoreView) 

     titleLabel.translatesAutoresizingMaskIntoConstraints = false 
     recentScoreLabel.translatesAutoresizingMaskIntoConstraints = false 
     highscoreLabel.translatesAutoresizingMaskIntoConstraints = false 
     scoreView.addSubview(titleLabel) 
     scoreView.addSubview(recentScoreLabel) 
     scoreView.addSubview(highscoreLabel) 

     titleLabel.textAlignment = .center 
     titleLabel.font = UIFont.boldSystemFont(ofSize: 30) 
     titleLabel.textColor = UIColor.white 
     recentScoreLabel.textColor = UIColor.white 
     highscoreLabel.font = UIFont.boldSystemFont(ofSize: 20) 
     highscoreLabel.textColor = UIColor.white 

     titleLabel.text = titles[scoreIndex] 
     recentScoreLabel.text = "Recent: " + String(UserDefaults.standard.integer(forKey: multipleChoiceRecentscoreIdentifier)) 
     highscoreLabel.text = "Highscore: " + String(UserDefaults.standard.integer(forKey: multipleChoiceHighScoreIdentifier)) 

     let constraints = [ 
      contentView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: 8.0), 
      contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor), 
      contentView.trailingAnchor.constraint(equalTo: view.trailingAnchor), 
      contentView.bottomAnchor.constraint(equalTo: view.bottomAnchor), 
      logoView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 20.0), 
      logoView.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.6), 
      logoView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor), 
      logoView.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: 0.2), 
      buttonView.topAnchor.constraint(equalTo: logoView.bottomAnchor, constant: 20.0), 
      buttonView.bottomAnchor.constraint(equalTo: scoreView.topAnchor, constant: -20.0), 
      buttonView.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.6), 
      buttonView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor), 
      gameButtons[0].topAnchor.constraint(equalTo: buttonView.topAnchor, constant: 8.0), 
      gameButtons[0].bottomAnchor.constraint(equalTo: gameButtons[1].topAnchor, constant: -8.0), 
      gameButtons[0].leadingAnchor.constraint(equalTo: buttonView.leadingAnchor), 
      gameButtons[0].trailingAnchor.constraint(equalTo: buttonView.trailingAnchor), 
      gameButtons[1].bottomAnchor.constraint(equalTo: gameButtons[2].topAnchor, constant: -8.0), 
      gameButtons[1].leadingAnchor.constraint(equalTo: buttonView.leadingAnchor), 
      gameButtons[1].trailingAnchor.constraint(equalTo: buttonView.trailingAnchor), 
      gameButtons[2].bottomAnchor.constraint(equalTo: gameButtons[3].topAnchor, constant: -8.0), 
      gameButtons[2].leadingAnchor.constraint(equalTo: buttonView.leadingAnchor), 
      gameButtons[2].trailingAnchor.constraint(equalTo: buttonView.trailingAnchor), 
      gameButtons[3].bottomAnchor.constraint(equalTo: buttonView.bottomAnchor, constant: -8.0), 
      gameButtons[3].leadingAnchor.constraint(equalTo: buttonView.leadingAnchor), 
      gameButtons[3].trailingAnchor.constraint(equalTo: buttonView.trailingAnchor), 
      gameButtons[0].heightAnchor.constraint(equalTo: gameButtons[1].heightAnchor), 
      gameButtons[1].heightAnchor.constraint(equalTo: gameButtons[2].heightAnchor), 
      gameButtons[2].heightAnchor.constraint(equalTo: gameButtons[3].heightAnchor), 
      scoreView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -40.0), 
      scoreView.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.6), 
      scoreView.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: 0.3), 
      titleLabel.topAnchor.constraint(equalTo: scoreView.topAnchor, constant: 8.0), 
      titleLabel.leadingAnchor.constraint(equalTo: scoreView.leadingAnchor), 
      titleLabel.trailingAnchor.constraint(equalTo: scoreView.trailingAnchor), 
      titleLabel.bottomAnchor.constraint(equalTo: recentScoreLabel.topAnchor, constant: -8.0), 
      recentScoreLabel.leadingAnchor.constraint(equalTo: scoreView.leadingAnchor), 
      recentScoreLabel.trailingAnchor.constraint(equalTo: scoreView.trailingAnchor), 
      recentScoreLabel.bottomAnchor.constraint(equalTo: highscoreLabel.topAnchor, constant: -8.0), 
      highscoreLabel.leadingAnchor.constraint(equalTo: scoreView.leadingAnchor), 
      highscoreLabel.trailingAnchor.constraint(equalTo: scoreView.trailingAnchor), 
      highscoreLabel.bottomAnchor.constraint(equalTo: scoreView.bottomAnchor, constant: -8.0), 
      titleLabel.heightAnchor.constraint(equalTo: recentScoreLabel.heightAnchor), 
      recentScoreLabel.heightAnchor.constraint(equalTo: highscoreLabel.heightAnchor) 
     ] 

     midXConstraints = [scoreView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor)] 
     leftConstraints = [scoreView.trailingAnchor.constraint(equalTo: contentView.leadingAnchor)] 
     rightConstraints = [scoreView.leadingAnchor.constraint(equalTo: contentView.trailingAnchor)] 

     NSLayoutConstraint.activate(constraints) 
     NSLayoutConstraint.activate(midXConstraints) 

     timer = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(nextScores), userInfo: nil, repeats: true) 
    } 

    func nextScores() { 
     scoreIndex = scoreIndex < (recentScores.count - 1) ? scoreIndex + 1 : 0 
     UIView.animate(withDuration: 1.0, animations: { 
      NSLayoutConstraint.deactivate(self.midXConstraints) 
      NSLayoutConstraint.activate(self.leftConstraints) 
      self.view.layoutIfNeeded() 
     }) {(completion: Bool) in 
      self.titleLabel.text = self.titles[self.scoreIndex] 
      self.recentScoreLabel.text = "Recent: " + String(self.recentScores[self.scoreIndex]) //Index out of bounds error appears here 
      self.highscoreLabel.text = "Highscore: " + String(self.highscores[self.scoreIndex]) 
      NSLayoutConstraint.deactivate(self.leftConstraints) 
      NSLayoutConstraint.activate(self.rightConstraints) 
      self.view.layoutIfNeeded() 
      UIView.animate(withDuration: 1.0, animations: { 
       NSLayoutConstraint.deactivate(self.rightConstraints) 
       NSLayoutConstraint.activate(self.midXConstraints) 
       self.view.layoutIfNeeded() 
      }) 
     } 
    } 



} 
+0

错误告诉你问题是什么。为什么不记录你的调用索引和self.recentscores上的可用最大索引来简单地看到你正在调用一个outofbound索引? – 2017-09-04 21:58:25

回答

1

的recentScores为空数组,即它具有0个元素,和你正在试图访问它的第一个元素。你不要追加任何元素到这个数组中。这就是为什么你得到“索引超出界限”的错误。

0

请试试这个:

self.recentScores计数为0,并且您试图访问self.recentScores[0]

if self.recentScores.count > 0 { 
    self.recentScoreLabel.text = "Recent: " + String(self.recentScores[self.scoreIndex]) //Index out of bounds error appears here 
} 
if self.highscores.count > 0 { 
    self.highscoreLabel.text = "Highscore: " + String(self.highscores[self.scoreIndex]) 
}