Dark and light not switching with segmented control (Swift) - swift

Well I'm trying to make a light and dark theme for a cookie clicker with segmented index but when i switch nothing happens and im really confused if anyone could help me i would really appreciate it.
Ive tried changing else if. Removing code just trying print statements in it its ad if the function
//
// ViewController.swift
// clicker
///Users/ishaanrao/Desktop/Swift/clicker/clicker/Base.lproj/Main.storyboard
// Created by Ishaan Rao on 8/1/19.
// Copyright © 2019 Ishaan Rao. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
//Properties
var x: Int = 0
#IBOutlet weak var selector: UISegmentedControl!
#IBOutlet weak var resetbtn: UIButton!
#IBOutlet weak var score: UILabel!
#IBOutlet var back: UIView!
//viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
resetbtn.backgroundColor = UIColor.black
resetbtn.setTitle("Reset", for: .normal)
resetbtn.setTitleColor(.white, for: .normal)
resetbtn.layer.masksToBounds = true
resetbtn.layer.cornerRadius = 5
score.backgroundColor = UIColor.blue
score.layer.masksToBounds = true
score.layer.cornerRadius = 5
score.textColor = UIColor.white
score.textAlignment = .center
// Do any additional setup after loading the view.
}
//methods
#IBAction func cookie(_ sender: Any) {
x += 1
score.text = "Score: \(x)"
}
#IBAction func reset(_ sender: Any) {
x = 0
score.text = "Score: \(x)"
}
#IBAction func darl(_ sender: Any, forEvent event: UIEvent) {
}
#IBAction func light(_ sender: Any) {
if selector.selectedSegmentIndex==0 {
resetbtn.backgroundColor = UIColor.black
resetbtn.setTitle("Reset", for: .normal)
resetbtn.setTitleColor(.white, for: .normal)
resetbtn.layer.masksToBounds = true
resetbtn.layer.cornerRadius = 5
score.backgroundColor = UIColor.blue
score.layer.masksToBounds = true
score.layer.cornerRadius = 5
score.textColor = UIColor.white
score.textAlignment = .center
} else if selector.selectedSegmentIndex==1 {
back.backgroundColor = .black
resetbtn.backgroundColor = UIColor.white
resetbtn.setTitle("Reset", for: .normal)
resetbtn.setTitleColor(.black, for: .normal)
resetbtn.layer.masksToBounds = true
resetbtn.layer.cornerRadius = 5
score.backgroundColor = UIColor.orange
score.layer.masksToBounds = true
score.layer.cornerRadius = 5
score.textColor = UIColor.black
score.textAlignment = .center
}
}
}
I want it to change colors but its not there are no errors

It appears that the IBAction just isn't linked to the button event. Try to link the Storyboard button TouchUpInside event to the action like this:
For more info, you can follow the Oficial Apple documentation

Related

If we click on the AddCommentsButton the AddCommentsTextView must enable. how to implement in swift iOS?

#IBOutlet weak var AddCommentsButton: UIButton!
#IBOutlet weak var AddCommentsTextView: UITextView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
self.AddCommentsButton.setTitle("Add Comments", for: UIControl.State.normal)
self.AddCommentsButton.setTitleColor(UIColor.blue, for: UIControl.State.normal)
AddCommentsTextView.rchDelegate = self as? RCHTextViewDelegate
AddCommentsTextView.delegate = self as? UITextViewDelegate
AddCommentsTextView.placeholder = "Leave a comment"
AddCommentsTextView.canShowBorder = true
AddCommentsTextView.addBorderWithCornerRadius(cornerRadius: 0, borderColor: .Gray, borderWidth: 0.5)
AddCommentsTextView.backgroundColor = UIColor.clear
self.AddCommentsTextView.font = UIFont.dynamicFont(control: .listKeyText)
self.AddCommentsTextView.textColor = UIColor.listKeyTextColor()
}
#IBAction func didTapAddCommentsButton(_ sender: Any) {
}
If you are looking for when you click on didTapAddCommentsButton button then the AddCommentsTextView Textview should show the cursor in the textview for entering the text then you can use:
#IBAction func didTapAddCommentsButton(_ sender: Any) {
self.AddCommentsTextView.becomeFirstResponder()
}
So that on button click it will enable textview cursor for entering purpose.
UPDATED:
If you want to remove focus from the text entry then use:
self.AddCommentsTextView.resignFirstResponder()

