1

OVERVIEW - I am making a flashcard app. I have gotten to the point where the user can swipe left and right through an array of images. The images are split into 11 different groups and all of the groups add up to one final array which the user can swipe through(code below).

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

NOW - I am working on a settings page(image below). There is 1 switch for each of the 11 lists of words in the code above. The top most switch would control list1, the second switch would control list2 etc...

enter image description here

THE PROBLEM - is that I want to add functionality to each switch. When a switch is in the off position, the group of images it is associated with should not be included in the final array and will not be displayed when the user is swiping through the flashcards. The code for my settings page thus far is below. I have tried experimenting with different bits of code such as connecting the switch to the ViewController and adding an Override func but I am not sure where to go at this point.

import UIKit

protocol WordSelectionDelegate: class {
func wordSelected(newWord: Word)
}

class MasterViewController: UITableViewController {
var words = [Word]()

weak var delegate: WordSelectionDelegate?

override func prepare(for segue: UIStoryboardSegue, sender: SecondViewController) {
    if let vc = segue.destination as? MasterViewController {
        vc.wordLists = wordLists
    }
}


@IBAction func switchAction(_ sender: UISwitch) {
     wordList[sender.tag].active = rollIntoLoanSwitch.isOn
}



override func viewDidLoad() {
    super.viewDidLoad()



}
required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)!

    self.words.append(Word(name: "initial /l/ 1 syllable", description: "lake lamb lamp lark leaf leash left leg lime lion lips list lock log look love lunch"))

    self.words.append(Word(name: "initial /l/ multisyllabic", description: ""))

    self.words.append(Word(name: "intersyllabic /l/", description: ""))

    self.words.append(Word(name: "final /l/", description: ""))

    self.words.append(Word(name: "initial /pl/", description: ""))

    self.words.append(Word(name: "initial /bl/", description: ""))

    self.words.append(Word(name: "initial /fl/", description: ""))

    self.words.append(Word(name: "initial /gl/", description: ""))

    self.words.append(Word(name: "initial /kl/", description: ""))

    self.words.append(Word(name: "initial /sl/", description: ""))

    self.words.append(Word(name: "final /l/ clusters", description: ""))


}


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

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return self.words.count
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 

    // Configure the cell...
    let word = self.words[indexPath.row]
    cell.textLabel?.text = word.name
    return cell
}

override  func tableView(_ tableView: UITableView, didSelectRowAt
    indexPath: IndexPath) {
    let selectedMonster = self.words[indexPath.row]
    self.delegate?.wordSelected(newWord: selectedMonster)
    if let Detail = self.delegate as? Detail {
        splitViewController?.showDetailViewController(Detail, sender: nil)
    }

}
/*
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, can

Any thoughts on how to go about solving this problem would be greatly appreciated . Thank you

enter image description here

Anthony Rubin
  • 69
  • 1
  • 1
  • 14
  • I can't see in the code the delegate/action target of the UISwitch being set, you need to do that otherwise the `switchAction` method will never be called. Have you done that anywhere else in you code? If you put a break point in that method, is it ever called? – Mrwerdo Jul 28 '17 at 01:24
  • I suppose i have not set that. The settings page is a split view controller so there are other classes that are tied to the split view but I have not put the switch action method in any other classes other than the ones above. – Anthony Rubin Jul 28 '17 at 02:48

1 Answers1

0

You're missing a number of parts to your program to make this work. They are:

  1. Setting the target method of the UISwitch control.
  2. Setting the tag number of the UISwitch control.
  3. Refreshing the presented images in the SecondViewController.

To set the target method of the UISwitch control, you'll need to call addTarget(_:action:for:) on each switch, passing the reference to the MasterViewController that you have. If you do this, then I'd recommend setting a tag for your UISwitch control in the Interface Builder. For example, assuming that your UISwitch had a tag of 1:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 

    // Configure the cell...
    let word = self.words[indexPath.row]
    cell.textLabel?.text = word.name
    if let switchControl = cell.viewWithTag(1) as UISwitch {
        switchControl.addTarget(self, action: #selector(switchAction(_:)), for: .valueChanged)
    }

    return cell
}

For point 3, the data in your MasterViewController is different than that in your SecondViewController. You need to obtain a reference to your SecondViewController and then update the data there, and tell it to redisplay the selected images. See this question for details on how to access a peer view controller from a split view controller.

Mrwerdo
  • 388
  • 2
  • 7
  • Thank you. However the flash cards are not displayed in the Detail view controller. I am going to be displaying other information there. I added a photo of my storyboard to the question so you can see the layout of the app. The scene with the owl is the opening screen then there is a segue to the flashcards (the scene with the alligator image, this is the SecondViewController) . To the right you can see my split view controller, this is the settings page I am working on. So I want to pass the information from The MainViewController(settings page) to the SecondViewController(alligator scene) – Anthony Rubin Jul 28 '17 at 20:59