Home > Software engineering >  The logic of the interaction between UISegmentedControl and GUI doesn't work in my app
The logic of the interaction between UISegmentedControl and GUI doesn't work in my app

Time:05-23

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

  • Related