Edit- How can I add that when the answer is wrong it will turn red and green in the correct answer? Swift 4.2

Creates a quiz game
How can I add that when the answer is incorrect, the incorrect answer will turn red and the correct answer will turn green at the same time?
How can I make the colors disappear when the new question comes? I have it that when you press an answer, a new question will come right after that
EDIT: This code is working fine.
#IBOutlet var options: [UIButton]!
#IBOutlet weak var questionLabel: UILabel!
#IBOutlet weak var progressView: UIView!
var allQuestions = QuestionBank()
var Number: Int = 0
var selectedAnswer: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
oppdatertekst()
options.forEach {
$0.layer.cornerRadius = 20
$0.backgroundColor = UIColor.orange
$0.setTitleColor(UIColor.black, for: .normal)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func answerPressed(_ sender: UIButton) {
feedback()
if sender.tag == selectedAnswer {
sender.backgroundColor = UIColor.green
let riktig = NSLocalizedString("Quiz.riktig", comment: "")
ProgressHUD.showSuccess(riktig)
} else if let correctOption = options.first(where: { $0.tag == selectedAnswer }) {
let feilnr = NSLocalizedString("Quiz.feilnr", comment: "")
ProgressHUD.showError("\(feilnr)\(selectedAnswer)")
correctOption.backgroundColor = UIColor.green
sender.backgroundColor = UIColor.red
}
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
self.Number += 1
self.oppdatertekst()
}
}
func oppdaterSpm() {
if Number <= allQuestions.list.count - 1{
questionLabel.text = allQuestions.list[Number].question
options.forEach {
$0.backgroundColor = .white
}
options[0].setTitle(allQuestions.list[Number].optionA, for: .normal)
options[1].setTitle(allQuestions.list[Number].optionB, for: .normal)
options[2].setTitle(allQuestions.list[Number].optionC, for: .normal)
options[3].setTitle(allQuestions.list[Number].optionD, for: .normal)
selectedAnswer = allQuestions.list[Number].correctAnswer
} else {
let alert....
}
}
Instead of having four IBOutlets use IBOutletCollection and connect these four buttons to this collection.
In answerPressed method if the correct answer is selected change clicked button color to green. If the wrong answer is selected change selected answer color to red, then get the correct answer button from the collection and change its color to green. After 5 seconds reload next question.
class ViewController: UIViewController {
#IBOutlet var options: [UIButton]!
#IBOutlet weak var questionLabel: UILabel!
#IBOutlet weak var progressView: UIView!
var allQuestions = QuestionBank()
var Number: Int = 0
var selectedAnswer: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
oppdatertekst()
options.forEach {
$0.layer.cornerRadius = 20
$0.backgroundColor = UIColor.orange
$0.setTitleColor(UIColor.black, for: .normal)
}
}
#IBAction func answerPressed(_ sender: UIButton) {
feedback()
if sender.tag == selectedAnswer {
sender.backgroundColor = UIColor.green
let riktig = NSLocalizedString("Quiz.riktig", comment: "")
ProgressHUD.showSuccess(riktig)
} else if let correctOption = options.first(where: { $0.tag == selectedAnswer }) {
let feilnr = NSLocalizedString("Quiz.feilnr", comment: "")
ProgressHUD.showError("\(feilnr)\(selectedAnswer)")
correctOption.backgroundColor = UIColor.green
sender.backgroundColor = UIColor.red
}
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
Number += 1
oppdatertekst()
}
}
}
Change all buttons color in oppdaterSpm method
func oppdaterSpm() {
if Number <= allQuestions.list.count - 1{
questionLabel.text = allQuestions.list[Number].question
options.forEach {
$0.backgroundColor = .white
}
options[0].setTitle(allQuestions.list[Number].optionA, for: .normal)
options[1].setTitle(allQuestions.list[Number].optionB, for: .normal)
options[2].setTitle(allQuestions.list[Number].optionC, for: .normal)
options[3].setTitle(allQuestions.list[Number].optionD, for: .normal)
selectedAnswer = allQuestions.list[Number].correctAnswer
} else {
let alert....
}
}
You have to write UIButton changes in common method. Call it anywhere.
When New Question Comes:
func whenNewQuestionComes() {
optionA.layer.cornerRadius = 20
optionA.backgroundColor = UIColor.orange
optionA.setTitleColor(UIColor.black, for: .normal)
optionB.layer.cornerRadius = 20
optionB.backgroundColor = UIColor.orange
optionB.setTitleColor(UIColor.black, for: .normal)
optionC.layer.cornerRadius = 20
optionC.backgroundColor = UIColor.orange
optionC.setTitleColor(UIColor.black, for: .normal)
optionD.layer.cornerRadius = 20
optionD.backgroundColor = UIColor.orange
optionD.setTitleColor(UIColor.black, for: .normal)
}
Show Green and Red
#IBAction func answerPressed(_ sender: UIButton) {
feedback()
optionA.backgroundColor = UIColor.red
optionB.backgroundColor = UIColor.red
optionC.backgroundColor = UIColor.red
optionD.backgroundColor = UIColor.red
if sender.tag == selectedAnswer {
sender.backgroundColor = UIColor.green
let riktig = NSLocalizedString("Quiz.riktig", comment: "")
ProgressHUD.showSuccess(riktig)
}
/*
else if let correctOption = options.first(where: { $0.tag == selectedAnswer }) {
let feilnr = NSLocalizedString("Quiz.feilnr", comment: "")
ProgressHUD.showError("\(feilnr)\(selectedAnswer)")
correctOption.backgroundColor = UIColor.green
sender.backgroundColor = UIColor.red
}
*/
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
self.Number += 1
self.oppdatertekst()
}
}

