1

I am trying to create a flashcard app. I successfully got the app too the point where I could swipe through an array of photos(see code below).

import UIKit

class SecondViewController: UIViewController , UIGestureRecognizerDelegate  {



@IBAction func home(_ sender: Any) {
performSegue(withIdentifier: "home", sender: self)
}


@IBOutlet weak var imgPhoto: UIImageView!





var imageList:[String] = ["alligator", "apple", "balance", "ball", "ballerina", "balloon", "bell", "belt", "black", "blanket", "blender", "blocks", "blond", "blood", "blow", "blue", "bowling", "bubble", "bully", "calendar", "castle", "cello", "clam", "clamp", "clap", "claw", "clean", "climb", "clip", "cloud", "cold", "colors", "crawl", "curlyhair", "dollar", "dolphin", "elephant", "elf", "eyelashes", "fall", "fishbowl", "flag", "flipflop", "float", "floor", "flower", "fluffy", "flute", "fly", "gasoline", "girl", "glacier", "glad", "glasses", "glide", "glitter", "globe", "glove", "glue", "goalie", "golf", "hula", "jellyfish", "ladder", "ladybug", "lake", "lamb", "lamp", "lark", "laughing", "lawnmower", "leaf", "leash", "left", "leg", "lemon", "leopard", "leprechaun", "letters", "licking", "lifesaver", "lifting", "lightbulb", "lightning", "lime", "lion", "lips", "list", "listen", "llama", "lock", "log", "look", "love", "lunch", "melt", "milk", "olive", "owl", "pail", "peel", "pillow", "pilot", "planet", "plank", "plant", "plate", "play", "plum", "plumber", "plus", "polarbear", "pool", "rollerskate", "ruler", "shelf", "silly", "sled", "sleep", "sleeves", "slice", "slide", "slime", "slip", "slow", "smile", "telephone", "television", "tulip", "umbrella", "valentine", "violin", "whale", "wheel", "xylophone", "yellow"]
 let maxImages = 135
 var imageIndex: NSInteger = 0


override func viewDidLoad() {
super.viewDidLoad()

// Do any additional setup after loading the view.
imgPhoto.isUserInteractionEnabled = true


let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(Swiped(gesture:)))
leftSwipe.cancelsTouchesInView = false


let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(Swiped(gesture:)))
rightSwipe.cancelsTouchesInView = false

leftSwipe.direction = .left
rightSwipe.direction = .right


view.addGestureRecognizer(leftSwipe)
view.addGestureRecognizer(rightSwipe)


}



