Update CoreData Value with UISwitch in UITableViewCell - uitableview

Just learning so I am sure there are much better ways to code what I have so far. Anyways, I have a simple task list that is saved to core data. You can segue to another VC where you can edit or create new task. I wanted to be able to put a uiswitch in the custom cell that would allow you to set the task as complete and then reload the tableview. I have searched all over and found this Select UITableView's row when tapping on its UISwitch in Swift but can't seem to translate a solution. Any help would be great.
enter image description here
I am not sure if I am supposed to code the save within the custom cell or just or pass delegate.
Here is my custom cell
protocol SettingCellDelegate : class {
func didChangeSwitchState(sender: TaskCell, isOn: Bool)
}
class TaskCell: UITableViewCell {
var delegate: SettingCellDelegate!
#IBOutlet weak var taskImage: UIImageView!
#IBOutlet weak var arrowImage: UIImageView!
#IBOutlet weak var dueDateLabel: UILabel!
#IBOutlet weak var dueDateValue: UILabel!
#IBOutlet weak var dueTimeLabel: UILabel!
#IBOutlet weak var dueTimeValue: UILabel!
#IBOutlet var taskCellStatus: UITextField!
#IBOutlet var taskCellSwitchDisplay: UISwitch!
#IBAction func taskCellSwitchAction(sender: AnyObject) {
if (taskCellSwitchDisplay.on) {
taskCellStatus.text = "Completed"
} else {
taskCellStatus.text = "Active"
}
}
#IBOutlet weak var taskNameValue: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
delegate = self
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
taskCellSwitchDisplay.addTarget(self, action: "switchChanged:", forControlEvents: UIControlEvents.ValueChanged)
}
func configureCell(task: Tasks) {
taskImage.image = UIImage(named: "Icon.png")
arrowImage.image = UIImage(named: "arrow_filled.png")
dueDateLabel.text = "Due Date:"
dueDateValue.text = task.taskDate
dueTimeLabel.text = "Due Time:"
dueTimeValue.text = task.taskTime
taskNameValue.text = task.taskName
taskCellStatus.text = task.status
//taskCellStatus.hidden = true
if (taskCellStatus.text == "Completed") {
taskCellSwitchDisplay.on = true
} else {
taskCellSwitchDisplay.on = false
}
}
func switchChanged(taskCellSwitchDisplay: UISwitch) {
_ = taskCellSwitchDisplay.on
if taskCellSwitchDisplay.on == true {
let switchValue = "Completed"
print("Switch Variable: \(switchValue)")
delegate.didChangeSwitchState(self, isOn: true)
} else {
let switchValue = "Active"
print("Switch Variable: \(switchValue)")
delegate.didChangeSwitchState(self, isOn: false)
}
}
Here is where I am getting the delegate in my tableview
extension TaskCell: SettingCellDelegate {
func didChangeSwitchState(sender: TaskCell, isOn: Bool) {
if isOn == true {
print("true")
} else {
print("false")
}
}

Related

Can't use constraints for cell with .xib file

I need to set constraints for a UILabel, but whenever I try to add a constraint for my UITableViewCell it messes up, and the element goes to the top left corner it seems
Here's how I set up my UI elements
Here's how it looks like when I run in a simulator
"Food" is the "English Meaning" UILabel
Here's my code for the cell file that's generated with the xib
class ReusableCell: UITableViewCell {
#IBOutlet weak var arabicMeaning: UILabel!
#IBOutlet weak var englishMeaning: UILabel!
#IBOutlet weak var upvoteButton: UIButton!
#IBOutlet weak var downvoteButton: UIButton!
#IBOutlet weak var upvoteCount: UILabel!
#IBOutlet weak var downvoteCount: UILabel!
var upFlag = true
var downFlag = true
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
static func nib() -> UINib{
return UINib(nibName: K.ReusableCell, bundle: nil)
}
#IBAction func ReviewPressed(_ sender: UIButton) {
if upFlag && downFlag{
if sender == upvoteButton{
upvoteCount.text = String(Int(upvoteCount.text!)! + 1)
}
else {
downvoteCount.text = String(Int(downvoteCount.text!)! + 1)
}
}
else if sender == upvoteButton && upFlag{
upFlag = false
downFlag = true
upvoteCount.text = String(Int(upvoteCount.text!)! + 1)
}
else if sender == downvoteButton && downFlag{
upFlag = true
downFlag = false
downvoteCount.text = String(Int(downvoteCount.text!)! + 1)
}
}
}

Updates on View Controller Disappear After Segue