How do I set my variable correctly to a value on Firebase and not have it reset the progress?

Everytime I leave this ViewController and then come back the quiz starts back to question 1. I want it to resume from where I left off.
I believe why it keeps resetting to zero is because my initial "questionNumber" is set to 0 but I'm not sure how to set its value to the value in Firebase correctly. I get error after error. I've tried so many different ways but none of them seem to work and resume from where I left off.
Thanks for your help! PLEASE help me!
class CryptoViewController: UIViewController {
var questionList = CryptoBank()
var score = 0
var pickedQuestion = 0
var uid = FIRAuth.auth()?.currentUser?.uid
var questionNumber = 0
#IBOutlet weak var questionViewer: UILabel!
#IBOutlet weak var choiceOne: UIButton!
#IBOutlet weak var choiceTwo: UIButton!
#IBOutlet weak var choiceThree: UIButton!
#IBOutlet weak var scoreLabel: UILabel!
#IBOutlet weak var questionNumberView: UILabel!
#IBOutlet weak var progressBarView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
choiceOne.titleLabel?.textAlignment = NSTextAlignment.center
choiceTwo.titleLabel?.textAlignment = NSTextAlignment.center
choiceThree.titleLabel?.textAlignment = NSTextAlignment.center
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.view.backgroundColor = .clear
update()
}
#IBAction func buttonPressed(_ sender: AnyObject) {
if sender.tag == 1 {
pickedQuestion = 1}
else if sender.tag == 2 {
pickedQuestion = 2}
else if sender.tag == 3 {
pickedQuestion = 3}
checkAnswer()
questionNumber += 1
nextQuestion()
}
func checkAnswer(){
let correctAnswer = questionList.cryptoBank[questionNumber].answer
if pickedQuestion == correctAnswer {
score += 1
}else{
print("Wrong Answer")
}
}
func updateFirebase(){
let ref = FIRDatabase.database().reference()
guard let uid = FIRAuth.auth()?.currentUser!.uid else{
return}
ref.child("Users").child(uid).child("Cryptoquiz").child("Question Number").setValue(questionNumber)
ref.child("Users").child(uid).child("Cryptoquiz").child("Score").setValue(score)
}
func nextQuestion(){
if questionNumber <= 9 {
update()
} else{
scoreLabel.text = "Score: \(score)"
let alert = UIAlertController(title: "Done!", message: "Would you like to restart?", preferredStyle: .alert)
let restartAction = UIAlertAction(title: "Restart", style: .default, handler: { (UIAlertAction) in
self.startAgain()
})
alert.addAction(restartAction)
present(alert, animated: true, completion: nil)
}}
func update(){
let nextQuest = questionList.cryptoBank[questionNumber]
questionViewer.text = nextQuest.question
choiceOne.setTitle(nextQuest.choice1, for: .normal)
choiceTwo.setTitle(nextQuest.choice2, for: .normal)
choiceThree.setTitle(nextQuest.choice3, for: .normal)
scoreLabel.text = "Score: \(score)"
questionNumberView.text = "Question: \(questionNumber + 1)"
progressBarView.frame.size.width = (view.frame.size.width/9) * CGFloat(questionNumber + 1)
updateFirebase()
}
}
You can save your progress in UserDefaults in viewDidDisappear() like this:
UserDefaults.standard.set(questionNumber, forKey: "questionNumber")
And then every time you open your view, in viewDidLoad() or in viewDidAppear() you update your questionNumber like this:
let questionNumberSaved = UserDefaults.standard.integer(forKey: “questionNumber”) ?? 0
questionNumber = questionNumberSaved
Then after doing this you call your updateFirebase() method