func Swiped(gesture: UIGestureRecognizer) {

if let swipeGesture = gesture as? UISwipeGestureRecognizer {

    switch swipeGesture.direction {

    case UISwipeGestureRecognizerDirection.right :
        print("User swiped right")

        // decrease index first

        imageIndex -= 1

        // check if index is in range

        if imageIndex < 0 {

            imageIndex = maxImages

        }

        imgPhoto.image = UIImage(named: imageList[imageIndex])

    case UISwipeGestureRecognizerDirection.left:
        print("User swiped Left")

        // increase index first

        imageIndex += 1

        // check if index is in range

        if imageIndex > maxImages {

            imageIndex = 0

        }

        imgPhoto.image = UIImage(named: imageList[imageIndex])




    default:
        break //stops the code/codes nothing.


    }
}

but I needed to add a settings page so that the user could choose which word groups they wanted to have displayed, so I have tried to change the code so that the words were split up into groups and I made the groups "active" so that the user could manipulate them in a settings page(if the user turns a word group off then that word group is no longer active). However I have not been able to get this new code to run smooth, it is riddled with bugs. Can any of you see what is wrong with this new code? as of now I have not made a settings page but when I run the new code I should be able to swipe through all of the pictures just like my original code, However this is not possible currently. Any help would be much appreciated. Thanks!

import UIKit

class SecondViewController: UIViewController , UIGestureRecognizerDelegate  {



@IBAction func home(_ sender: Any) {
performSegue(withIdentifier: "home", sender: self)
}


@IBOutlet weak var imgPhoto: UIImageView!



struct List {
    let words: [String]
    var active: Bool
}

let list1 = List(words:["lake", "lamb", "lamp", "lark", "leaf", "leash", "left", "leg", "lime", "lion", "lips", "list", "lock", "log", "look", "love", "lunch"], active: true)

let list2 = List(words: ["ladder", "ladybug", "laughing", "lawnmower", "lemon", "leopard", "leprechaun", "letters", "licking", "lifesaver", "lifting", "lightbulb", "lightning", "listen", "llama"], active: true)

let list3 = List(words: ["alligator", "balance", "ballerina", "balloon", "bowling", "cello", "colors", "curlyhair", "dollar", "dolphin", "elephant", "eyelashes", "gasoline", "goalie", "hula", "jellyfish", "olive", "pillow", "pilot", "polarbear", "rollerskate", "ruler", "silly", "telephone", "television", "tulip", "umbrella", "valentine", "violin", "xylophone", "yellow"], active: true)

let list4 = List(words: ["apple", "ball", "bell", "bubble", "castle", "fall", "fishbowl", "girl", "owl", "pail", "peel", "pool", "smile", "whale", "wheel"], active: true)

let list5 = List(words: ["planet", "plank", "plant", "plate", "play", "plum", "plumber", "plus"], active: true)

let list6 = List(words: ["black", "blanket", "blender", "blocks", "blond", "blood", "blow", "blue"], active: true)

let list7 = List(words: ["flag", "flipflop", "float", "floor", "flower", "fluffy", "flute", "fly"], active: true)

let list8 = List(words: ["glacier", "glad", "glasses", "glide", "glitter", "globe", "glove", "glue"], active: true)

let list9 = List(words: ["clam", "clamp", "clap", "claw", "clean", "climb", "clip", "cloud"], active: true)

let list10 = List(words:["sled", "sleep", "sleeves", "slice", "slide", "slime", "slip", "slow"], active: true)

let list11 = List(words: ["belt", "cold", "dolphin", "elf", "golf", "melt", "milk", "shelf"], active: true)



var imageIndex: NSInteger = 0









override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
imgPhoto.isUserInteractionEnabled = true




    var wordLists = [list1, list2, list3, list4, list5, list6, list7, list8, list9, list10, list11]

    var imageList: [String] {

        let active = wordLists.reduce([]) { (result:[String], list:List) in
            if list.active {
                return result + list.words

            } else {
                return result
            }
        }

        return active

    }


    let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(Swiped(gesture:)))
    leftSwipe.cancelsTouchesInView = false


    let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(Swiped(gesture:)))
    rightSwipe.cancelsTouchesInView = false

    leftSwipe.direction = .left
    rightSwipe.direction = .right


    view.addGestureRecognizer(leftSwipe)
    view.addGestureRecognizer(rightSwipe)


}



func Swiped(gesture: UIGestureRecognizer) {

    if let swipeGesture = gesture as? UISwipeGestureRecognizer {

        switch swipeGesture.direction {

        case UISwipeGestureRecognizerDirection.right :
            print("User swiped right")

            // decrease index first

            imageIndex -= 1

            // check if index is in range

            if imageIndex < 0 {

                imageIndex = imageList

            }

            imgPhoto.image = UIImage(named: imageList[imageIndex])

        case UISwipeGestureRecognizerDirection.left:
            print("User swiped Left")

            // increase index first

            imageIndex += 1

            // check if index is in range

            if imageIndex > imageList {

                imageIndex = 0

            }

            imgPhoto.image = UIImage(named: imageList[imageIndex])




        default:
            break //stops the code/codes nothing.


        }
    }
}










override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
}


/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
}
*/
0

1 Answer 1

0

You're very close; there are a few fixes needed:

  1. Move the imageList computed variable to the class level, instead of inside viewDidLoad.

  2. The imageIndex variable can be an Int instead of an NSInteger. This is not a breaking change, but will make things easier and is better Swift style.

  3. Where you previously used the maxImages variable, you can replace them with imageList.count, which is the total number of elements in the array.

Here is the final, edited code. It compiles; let me know if it works!

class SecondViewController: UIViewController , UIGestureRecognizerDelegate  {

    @IBAction func home(_ sender: Any) {
        performSegue(withIdentifier: "home", sender: self)
    }

    @IBOutlet weak var imgPhoto: UIImageView!

    struct List {
        let words: [String]
        var active: Bool
    }

    let list1 = List(words:["lake", "lamb", "lamp", "lark", "leaf", "leash", "left", "leg", "lime", "lion", "lips", "list", "lock", "log", "look", "love", "lunch"], active: true)

