0

I am trying to create a flashcard app. I successfully got the app too the point where there were 11 different arrays of flashcards and all of these arrays added up to one final array which I could then swipe through. As you can see each group has "active: true" at the end of it.
This is because I have a settings page to turn each word group on and off.

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: 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()

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

// 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.
    }
}
}
}

but I needed to add a sound file to each flashcard so that whenever the card is tapped an audio file plays, so I have tried to change the code so that each word in each group is coupled with an audio file. 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? 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! (new code below)

import UIKit

class SecondViewController: UIViewController , UIGestureRecognizerDelegate  {



var imageIndex: Int = 0
@IBAction func home(_ sender: Any) {
    performSegue(withIdentifier: "home", sender: self)
}

@IBOutlet weak var imgPhoto: UIImageView!

struct List {
    let words: [Card] /*Create array of cards*/
    var active: Bool
}




let firstList:[Card] =[
    Card(image: UIImage(named: "lake")!, soundUrl: "Lake"),
    Card(image: UIImage(named: "lamb")!, soundUrl: "Lamb"),
    Card(image: UIImage(named: "lamp")!, soundUrl: "Lamp"),
    Card(image: UIImage(named: "lark")!, soundUrl: "Lark"),
    Card(image: UIImage(named: "leaf")!, soundUrl: "Leaf"),
    Card(image: UIImage(named: "leash")!, soundUrl: "Leash"),
    Card(image: UIImage(named: "left")!, soundUrl: "Left"),
    Card(image: UIImage(named: "leg")!, soundUrl: "Leg"),
    Card(image: UIImage(named: "lime")!, soundUrl: "Lime"),
    Card(image: UIImage(named: "lion")!, soundUrl: "Lion"),
    Card(image: UIImage(named: "lips")!, soundUrl: "Lips"),
    Card(image: UIImage(named: "list")!, soundUrl: "List"),
    Card(image: UIImage(named: "lock")!, soundUrl: "Lock"),
    Card(image: UIImage(named: "log")!, soundUrl: "Log"),
    Card(image: UIImage(named: "look")!, soundUrl: "Look"),
    Card(image: UIImage(named: "love")!, soundUrl: "Love"),
    Card(image: UIImage(named: "lunch")!, soundUrl: "Lunch")
        ]

let secondList:[Card] = [
    Card(image: UIImage(named: "lake")!, soundUrl: "Lake"),
    Card(image: UIImage(named: "lamb")!, soundUrl: "Lamb"),
    Card(image: UIImage(named: "lamp")!, soundUrl: "Lamp"),
    Card(image: UIImage(named: "lark")!, soundUrl: "Lark"),
    Card(image: UIImage(named: "leaf")!, soundUrl: "Leaf"),

    ]

struct List {
    let words: [Card] /*Create array of cards*/
    var active: Bool
}

let list1 = List(words:firstList, active: true)
let list2 = List(words:secondList, active: true)

var imageList: [String]{
let wordLists = [list1, list2]

print((wordLists[0] as! List).words[0].soundurl)



    override func viewDidLoad() {
    super.viewDidLoad()



    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
    imgPhoto.isUserInteractionEnabled = true
    imgPhoto.addGestureRecognizer(tapGestureRecognizer)

    imgPhoto.image = (imageList[0] ).image

    // 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)

}

@IBAction func imageTapped(tapGestureRecognizer: UITapGestureRecognizer)
{
    print("hhh")
    imageList[imageIndex].playSound()
    // Your action
}

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 = words.count - 1

            }

            imgPhoto.image = itemList[imageIndex].image

        case UISwipeGestureRecognizerDirection.left:
            print("User swiped Left")
            // increase index first

            imageIndex += 1

            // check if index is in range

            if imageIndex > itemList.count - 1 {

                imageIndex = 0

            }



            imgPhoto.image = itemList[imageIndex].image
        default:


            break //stops the code/codes nothing.
        }
    }
}
}
1
  • Do not ask the same question twice. Commented Aug 5, 2017 at 3:29

1 Answer 1

0

You haven't elaborated what the bugs are. However, from what I see in the code you pasted - the main change is the sound file plus the isUserInteractionEnabled enabled.

I don't see the playSound implementation, but I attach here this snippet I often use in Swift3 whenever I need to play sound - and it is working perfect: (don't forget to put the import AVFoundation also)

var audioPlayer : AVAudioPlayer?

func playSound()
{
    let fileURL = Bundle.main.path(forResource: "beep-01a", ofType:"mp3")!

    let url = URL(fileURLWithPath: fileURL)

    do
    {
        let player = try AVAudioPlayer(contentsOf: url)
        self.audioPlayer = player
        player.prepareToPlay()
        player.play()
    }
    catch let error as NSError
    {
        print(error.description)
    }
}

If it still not running smooth, try to put the playSound in thread in background when you call it in the tap : DispatchQueue.global().async { self.playSound() })

If it's not the sound after all - provide some data on the bugs..

Good Luck

Sign up to request clarification or add additional context in comments.

4 Comments

My apologies, perhaps I should have been more specific. It is not a problem with playing the sounds but it is a problem with the image array. If you look at the first block of code you will see there are 11 different image arrays which add up to one final array. If you look at my new code, I have 2 arrays and wish to have them compile as one array like you see in my first block of code
I think problem may be laid out here : let wordLists = [list1, list2]. This yields array of 2 array items and not one joined array of items from both of them. You should do the reduce you did on first block, or use flatMap to unite the arrays.
the problem is that with my new structure im not sure how to make each list "active" which would then allow me to do the reduce. Do you have any idea how I could make each list active?
Needed to pull the words from firstList and secondList into a new list, and on it to do the reduce. Here's a pseudo to give you a general idea: let activeListOfWords : List = List(words:[], active: true) for card in firstList { activeListOfWords.words.append(card as! List).soundUrl } // now list1 is a list of words, without images // same goes for secondList

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.