问题
I am trying to make a simple flashcard app.
OVERVIEW - To give you the basic run down of the app, all of the flashcards contain an object that has the letter l. Sometimes the word starts with the letter l, sometimes there is a double ll, sometimes the word starts with pl or kl, or sl, etc...
SO FAR - I have made the app so that there is a home page and from the home page you press Go and then it takes you too a second view controller. From there you can swipe left and right through the flash cards. I did this by creating an array with all of the images and then adding a swipe gesture (code below)
//
// SecondViewController.swift
// firstapp
//
// Created by Anthony Rubin on 6/20/17.
// Copyright © 2017 rubin. All rights reserved.
//
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.
}
}
}
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.
}
*/
THE PROBLEM - I want to create a settings page. This settings page will have a basic on and off switch for each group of words. So lets say I do not want any words that have the initial letter l, I would turn the button too the off position and then when I swipe through the images there will be no flashcards with the initial letter l.
settings page
MY IDEA - I imagine that i will have to connect each on and off switch too its corresponding array of words and then code up if, then statements for each button. Then add all of the arrays together. However im not sure at all how to begin doing this. I have made a Table view with all the different on and off switches but have not yet added any functionality. I am also not sure how I am going to send the information from my table view to the second view controller.
I know this is alot to ask in one question but any help would be much appreciated. Thank you
回答1:
There's a lot here, but you seem to have made a good start.
If the words and the categories are fairly fixed then the first thing I'd do is split the word list up into the different categories, then you can combine the ones you want for you images using:
let list1 = ["Bat", "Cow"]
let list2 = ["Frog", "Rabbit"]
let list3 = ["Parrot", "Tiger"]
var imageList: [String] {
return list1+list2
}
You could keep an array of activeLists and then use a reduce
function to return the final array:
var activeLists = [list1, list2]
var imageList: [String] {
return activeLists.reduce([], {$0 + $1})
}
But you'll probably end up needing a more manageable data source than a simple String Array to store the information perhaps:
struct List {
let words: [String]
var active: Bool
}
Then you could have:
let list1 = List(words: ["Bat", "Cow"], active: true)
let list2 = List(words: ["Frog", "Rabbit"], active: true)
let list3 = List(words: ["Parrot", "Tiger"], active: true)
var wordLists = [list1, list2, list3]
var imageList: [String] {
let active = wordLists.reduce([]) { (result:[String], list:List) in
if list.active {
return result + list.words
} else {
return result
}
}
return active
}
Note: I wouldn't use maxImages
as a constant as that will need to change, you can use imageList.count
instead.
Regarding sending information, there's a few ways of doing this. One way is to use prepareForSegue to send the information to the new viewController. Something like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? SettingsViewController {
vc.wordLists = wordLists
}
}
Then within Settings you can toggle individual word lists with:
wordLists[1].active = false
An easy way to match up switches to the array reference is to give each UISwitch a Tag within the Storyboard that matches its index in the wordLists Array, hook all of the UISwitches to the same IBAction then when it is triggered use:
@IBAction func switchAction(_ sender: UISwitch) {
wordList[sender.tag].active = rollIntoLoanSwitch.isOn
}
Then you could use a Delegate to send the information back on each toggle or when you leave the view. Alternatively you can define your word lists in a separate Class, with a singleton and reference it from everywhere, it depends on how many different views you're going to need access to the word lists.
回答2:
You can use Delegation Pattern to send message from one view controller to another. For delegation pattern you make your SecondViewController as delegate of SettingsViewController and set up communication between both classes.
If you have to pass data from SettingsViewController To SecondViewController
Create protocol in SettingsViewController as
protocol SettingsViewControllerDelegate {
func settingDidFinished(data : [String])
}
Create an id in SettingsViewController , so that you can assign any class as its delegate class.
class SettingsViewController : UIViewController {
// MARK:- Delegate
var SettingsViewControllerDelegate ?
Call protocol method in SettingsViewController on submit button or wherever required.
@IBAction private func doneTapped(_ sender: AnyObject) {
delegate?.settingDidFinished(data : yourSettingsArray)
}
Create an object of SettingsViewController in SecondViewController and assign SecondViewController as delegate of SettingsViewController as
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let settingsVc = segue.destinationViewController as? SettingsViewController {
settingsVc .delegate = self
}
}
Implement required protocol methods of SettingsViewController in SecondViewController
extension SecondViewController: SettingsViewControllerDelegate {
// # 4: "SecondViewController" implements "SettingsViewControllerDelegate " protocols:
func settingDidFinished(data : [String]) {
print("Settings finished") // use settings Array here. Access your settings here and add/substract array as per your requirements.
}
}
Hope it helps.. Happy Coding..:)
来源:https://stackoverflow.com/questions/44896038/settings-page-to-add-or-subtract-different-image-arrays-coding-with-swift-and-x