    let list2 = List(words: ["ladder", "ladybug", "laughing", "lawnmower", "lemon", "leopard", "leprechaun", "letters", "licking", "lifesaver", "lifting", "lightbulb", "lightning", "listen", "llama"], active: true)

    let list3 = List(words: ["alligator", "balance", "ballerina", "balloon", "bowling", "cello", "colors", "curlyhair", "dollar", "dolphin", "elephant", "eyelashes", "gasoline", "goalie", "hula", "jellyfish", "olive", "pillow", "pilot", "polarbear", "rollerskate", "ruler", "silly", "telephone", "television", "tulip", "umbrella", "valentine", "violin", "xylophone", "yellow"], active: true)

    let list4 = List(words: ["apple", "ball", "bell", "bubble", "castle", "fall", "fishbowl", "girl", "owl", "pail", "peel", "pool", "smile", "whale", "wheel"], active: true)

    let list5 = List(words: ["planet", "plank", "plant", "plate", "play", "plum", "plumber", "plus"], active: true)

    let list6 = List(words: ["black", "blanket", "blender", "blocks", "blond", "blood", "blow", "blue"], active: true)

    let list7 = List(words: ["flag", "flipflop", "float", "floor", "flower", "fluffy", "flute", "fly"], active: true)

    let list8 = List(words: ["glacier", "glad", "glasses", "glide", "glitter", "globe", "glove", "glue"], active: true)

    let list9 = List(words: ["clam", "clamp", "clap", "claw", "clean", "climb", "clip", "cloud"], active: true)

    let list10 = List(words:["sled", "sleep", "sleeves", "slice", "slide", "slime", "slip", "slow"], active: true)

    let list11 = List(words: ["belt", "cold", "dolphin", "elf", "golf", "melt", "milk", "shelf"], active: true)

    var imageIndex: Int = 0

    var imageList: [String] {

        let wordLists = [list1, list2, list3, list4, list5, list6, list7, list8, list9, list10, list11]

        let active = wordLists.reduce([]) { (result:[String], list:List) in
            if list.active {
                return result + list.words

            } else {
                return result
            }
        }

        return active

    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        imgPhoto.isUserInteractionEnabled = true

        let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(Swiped(gesture:)))
        leftSwipe.cancelsTouchesInView = false

        let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(Swiped(gesture:)))
        rightSwipe.cancelsTouchesInView = false

        leftSwipe.direction = .left
        rightSwipe.direction = .right

        view.addGestureRecognizer(leftSwipe)
        view.addGestureRecognizer(rightSwipe)

    }

    func Swiped(gesture: UIGestureRecognizer) {

        if let swipeGesture = gesture as? UISwipeGestureRecognizer {

            switch swipeGesture.direction {

            case UISwipeGestureRecognizerDirection.right :
                print("User swiped right")

                // decrease index first

                imageIndex -= 1

                // check if index is in range

                if imageIndex < 0 {

                    imageIndex = imageList.count - 1

                }

                imgPhoto.image = UIImage(named: imageList[imageIndex])

            case UISwipeGestureRecognizerDirection.left:
                print("User swiped Left")

                // increase index first

                imageIndex += 1

                // check if index is in range

                if imageIndex > imageList.count - 1 {

                    imageIndex = 0

                }

                imgPhoto.image = UIImage(named: imageList[imageIndex])

            default:
                break //stops the code/codes nothing.
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

11 Comments

Beat me to it. Yes, the problem was scope. In the new code, OP moved the variable to a local function.
Thanks for your imput. The code does run however if I am at the first flash card and I swipe left the app crashes. But lets say I swipe right 3 times, that will work and then I will be able to swipe left 3 times back to the first card. but then after that if I swipe left one more time it crashes. any idea why? @Shades
I think it's an index out of bounds error. Try changing imageIndex = imageList.count to imageIndex = imageList.count - 1. I've updated my answer to reflect this change.
hello, i tried to change this but it still crashes for some reason. if you look at my original code it would start on the alligator picture and then i could swipe left and right through the pictures. now it starts me off on a blank page(this is something I am trying to fix, I would like it to start off on the first picture of the first list). Also I can swipe left, but when I swipe right past the first picture and then try to swipe left again it crashes. Any thoughts?
What line of code is causing the crash and what does the error say?
|

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.