selecting with UIButton and moving a specific model data with segue

I am new to swift and new to programming in general. I am building a quiz app. I want to select a topic in a TopicViewController and move to a new Quizviewcontroller that will display the question and answer choices. I have multiple question bank that I believe are objects of a class Question. I am able to move to the QuizViewConctroller with segue but unable to select the Question bank based on the topic UI button selected.
I have tried and spent days trying to figure this out. I have looked at similar posts in SO. I have posted this question before but did not get any reply. I would really appreciate if someone could help. I don't know how else to proceed...
TopicsViewController:
import UIKit
class TopicsViewController: UIViewController, ReturnToTopicVCDelegate {
func goToTopicVC() {}
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func goToQuestionsVCWhenPressed(_ sender: UIButton) {
performSegue(withIdentifier: "segueToQuestionVC", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueToQuestionVC" {
let quizVC = segue.destination as! QuizViewController
quizVC.delegate = self
}
}
}
QuizViewController:
import UIKit
import QuartzCore
protocol ReturnToTopicVCDelegate {
func goToTopicVC()
}
class QuizViewController: UIViewController {
var delegate: ReturnToTopicVCDelegate?
#IBOutlet weak var questionLabel: UILabel!
#IBOutlet weak var questionImageView: UIImageView!
#IBOutlet weak var optionAButton: UIButton!
#IBOutlet weak var optionBButton: UIButton!
#IBOutlet weak var optionCButton: UIButton!
#IBOutlet weak var optionDButton: UIButton!
#IBOutlet weak var optionEButton: UIButton!
//outlets for the progress
#IBOutlet weak var questionCounter: UILabel!
#IBOutlet weak var scoreLabel: UILabel!
var allQuestions = QuestionBank()
var selectedAnswer: Int = 0 // answer selected by the subject
var questionNumber: Int = 0
var score: Int = 0
#IBAction func answerPressed(_ sender: UIButton) {
if sender.tag == selectedAnswer {
print("correct answer")
sender.backgroundColor = .green
score += 1
} else {
print("wrong")
sender.backgroundColor = .red
print("\(allQuestions.list[questionNumber].correctAnswer)")
//the following two lines change the right answer button to green using the tag value of the button
let correctAnswerButton = view.viewWithTag(selectedAnswer) as? UIButton
correctAnswerButton?.backgroundColor = UIColor.green
}
}
#IBAction func GoToNextQuestion(_ sender: UIButton) {
questionNumber += 1
nextQuestion()
}
func nextQuestion() {
if questionNumber <= allQuestions.list.count - 1 {
questionLabel.text = allQuestions.list[questionNumber].question
questionImageView.image = UIImage(named: (allQuestions.list[questionNumber].questionImage))
optionAButton.setTitle(allQuestions.list[questionNumber].optionA, for: .normal)
optionBButton.setTitle(allQuestions.list[questionNumber].optionB, for: .normal)
optionCButton.setTitle(allQuestions.list[questionNumber].optionC, for: .normal)
optionDButton.setTitle(allQuestions.list[questionNumber].optionD, for: .normal)
optionEButton.setTitle(allQuestions.list[questionNumber].optionE, for: .normal)
selectedAnswer = allQuestions.list[questionNumber].correctAnswer
updateUI()
} else {
let alert = UIAlertController(title: "Great!", message: "Do you want to start over?", preferredStyle: .alert)
let restartAction = UIAlertAction(title: "Restart", style: .default) { (UIAlertAction) in
self.restartQuiz()
}
alert.addAction(restartAction)
present(alert, animated: true, completion: nil)
}
}
func updateUI() {
scoreLabel.text = "score: \(score)"
questionCounter.text = "\(questionNumber + 1)/\(allQuestions.list.count)"
}
func restartQuiz() {
score = 0
questionNumber = 0
nextQuestion()
}
#IBAction func goBackToTopicsVC(_ sender: Any) {
delegate?.goToTopicVC()
dismiss(animated: true, completion: nil)
}
}
The Questions are in this format
import Foundation
class QuestionBank {
var list = [Question]()
init() {
let skyColorQuestion = Question(questionText: “What is the color of sky?", image: "sky", choiceA: "blue", choiceB: "black", choiceC: "yellow", choiceD: "pink", choiceE: "None of the above", answer: 1)
let whatQuestion = Question(questionText: “what…?”, image: "image", choiceA: "x", choiceB: "y", choiceC: "z", choiceD: "m", choiceE: "None of the above", answer: 3)
list.append(skyColorQuestion)
list.append(whatQuestion)
}
}
Navigation Pane
Storyboard
Add the data are not correct in this way. My recommendation you can use a Realm, sqLite, CoreData or FireBase.

UIButton image in Swift does not change colors even after a function is created

I am using Xcode 8 and Swift 3, and am trying to create a button that changes colors when I click on it.
the button is black, but should turn blue when I click. The button is an image of a piggy bank.
I went ahead and added an image of the black pig and blue pig, with names money_off and money_on, respectively.
I am now in the process of writing code to turn the black image blue upon click. The code itself shows no errors, but the simulation was not successful. Clicking on the black piggy bank does nothing.
Does anyone have a clue what might be happening?
import UIKit
class SecondViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var label: UILabel!
let step: Float = 1
#IBOutlet weak var moneybutton: UIButton!
#IBOutlet var itemTextField: UITextField!
#IBAction func moneyClicked(_ sender: UIButton) {
if sender.currentImage === #imageLiteral(resourceName: "money_off"){
sender.setImage(#imageLiteral(resourceName: "money_on"), for: .normal)}
else {
sender.setImage(#imageLiteral(resourceName: "money_off"), for: .normal)
}
}
}
Try this-
class SecondViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var moneybutton: UIButton!
func viewDidLoad() {
self.moneybutton.setImage(UIImage(named:"money_on"), for: .selected)
self.moneybutton.setImage(UIImage(named:"money_off"), for: .normal)
}
#IBAction func moneyClicked(_ sender: UIButton) {
self.moneybutton.isSelected = !self.moneybutton.isSelected
}
}
You better not rely on the return value of some #imageLiteral, but instead keep a state, like moneyOff in the example code below.
(sorry, no Xcode available, so code might contain some syntax errors, but you'll get the idea):
class SecondViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var label: UILabel!
let step: Float = 1
var moneyOff = true
#IBOutlet weak var moneybutton: UIButton!
#IBOutlet var itemTextField: UITextField!
#IBAction func moneyClicked(_ sender: UIButton) {
if moneyOff {
sender.setImage(#imageLiteral(resourceName: "money_on"), for: .normal)}
else {
sender.setImage(#imageLiteral(resourceName: "money_off"), for: .normal)
}
moneyOff = !moneyOff // toggle state
}
}
I guess problem is your connection between storyboard and view controller.
I try to add button programmatically and it work.
import UIKit
import AVFoundation
class ViewController: UIViewController {
lazy var btn: UIButton = {
let btn = UIButton()
btn.translatesAutoresizingMaskIntoConstraints = false
btn.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleClicked)))
btn.isUserInteractionEnabled = true
btn.setImage(UIImage(named: "money_off"), for: .normal)
return btn
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .green
view.addSubview(btn)
btn.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
btn.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 50).isActive = true
btn.widthAnchor.constraint(equalToConstant: 50).isActive = true
btn.heightAnchor.constraint(equalToConstant: 10).isActive = true
}
func handleClicked() {
if btn.currentImage == UIImage(named: "money_off") {
btn.setImage(UIImage(named: "money_on"), for: .normal)
} else {
btn.setImage(UIImage(named: "money_off"), for: .normal)
}
}
}
Below code is work for me:
class ViewController: UIViewController {
#IBOutlet weak var moneybutton: UIButton!
func viewDidLoad()
{
moneybutton.setImage(UIImage(named:"money_on"), for: .selected)
moneybutton.setImage(UIImage(named:"money_off"), for: .normal)
}
#IBAction func moneyClicked(_ sender: UIButton)
{
if self.btn.isSelected
{
self.moneybutton.isSelected = false
}
else{
self.moneybutton.isSelected = true
}
}