I've been working through a project and have gotten most of the functionality straight, however there's one part that continues to stump me. I am using MVC format, and I have a two view controllers (one profile and one game). When progress is made on the game, the proper changes to game view controller show (i.e. button disappears and UI background color changes colors). However, when I segue to profile view controller using 'back' on navigation bar and return to the game view controller, the game view controller returns to the default without reflecting game progress.
I've tried unwinding segue, making a delegate going from view controller to model responsible for game play, adjusting my game logic, and trying viewdidload and viewwillappear. I'm running out of ideas.
Here are samples of pertinent code:
Game View Controller
import UIKit
import Firebase
class GameController: UIViewController, BrainDelegate, UITextFieldDelegate {
#IBOutlet weak var dateUsername: UILabel!
#IBOutlet weak var questionText: UILabel!
#IBOutlet weak var scoreText: UILabel!
#IBOutlet weak var answerOne: UITextField!
var userListOne: [String] = []
#IBOutlet weak var answerTwo: UITextField!
#IBOutlet weak var answerThree: UITextField!
#IBOutlet weak var answerFour: UITextField!
#IBOutlet weak var enterOne: UIButton!
#IBOutlet weak var enterTwo: UIButton!
#IBOutlet weak var enterThree: UIButton!
#IBOutlet weak var enterFour: UIButton!
#IBOutlet weak var feedbackText: UILabel!
#IBAction func logoutPressed(_ sender: UIBarButtonItem) {
do {
try Auth.auth().signOut()
navigationController?.popToRootViewController(animated: true)
} catch let signOutError as NSError {
print ("Error signing out: %#", signOutError)
}
}
let db = Firestore.firestore()
var questions = [Question]()
var Brain = Brain()
var delegate: brainDelegate?
//variables for delegate with json data
var questioner : String?
var dater : String?
var a1 : String?
var a2 : String?
var a3 : String?
var a4 : String?
//For game play
var answer1: String?
var answer2: String?
var answer3: String?
var answer4: String?
var puzzlesCompleted = "0"
func didUpdateBrain(narratives: [Question]) {
self.questions = narratives
}
func didFailWithError(error: Error) {
print(error)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
minketBrain.delegate = self
answerOne.delegate = self
answerTwo.delegate = self
answerThree.delegate = self
answerFour.delegate = self
if let localData = minketBrain.readLocalJSONFile(forName: K.minketClues) {
minketBrain.parseJSON(jsonData: localData)
}
//Transfer data from Profile Controller
self.questionText.text = questioner
self.dateUsername.text = dater
self.answer1 = a1
self.answer2 = a2
self.answer3 = a3
self.answer4 = a4
}
override func viewWillAppear(_ animated: Bool) {
view.reloadInputViews()
answerOne.text = userListOne.last
}
//MARK: - Button Logic
#IBAction func enterPressed(_ sender: UIButton) {
enterPressedOne()
allRight()
}
//Other buttons replicate the same code above
//MARK: - Correct Answer Logic
func allRight(){
if answerOne.backgroundColor == UIColor.green && answerTwo.backgroundColor == UIColor.green && answerThree.backgroundColor == UIColor.green && answerFour.backgroundColor == UIColor.green {
feedbackText.text = K.congratsText
puzzlesCompleted = "1"
if let allAnswer = scoreText.text, let userName = Auth.auth().currentUser?.email{
db.collection(K.FStore.collectionName).addDocument(data: [K.FStore.userName:userName, K.FStore.clueDate:dateUsername.text!, K.FStore.totalPoints:allAnswer, K.FStore.completionField:puzzlesCompleted]) { (error) in
if let e = error{
print("There was an error in data collection to Firestore \(e)")
}else{
print("Successfully saved data")
}
}
}
}
}
//MARK: - Update UI-Each Question
func enterPressedOne(){
if let item = answerOne.text, item.isEmpty == true { // need to make sure we have something here
userListOne.append(item) // store it in our data holder
print(userListOne)
}
if answerOne.text == self.answer1!.lowercased(){
answerOne.backgroundColor = UIColor.green
enterOne.isHidden = true
answerOne.isEnabled = false
}else{
answerOne.backgroundColor = UIColor.red
}
}
}
Unwind segue function in my profile controller
#IBAction func unwindToDestinationViewController (sender: UIStoryboardSegue){
print("Unwind")
}

IOS Updating button title and updating array with button value?

