The functionality I tried to implement in the quiz game is looks like this:
Here is the SettingsViewController
which contains the settings of an app, where user can choose the difficulity
of the game and the sequence
of the questions the game have using UISegmentedControl
.
The SettingsViewController
contains these methods using to implement this functionality:
@IBAction func didChooseDifficulty(_ sender: UISegmentedControl) {
difficulityDelegate?.didChooseDifficulity(
difficulity: selectedDifficulty)
UserDefaults.standard.set(
sender.selectedSegmentIndex,
forKey: "chosenDifficulity")
}
private var selectedDifficulty: Difficulty {
switch self.difficultyControl.selectedSegmentIndex {
case 0: return .easy
case 1: return .hard
case 2: return .insane
default: return .hard
}
}
@IBAction func didChooseSequence(_ sender: UISegmentedControl) {
sequenceDelegate?.didChooseSequence(
sequence: selectedSequence)
UserDefaults.standard.set(
sender.selectedSegmentIndex,
forKey: "chosenSequence")
}
private var selectedSequence: Sequence {
switch self.sequenceControl.selectedSegmentIndex {
case 0: return .sequentally
case 1: return .shuffled
default: return .sequentally
}
}
override func viewDidLoad() {
super.viewDidLoad()
setupQuestionsSequence()
setupDifficulty()
}
func setupQuestionsSequence() {
if let sequence = UserDefaults.standard.value(
forKey: "chosenSequence") {
let selectedIndex = sequence as! Int
sequenceControl.selectedSegmentIndex = selectedIndex
}
}
func setupDifficulty() {
if let difficulity = UserDefaults.standard.value(
forKey: "chosenDifficulity") {
let selectedIndex = difficulity as! Int
difficultyControl.selectedSegmentIndex = selectedIndex
}
}
I use the DifficulityDelegate
and ChooseQuestionsSequenceDelegate
protocols here:
protocol DifficulityDelegate: AnyObject {
func didChooseDifficulity(
difficulity: Difficulty)
}
protocol ChooseQuestionsSequenceDelegate: AnyObject {
func didChooseSequence(
sequence: Sequence)
}
Also here is the GameDelegate
protocol, the main protocol of the game I use:
protocol GameDelegate: AnyObject {
func didEndGame(
difficulty: Difficulty,
withScore score: Int,
name: String,
removeTwoUsed: Bool,
callFriendUsed: Bool,
audienceHelpUsed: Bool)
}
Here is the GameSession
class using for the main logic of the game:
class GameSession {
var questionNumber: Int = 0
var callFriendUsed = false
var audienceHelpUsed = false
var removeTwoUsed = false
var difficulty: Difficulty = .hard
var sequence: Sequence = .sequentally
}
Here is the Question
structure with the questions is there:
struct Question: Codable {
let question: String
let answers: [String]
let rightAnswer: Int
let difficulty: Difficulty
}
And here is the GameViewController
, the main controller where is the game itself occurs.
I need to gain some understanding of why it's nothing happens when I change the UISegmentedControl
states. There is no any changes of the game difficulty
and the sequence
of the questions occurs.
Here is the some code from the GameViewController
:
weak var delegate: GameDelegate?
weak var sequenceDelegate: ChooseQuestionsSequenceDelegate?
weak var difficulityDelegate: DifficulityDelegate?
private var questions = [Question]()
var gameSession = GameSession()
var score = 0
var questionNumber = Observable<Int>(0)
var difficulty: Difficulty = .hard {
didSet {
gameSession.difficulty = difficulty
}
}
var sequence: Sequence = .sequentally {
didSet {
gameSession.sequence = sequence
}
}
private var chooseDifficultyStrategy: DiffilultyStrategy {
switch difficulty {
case .easy: return EasyModeStrategy()
case .hard: return HardModeStrategy()
case .insane: return InsaneModeStrategy()
}
}
private var setupSelectedSequence: SequenceStrategy {
switch sequence {
case .sequentally: return SequentiallyStrategy()
case .shuffled: return ShuffledStrategy()
}
}
func initialSetup() {
delegate = Game.instance
Game.instance.gameSession = gameSession
questions = chooseDifficultyStrategy.setupGame(
lifelineButtons: lifelineButtonsCollection)
questions = setupSelectedSequence.setupGame()
}
It might be stupid, I'll be very glad if someone will help me understand what am I doing wrong. Thanks!
CodePudding user response:
Speaking in very broad terms, I'd say that the protocol-and-delegate mechanism isn't what's wanted here. The view controllers that interact with the user's preferences, GameViewController and SettingsViewController, don't necessarily exist at the same time, so they cannot communicate with one another.
What's more likely needed is some central repository, as it were, where the SettingsViewController can write down the user's desires and the GameViewController can read them. A common place to keep preferences like this is UserDefaults; it has the advantage that it persists over time, even between launches of the app, and that it is globally available (meaning any of your code anywhere can interact with it).