Segmented control not changing index - ios

I'm coding a game, and I have a segmented control for the user to select a difficulty level. I've added some simple code inside the cases to check if the index changes, but it doesn't appear to. Here's the code:
#IBAction func chooseOnePlayerDifficulty(_ sender: UISegmentedControl) {
switch onePlayerGameType {
case .sluggish:
onePlayerGameType = typeOfGame.sluggish
print("Sluggish difficulty selected.")
case .average:
onePlayerGameType = typeOfGame.average
print("Average difficulty selected.")
case .ninja:
onePlayerGameType = typeOfGame.ninja
print("Ninja difficulty selected.")
}
}
Now, when I test this in the simulator, the only thing that prints to the console is "Average difficulty selected." No matter which one I select. Why is this happening and how do I fix it?
EDIT: I've found an answer that works by asking this question on another forum. Thanks for the help though. Here's the answer from there that worked for me: Here is the link to the answer

This part of your code sets onePlayerGameType to .average, when you select the control again the value is still .average.
case .average:
onePlayerGameType = typeOfGame.average
I have a segmented control for the user to select a difficulty level
If that's all you need why do you need switch and not just assign it directly?
enum typeOfGame : Int {
case sluggish
case average
case ninja
}
#IBAction func chooseOnePlayerDifficulty(_ sender: UISegmentedControl) {
// assuming typeOfGame is enum
let difficultyLevel = typeOfGame(rawValue: sender.selectedSegmentIndex)
onePlayerGameType = difficultyLEvel
}

I hope you registered action method with segment control in StoryBoard/XIB or in code
segmentedControl.addTarget(self, action: "chooseOnePlayerDifficulty:", forControlEvents: .ValueChanged)
Try with following
#IBAction func chooseOnePlayerDifficulty(_ sender: UISegmentedControl) {
let selectedSegment = sender.selectedSegmentIndex
switch selectedSegment {
case 0:
onePlayerGameType = typeOfGame.sluggish
print("Sluggish difficulty selected.")
case 1:
onePlayerGameType = typeOfGame.average
print("Average difficulty selected.")
case 2:
onePlayerGameType = typeOfGame.ninja
print("Ninja difficulty selected.")
default:
print("Assing default")
}
}
Edit Right #JakeG, updated answer

Related

How to enable drawFilledEnabled in click of button Swift 5 (For-in loop requires 'ChartData' to conform to 'Sequence')

I am trying to create a specific button that enables .toggleFilled. Hence, a created an outlet and copied the code from Charts Demo (daniel gindi).
#IBAction func tappedFill(_ sender: UIButton) {
guard let data = lineChartView.data else { return }
for case let set as LineChartDataSet in data {
set.drawFilledEnabled = !set.drawFilledEnabled
}
lineChartView.setNeedsDisplay()
}
I can't solve this: "For-in loop requires 'ChartData' to conform to 'Sequence'". The above code works perfectly fine in Demo.

How to add an alert to switch toggle for multiple answers?

I created a Quiz app. There is one question with five answers, where the user can choose one of them. However at the moment it's possible to choose more than one answer. How can I add an alert (UIAlertController) and a restriction so if the user has already chosen one answer and tries to choose a second one ?
var questionIndex = 0
var answersChosen: [Answer] = []
func updateUI() {
let currentQuestion = questions[questionIndex]
let currentAnswers = currentQuestion.answers
let totalProgress = Float(questionIndex) /
Float(questions.count)
numberOfQuestion.text = "\(questionIndex+1)/5"
// navigationItem.title = "Вопрос - \(questionIndex+1)"
mainQuestion.text = currentQuestion.text
progressBar.setProgress(totalProgress, animated:
true)
updateMultipleStack(using: currentAnswers)
}
#IBAction func multipleAnswerButtonPressed(_ sender: Any) {
let currentAnswers = questions[questionIndex].answers
if firstSwitch.isOn {
answersChosen.append(currentAnswers[0])
}
if secondSwitch.isOn {
answersChosen.append(currentAnswers[1])
}
if thirdSwitch.isOn {
answersChosen.append(currentAnswers[2])
}
if fourthSwitch.isOn {
answersChosen.append(currentAnswers[3])
}
if fifthSwitch.isOn {
answersChosen.append(currentAnswers[4])
}
nextQuestion()
}
func updateMultipleStack(using answers: [Answer]) {
firstSwitch.isOn = false
secondSwitch.isOn = false
thirdSwitch.isOn = false
fourthSwitch.isOn = false
fifthSwitch.isOn = false
firstQuestionLbl.text = answers[0].text
secondQuestionLbl.text = answers[1].text
thirdQuestionLbl.text = answers[2].text
fourthQuestionLbl.text = answers[3].text
fifthQuestionLbl.text = answers[4].text
}
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
if segue.identifier == "ResultSegue" {
let resultsViewController = segue.destination as! ResultViewController
resultsViewController.responses = answersChosen
}
}
}
The approach I'd take would be to separate the user's selection of an answer (UISwitch collection) from processing the selected answer(Submit Answer button). This would allow the user to change their answer. The previous selection is automatically cleared. The answer is final when pressing a "Submit Answer" button (not shown).
In this code example, the switches are set as an IBOutlet collection. The tag on each switch is set from 0 to 4. All the switches are connected to an IBAction called switchPressed. A variable called selectedAnswer is used to identify the user's final picked answer when the "Submit Answer" is pressed.
#IBOutlet var switches: [UISwitch]!
private let noAnswer = -1
private var selectedAnswer = -1
#IBAction func switchPressed(_ sender: UISwitch) {
// Check if user turned off switch
guard sender.isOn == true else {
selectedAnswer = noAnswer
return
}
// Get user's answer and set all switches
selectedAnswer = sender.tag
switches.forEach { $0.isOn = false }
sender.isOn = true
}
#IBAction func submitAnswer(_ sender: UIButton) {
guard selectedAnswer > noAnswer else { return }
// use selectedAnswer to process answer and go to the next question
answersChosen.append(currentAnswers[selectedAnswer])
}
You could store all the switches in an array named Switches for example and then run a for loop to check if more than one is selected when checking answer.
var count = 0
for switchToggle in switches {
if switchToggle.isOn {
count += 1
if count > 1 {
//Print Warning "only select one"
}
} else {
//append answers
}
}
you could also use this to have multiple answers for certain quiz question
For the warning, you have different options you could use. You could use UIAlertController to display a warning if more than one button is selected but this could become annoying for the user after a while.
Another option could be to use a UILabel which warns the user to only pick one answer. You could animate the label to fade away after a few seconds.

