0

I have different arrays, they store a different number of elements, at the click of a button the index of the array is increased by 1 and the element is added to another array, I did an array range check, but it does not work. what could be the problem

xCode console: Fatal error: Index out of range: file

class ViewController: UIViewController {
    var currentIndex = 0
    var arrayIndex = -1
    var arrayWords: [Words]?  {
        didSet {
            //            wordTextLabel.text = arrayWords?[0].arrayWords?[currentIndex].name
            //            wordImage.image = arrayWords?[0].arrayWords?[currentIndex].image
            //            wordArray.append((arrayWords?[0].arrayWords?[currentIndex])!)
        }
    }

    var testArray = ["Hello","Energy","Disk","Duck","Wafles"]

    var wordArray: [String] = [] //[ArrayWords] = []

    lazy var wordTextLabel: UILabel = {
        let label = UILabel()
        label.text = testArray[currentIndex]//arrayWords?[0].arrayWords?[currentIndex].name
        label.textColor = .white
        label.font = UIFont(name: "OpenSans-ExtraBold", size: 20)
        label.textAlignment = .center
        label.translatesAutoresizingMaskIntoConstraints = false
        label.isUserInteractionEnabled = true
        return label
    }()

    lazy var wordImage: UIImageView = {
        let image = UIImageView()
        image.contentMode = .scaleAspectFit
        image.tintColor = .white
        image.translatesAutoresizingMaskIntoConstraints = false
        return image
    }()

    lazy var button1: UIButton = {
        let button = UIButton()
        button.backgroundColor = .white
        button.setTitle("Good", for: .normal)
        button.setTitleColor(.black, for: .normal)
        button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
        button.layer.cornerRadius = 40
        button.clipsToBounds = true
        button.translatesAutoresizingMaskIntoConstraints = false
        return button
    }()

    lazy var button2: UIButton = {
        let button = UIButton()
        button.backgroundColor = .white
        button.setTitle("No", for: .normal)
        button.setTitleColor(.black, for: .normal)
        button.layer.cornerRadius = 40
        button.translatesAutoresizingMaskIntoConstraints = false
        return button
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupView()  
    }

    func setupView() {
        view.setGradient(colorOne: Color.purpleColor, colorTwo: Color.pinkColor,
                         startPoint: CGPoint(x: 1.0, y: 0.1), endPoint: CGPoint(x: 0.1, y: 1.0))
        view.addSubview(wordTextLabel)
        //wordTextLabel.addSubview(wordImage)
        //view.addSubview(wordImage)
        view.addSubview(button1)
        view.addSubview(button2)

        NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|-120-[v0]-120-|", metrics: nil, views: ["v0": wordTextLabel]))

        button1.bottomAnchor.constraint(lessThanOrEqualTo: view.bottomAnchor, constant: -40).isActive = true
        button1.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 30).isActive = true
        button1.heightAnchor.constraint(equalToConstant: 80).isActive = true
        button1.widthAnchor.constraint(equalToConstant: 80).isActive = true

        button2.bottomAnchor.constraint(lessThanOrEqualTo: view.bottomAnchor, constant: -40).isActive = true
        button2.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -30).isActive = true
        button2.heightAnchor.constraint(equalToConstant: 80).isActive = true
        button2.widthAnchor.constraint(equalToConstant: 80).isActive = true

        //        wordArray.append((arrayWords?[0].arrayWords?[currentIndex])!)

    }

    @objc func buttonAction(sender: Any!) {
        print("Button tapped")
        action()
    }

    func action() {

        if currentIndex < testArray.count/*arrayWords?[0].arrayWords?.count*/ { //!= 2 // !=
            currentIndex += 1

            arrayIndex += 1
            wordTextLabel.text = testArray[currentIndex]//arrayWords?[0].arrayWords?[currentIndex].name

            wordArray.append(testArray[arrayIndex])//((arrayWords?[0].arrayWords?[arrayIndex])!)

        } else if arrayIndex != 3 {
            arrayIndex += 1
            wordArray.append(testArray[arrayIndex])//((arrayWords?[0].arrayWords?[arrayIndex])!)

        }  

    }

}
4
  • Can you explain the purpose of currentIndex and arrayIndex? Why do you need two of them? Also, why does currentIndex start at 0 and arrayIndex start at -1? Also, why do you check to make sure that arrayIndex != 3? Commented Apr 30, 2020 at 14:25
  • You can't first check the index variable, if currentIndex < testArray.count, and then increase the variable since that invalidates the check. You need to do it in the opposite order and you also need to check your other index variable in the same way Commented Apr 30, 2020 at 14:27
  • @Rob when I start the application, the element at index 0 starts to appear at me, when I press the button, the element at index 0 is not added to another array, so the variable arrayIndex is needed Commented Apr 30, 2020 at 15:25
  • @Rob and check arrayIndex! = 3 is needed because the last element is not added to another array Commented Apr 30, 2020 at 15:27

1 Answer 1

1

Change action() as below and it will work fine. There is no need to maintain two index variables and without the second variable you don't need the else if... either

func action() {
    if currentIndex < testArray.count {
        wordTextLabel.text = testArray[currentIndex]
        wordArray.append(testArray[currentIndex])
    }
    currentIndex += 1
}
Sign up to request clarification or add additional context in comments.

5 Comments

When you click on the button, the first element from the array appears twice
@Mospy Not for me when I run the code in a playground but I see that you initialise the text label with the first word (using lazy) so that might be why you see it twice.
yes, I initialize the label in the text, because when loading the controller I need to display the first element from the array.
One solution is to start currentIndex at 1 instead of 0 then but I think this is beyond the question which was about the index out of range error.
but if I start with index 1, then the element under index 0 will not be displayed

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.