I am new to IOS Development and am implementing IOS QUIZ App.
How to update question and answers in QUIZ app.
Please check below my code this is how I am displaying.
#IBOutlet weak var prevBtn: UIButton!
#IBOutlet weak var nxtBtn: UIButton!
#IBOutlet weak var qstnlbl: UILabel!
#IBOutlet weak var answerABtn: UIButton!
#IBOutlet weak var answerBBtn: UIButton!
#IBOutlet weak var answerCBtn: UIButton!
#IBOutlet weak var answerDBtn: UIButton!
let questions = ["How many days are there in 1 year?", "Favorite color?", "Where was I born?"]
let answers = [["360", "365", "384", "377"], ["blue", "black", "green", "orange"], ["Tokyo", "New York", "Tennessee", "rajahmundry"]]
//Variables
var currentQuestion = 0
var rightAnswerPlacement:UInt32 = 0
var points = 0;
//Label
#IBOutlet weak var lbl: UILabel!
//Button
#IBAction func action(_ sender: AnyObject)
{
if (sender.tag == Int(rightAnswerPlacement))
{
print ("RIGHT!")
points += 1
}
else
{
print ("WRONG!!!!!!")
}
if (currentQuestion != questions.count)
{
newQuestion()
}
}
#IBAction func preAction(_ sender: AnyObject)
{
if (currentQuestion != questions.count)
{
newQuestion()
}
currentQuestion = currentQuestion - 1
}
#IBAction func nxtaction(_ sender: AnyObject)
{
if (currentQuestion != questions.count)
{
newQuestion()
}
currentQuestion = currentQuestion + 1
}
override func viewDidAppear(_ animated: Bool)
{
newQuestion()
}
//Function that displays new question
func newQuestion()
{
qstnlbl.text = questions[currentQuestion]
rightAnswerPlacement = arc4random_uniform(3)+1
//Create a button
var button:UIButton = UIButton()
var x = 1
for i in 1...4
{
//Create a button
button = view.viewWithTag(i) as! UIButton
button.setTitle(answers[currentQuestion][x], for: .normal)
x = 2
}
currentQuestion += 1
}
based on user selection answers has be to added to answerArray.
For Ex: if user selects in first question in answerABtn answer option "A " answerArray has to update with "A" value.
user can able to update answer
for Ex: user select 1st question answer option "b" answerArray has to update with "b" value.
please help me out to make this quiz app.
quiz app ui
enter image description here
There are quite a few things you should be doing differently, but to get you on your way...
You will want to create a answerArray variable to hold the user-selected answers. Inside your action func, you are already tracking which button was tapped, so append the button's title to your answer array at the same point.
Your current previous and next actions don't make any sense, because you are not tracking the question count correctly, and you are picking a random "correct" answer each time.
Here is your code, modified for:
better question count incrementing
tracking user selected answers in answerArray
clearing the screen when the quiz is complete
Note: this is just example code... this should not be considered "everything fixed" -- but it should help you with this step. Review the comments I've added to your code.
class QuizViewController: UIViewController {
#IBOutlet weak var prevBtn: UIButton!
#IBOutlet weak var nxtBtn: UIButton!
#IBOutlet weak var qstnlbl: UILabel!
#IBOutlet weak var answerABtn: UIButton!
#IBOutlet weak var answerBBtn: UIButton!
#IBOutlet weak var answerCBtn: UIButton!
#IBOutlet weak var answerDBtn: UIButton!
let questions = ["How many days are there in 1 year?", "Favorite color?", "Where was I born?"]
let answers = [["360", "365", "384", "377"], ["blue", "black", "green", "orange"], ["Tokyo", "New York", "Tennessee", "rajahmundry"]]
//Variables
var currentQuestion = 0
var rightAnswerPlacement:UInt32 = 0
var points = 0;
// array to hold answers
var answerArray: [String] = [String]()
//Label
#IBOutlet weak var lbl: UILabel!
//Button
#IBAction func action(_ sender: AnyObject)
{
// make sure this came from a button, and get the button title
guard let btn = sender as? UIButton,
let btnTitle = btn.currentTitle else { return }
if (btn.tag == Int(rightAnswerPlacement))
{
print ("RIGHT!")
points += 1
}
else
{
print ("WRONG!!!!!!")
}
// append the selected answer to the answerArray
answerArray.append(btnTitle)
// increment question counter
currentQuestion += 1
// if there are more questions
if (currentQuestion < questions.count)
{
newQuestion()
}
else
{
quizComplete()
}
}
func quizComplete() -> Void {
[answerABtn, answerBBtn, answerCBtn, answerDBtn].forEach {
$0?.isHidden = true
}
qstnlbl.text = "Your score: \(points)"
}
// these two funcs do not make any sense as written
/*
#IBAction func preAction(_ sender: AnyObject)
{
if (currentQuestion != questions.count)
{
newQuestion()
}
currentQuestion = currentQuestion - 1
}
#IBAction func nxtaction(_ sender: AnyObject)
{
if (currentQuestion != questions.count)
{
newQuestion()
}
currentQuestion = currentQuestion + 1
}
*/
override func viewDidAppear(_ animated: Bool)
{
newQuestion()
}
//Function that displays new question
func newQuestion()
{
qstnlbl.text = questions[currentQuestion]
rightAnswerPlacement = arc4random_uniform(3)+1
for i in 1...4
{
// get a reference to a button
let button = view.viewWithTag(i) as! UIButton
button.setTitle(answers[currentQuestion][i-1], for: .normal)
}
// don't increment question count here
// increment it AFTER user answers the question (in button tap action)
//currentQuestion += 1
}
}
here you go:
import UIKit
class ViewController: UIViewController {
var emptyArray : [String] = []
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .red
}
#objc func buttonAction(sender: UIButton!) {
emptyArray.append("A")
print(emptyArray)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let button = UIButton()
button.frame = CGRect(x: self.view.frame.size.width - 300, y: 200, width: 100, height: 100)
button.backgroundColor = UIColor.blue
button.setTitle("Name your Button ", for: .normal)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
self.view.addSubview(button)
}
}
when you press the buttom over and over, the output to debug window is this
["A"]
["A", "A"]
["A", "A", "A"]
["A", "A", "A", "A"]