Send many things through a segue - Swift 4

Edit - not really a question anymore - please feel free to delete this post or use it as you wish. A little red box says this post is mostly code and Grammarly is kind of helpful too so just rambling on now until the little red box goes away.
Working solution:
ViewController1 ->
enum to tag many buttons - (change each button tag in interface builder)
enum Answers : Int, CustomStringConvertible {
case bag = 1
case bird = 2
enum for text
var description : String {
switch self {
case .bag: return "Beg"
case .bird: return "Birds"
}
}
enum for images - (stored in Assets)
var pics : String {
switch self {
case .bag: return "beg"
case .bird: return "birds"
}
}
}
Prepare segue - (storyboard should match identifier name)
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ShowAnswers" {
guard
let controller = segue.destination as? proverbsViewController,
let category = sender as? Answers
else { return }
controller.answer = category.description
controller.image = UIImage(named: category.pics)!
}
}
Button to segue - all buttons are connected here (tagged in IB)
#IBAction func onButtonTap(_ sender: UIButton) {
performSegue(withIdentifier: "ShowAnswers", sender: Answers(rawValue: sender.tag))
}
}
Recieve data:
ViewController2 ->
var answer = ""
var image = UIImage()

I keep getting the errors... 'use of unresolved identifier' and 'Type gameType has no member pause game'

I created a button to pause my game and I'm trying to make some actions for it.
So I have no idea what I'm doing wrong, all other 'solutions' on this website haven't been working for me, so could you please tell me what I'm doing wrong, or rather what I'm not doing.
import Foundation
import UIKit
enum gameType {
case easy
case medium
case hard
case player2
case impossible
}
func pauseGame() { // HERE IS WHERE I GET THE ERRORS... IN THIS FUNCTION
self.isPaused = true
currentGameType = gameType.pauseGame
self.physicsWorld.speed = 0
self.speed = 0.0
}
class MenuVC : UIViewController {
#IBAction func Player2(_ sender: Any) {
moveToGame(game: .player2)
}
#IBAction func Easy(_ sender: Any) {
moveToGame(game: .easy)
}
#IBAction func Medium(_ sender: Any) {
moveToGame(game: .medium)
}
#IBAction func Hard(_ sender: Any) {
moveToGame(game: .hard)
}
#IBAction func Impossible(_ sender: AnyObject) {
moveToGame(game: .impossible)
}
func moveToGame(game : gameType) {
let gameVC = self.storyboard?.instantiateViewController(withIdentifier: "gameVC") as! GameViewController
currentGameType = game
self.navigationController?.pushViewController(gameVC, animated: true)
}
}
At the top of your file, gameType is an enumeration. That means that there are a finite set of cases that it can have (the game type can either be easy, medium, hard, etc.) In your code, you're attempting to use a case called pauseGame, but if you look at the definition of gameType there's no case with that name. So you either need to a) add a pauseGame case to gameType (does it make sense for pauseGame to be a "kind" of game?) or not set the gameType inside your pauseGame function.
My instinct is that you don't actually want to change the type of the game when the user pauses it, so you can probably just get rid of that line. Also, a note on style -- it's good to start the names of types with capital letters to distinguish them from functions and local variables (so GameType instead of gameType.)

How to get label name from Button?

I am new in Swift and I am making a simple calculator where I wan't to detect a button which was pressed and my code is below.
#IBAction func ButtonTapped(TheButton : UIButton){
println(TheButton.titleLabel.text)
}
But It Shows me error like "UILabel? Does not have a member a named text"
and it tell me to modify code like this
println(TheButton.titleLabel?.text)
This Prints Optional("1") (1 is my button name)
So anybody can help me why this is happend to me and how can I print my button name without Optional?
If you are sure that titleLabel is not nil:
println(TheButton.titleLabel!.text)
else
if let text = TheButton.titleLabel?.text {
println(text)
}
More simply, you could just do:
let titleValueString = TheButton.currentTitle!
If the button's title is not nil, the exclamation point (!) will implicitly unwrap the optional (currentTitle without the exclamation point) and you will have a string value for the title of the button in your constant, titleValueString
The top answer no longer works. Here is the corrected version for Swift 2.2:
If you are sure that titleLabel is not nil:
print(TheButton.titleLabel!.text!)
If you are not:
if let text = TheButton.titleLabel?.text {
print(text)
}
for Swift 5
There are many ways to do this but the easiest is just what I mentioned below:
#IBAction func keyPressed(_ sender:UIButton){
print(sender.currentTitle!)
}
Swift 5: I found this much cleaner
#IBAction func ButtonTapped(_ sender : UIButton){
guard let btnTxt = sender.titleLabel!.text else{
return
}
print(btnTxt)
// now you can make use of this variable
if btnTxt == "something" {
.......
}
}

Resources