Not woking UIView ishidden after change UILabel text value in swift

I want to change uilabel value and show uiview that has hide like a popup windows.
When I touch a button, that code print "setPopupView 0".
but doesn't show settingView.
and I touch a button again.
print "setPopupView 0" and show settingView.
so When "settingLabelValueUnit text" has changed not show settingView,
but when "settingLabelValueUnit text" has not changed show settingView.
(It means "settingLabelValue text" is same as input value)
I don't know why.
Anyone can help me?
Thank you
here is my swift code.
class ViewController: UIViewController {
#IBOutlet weak var workoutScrollView: UIScrollView!
#IBOutlet weak var settingView: UIView!
#IBOutlet weak var settingLabelValueUnit: UILabel!
#IBOutlet weak var imgSettingBGcal: UIImageView!
#IBOutlet weak var imgSettingBGdis: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
self.imgSettingBGcal.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(calSettingClick)))
self.imgSettingBGdis.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(disSettingClick)))
}
func calSettingClick(sender: UITapGestureRecognizer) {
setPopupView(0)
}
func disSettingClick(sender: UITapGestureRecognizer) {
setPopupView(1)
}
func showPopup (_ settype:Int) {
switch settype {
case 0:
print("setPopupView 0")
self.settingLabelValueUnit.text = "Set1"
self.workoutScrollView.isHidden = true
self.settingView.isHidden = false
case 1:
print("setPopupView 0")
self.settingLabelValueUnit.text = "Set2"
self.workoutScrollView.isHidden = true
self.settingView.isHidden = false
}
}
}

How to access IBoutlet of one view controller in another view controller using swift?

How can I change the label text to textfield text?
This source code change the label text to textfield text which are in the same class, but I want to change the label in different class.
label is in the ViewController.swift and textfield is in the ProfileViewController.swift
This is the source code:
ViewController.swift
import UIKit
import Social
class ViewController: UIViewController, SideBarDelegate {
#IBOutlet weak var name: UILabel!
#IBOutlet weak var hedgeImage: UIImageView!
#IBOutlet weak var hideView: UIView!
var sideBar:SideBar = SideBar()
override func viewDidLoad() {
}
ProfileViewController.swift
class ProfileViewController: UIViewController {
#IBOutlet weak var ouput: UILabel!
#IBOutlet weak var name: UITextField!
#IBAction func nameChange(sender: AnyObject) {
ouput.text = name.text
}
}
One of the many ways to do this: You can add an observer to textField and update a variable that holds the name text which then you can send to the new vc in prepare for segue. Here is a sample
class ViewController: UIViewController {
var nameRecieved:String?
#IBOutlet weak var name: UILabel!{
didSet{
if nameRecieved != nil { name.text = nameRecieved }
}
}
}
class ProfileViewController: UIViewController, UITextFieldDelegate {
var nameHolder:String?
#IBOutlet weak var name: UITextField! { didSet{ name.delegate = self } }
//notification
var nameTextFieldObserver: NSObjectProtocol?
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let center = NSNotificationCenter.defaultCenter()
let q = NSOperationQueue.mainQueue()
nameTextFieldObserver = center.addObserverForName(UITextFieldTextDidChangeNotification, object: name, queue: q){
notification in
self.nameHolder = self.name.text
}
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
if nameTextFieldObserver != nil { NSNotificationCenter.defaultCenter().removeObserver(nameTextFieldObserver!) }
}
//Here you can pass the value of nameHolder to the other vc's var nameRecieved in your prepare for segue
}
You need to catch hold on to your ViewController object and pass the values. Something like this:
#IBAction func nameChange() {
ouput.text = name.text
// given both your views have a same parent
// and this view is the first child
let myViewController = parentViewController!.childViewControllers[1]
myViewController.name.text = name.text
myViewController.printLabelText()
}

Resources