Swift Combine question with UILabel subscribe - swift

import UIKit
import Combine
class ViewController: UIViewController {
#IBOutlet weak var allowMessageSwitch: UISwitch!
#IBOutlet weak var sendButton: UIButton!
#IBOutlet weak var messageLabel: UILabel!
#Published var canSendMessages: Bool = false
#Published var newMsg: String = ""
private var switchSubscriber: AnyCancellable?
private var btnSubscriber: AnyCancellable?
override func viewDidLoad() {
allowMessageSwitch.isOn = false
super.viewDidLoad()
setupProcesscingChain()
}
func setupProcesscingChain() {
switchSubscriber = $canSendMessages.receive(on: DispatchQueue.main).assign(to: \.isEnabled, on: sendButton)
btnSubscriber = $newMsg.receive(on: DispatchQueue.main).assign(to: \.text, on: messageLabel)
}
#IBAction func didSwitch (_ sender: UISwitch) {
canSendMessages = sender.isOn
}
#IBAction func sendMessage( _ sender: Any) {
}
}
I am getting error in
btnSubscriber = $newMsg.receive(on: DispatchQueue.main).assign(to: \.text, on: messageLabel)
error msg is
Type of expression is ambiguous without more context
I dont understand why label does not work as Switcher (bool)
I assume it is because \.isEnabled is not optional, and \.text is optional..??
how can I make this work with the same format. this is for practice and to understand how Combine works.. please help!

lableSubscriber = $newMsg.receive(on: DispatchQueue.main).assign(to: \.text!, on: messageLabel)
I solved it on my own! it was very simple.
just force unwrap the keyPath.

Related

Passing boolean from one View controller to another, both controlled by a Tab Controller

I've been looking at other questions/answers around this and I can't seem to find an answer thats worked for me. I'm making a game where you click a pizza and you generate money. You start off with only being able to generate one dollar through clicking but as you purchase Upgrades this number gains in value. In theory, when you click the level 1 upgrade button it will send a true value to the main game view, making a click earn 5 dollars instead of 1.
import UIKit
class GameViewController: UIViewController {
var wallet: Int = 0
var totalIncome: Int = 0
var level1UpgradeUsed: Bool = false
#IBOutlet weak var pizzaButton: UIButton!
#IBOutlet weak var labelWallet: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
print(level1UpgradeUsed)
// Do any additional setup after loading the view.
}
#IBAction func pizzaClick(_ sender: Any) {
let upgrades = UpgradesViewController()
let level1UpgradeUsed = upgrades.level1used
if level1UpgradeUsed == true {
wallet = wallet + 4
}
wallet = wallet + 1
labelWallet.text = ("$" + String(wallet))
}
In the upgrades controller I'm trying to send the true value once the button is clicked
import UIKit
class UpgradesViewController: UIViewController {
public var level1used: Bool = false
public var level2used: Bool = false
public var level3used: Bool = false
public var level4used: Bool = false
var level5used: Bool = false
#IBOutlet weak var buttonLevel1: UIButton!
#IBOutlet weak var buttonLevel2: UIButton!
#IBOutlet weak var buttonLevel3: UIButton!
#IBOutlet weak var buttonLevel4: UIButton!
#IBOutlet weak var buttonLevel5: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let gameViewController = segue.destination as? GameViewController {
gameViewController.level1UpgradeUsed = self.level1used
}
}
#IBAction func Level1Click(_ sender: Any) {
if level1used == false{
buttonLevel1.backgroundColor = UIColor.gray
level1used = true
}
else {
}
}
Im geussing I'm not utilizing the TabBarController to pass data and not sure at all how to go about doing that. I'm new to swift and teaching myself everything so I'm sorry if this seems like a redundant question. It feels like it should be a lot simpler then it looks.

Swift: Tracking User's score

I'm trying to create a Quiz app that consists of two buttons, false and true button. My question is, as I answer more questions in the app, I want the textLabel to keep track of my score. And then when I circle back to the first question again, it should reset. This is my code so far. I'm looking forward to your answers.
class ViewController: UIViewController {
#IBOutlet weak var questionLabel: UILabel!
#IBOutlet weak var progressBar: UIProgressView!
#IBOutlet weak var trueButton: UIButton!
#IBOutlet weak var falseButton: UIButton!
#IBOutlet weak var scoreLabel: UILabel!
var quizBrain = QuizBrain()
override func viewDidLoad() {
super.viewDidLoad()
updateUI()
progressBar.progress = 0.0
}
#IBAction func answerButtonPressed(_ sender: UIButton) {
let userAnswer = sender.currentTitle
let userGotItRight = quizBrain.checkAnswer(userAnswer!)
if userGotItRight {
sender.shortChangeTo(.green)
} else {
sender.shortChangeTo(.red)
}
quizBrain.nextQuestion()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.updateUI()
}
}
func updateUI() {
questionLabel.text = quizBrain.getQuestionText()
trueButton.backgroundColor = UIColor.clear
falseButton.backgroundColor = UIColor.clear
progressBar.progress = 33
scoreLabel.text = "Score: \(quizBrain.getScore)"
}
}
You don't have any code for it yet? You can create a struct like user
struct user {
var score: Int = 0
mutating func answerRight (){
self.score =+ 1 }
mutating func reset (){
self.score = 0 }
}
But I see this in your code "Score: (quizBrain.getScore)"
This says that quizBrain should know the score. But you never add a value to it So check your quizBrain and create a function or an object that can track the score and then call it here "if userGotItRight {}"

OS X Hello World Swift tutorial

So I'm following this tutorial for Swift and am not getting the desired result at the end. This is my code for the ViewController:
import Cocoa
class ViewController: NSViewController {
#IBOutlet weak var nameField: NSTextField!
#IBOutlet weak var helloLabel: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
#IBAction func sayButtonClicked(_ sender: Any) {
var name = nameField.stringValue
if name.isEmpty {
name = "World"
}
let greeting = "Hello \(name)!"
helloLabel.stringValue = greeting
}
}
And the following is the result:
When I debug the program however it does show the correct variables:
What am I doing wrong here?
Turns out I didn't stretch out the the Label field enough.

How to Store NSPopUpButton TitleOfSelectedItem to Core Data Model Field?

I have created the following view controller and wired up the controls in my storyboard to it.
import Foundation
import CoreData
import AppKit
protocol SubmissionViewControllerDelegate {
func controller(_controller: SubmissionViewController,
didAddSubmissionWithID profileID: Int64)
}
class SubmissionViewController : ViewController {
#IBOutlet var profileIDComboBox: NSPopUpButton!
var profileSelectedValue: String!
#IBOutlet var transcriptTypeComboBox: NSPopUpButton!
var transcriptTypeSelectValue: String!
#IBOutlet var submissionTypeComboBox: NSPopUpButton!
var submissionTypeSelectValue: String!
#IBOutlet var transcriptionTurnaroundComboBox: NSPopUpButton!
var turnaroundSelectValue: String!
#IBOutlet var persistentNoteComboBox: NSPopUpButton!
var persistentNoteSelectValue: String!
#IBOutlet var notesTextField: NSTextField!
#IBOutlet var batchIdentifierTextField: NSTextField!
#IBOutlet var languageInAudioComboBox: NSPopUpButton!
var languageSelectValue: String!
#IBOutlet var addResultViewButton: NSButton!
#IBOutlet var submissionFiles: NSTableView!
var delegate: SubmissionViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func save(_ sender: Any) {
guard case profileIDComboBox.titleOfSelectedItem =
profileSelectedValue else { return }
guard case transcriptTypeComboBox.titleOfSelectedItem =
transcriptTypeSelectValue else { return }
guard let delegate = delegate else { return }
delegate.controller(self, didAddSubmissionWithID:
profileSelectedValue)
}
}
I now want to store the titleOfSelectedItem from each NSPopUpButton in my Core Data Submission model. However, when I set the variables to be strings, I receive the error as follows:
Cannot convert value of type 'String?' to expected argument type '_OptionalNilComparisonType'
How do I accomplish this task?

Cannot convert value of type 'String?' to type 'NSString' in coercion

Im trying to make this calculator for various math formulas and I'm stuck at this point. I was following this tutorial
Here's my code:
import UIKit
class pythagorasViewController: UIViewController {
#IBOutlet weak var aLabel: UILabel!
#IBOutlet weak var bLabel: UILabel!
#IBOutlet weak var aField: UITextField!
#IBOutlet weak var bField: UITextField!
#IBOutlet weak var answerLabel: UILabel!
#IBAction func calculateButton(_ sender: UIButton) {
var a = (aField.text as NSString).floatValue
var b = (bField.text as NSString).floatValue
var answer = sqrt(a*a + b*b)
answerLabel.text = "\(answer)"
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
The part where I'm getting the error is at:
var a = (aField.text as NSString).floatValue
var b = (bField.text as NSString).floatValue
Prefer let to var when possible. You do not need to use NSString. You can cast String to Float?. You need to unwrap both the text property which is a String? (if you have a question about the type of a variable option click and it will show you) and the Float? conversion:
func calculateButton(_ sender: UIButton) {
guard let aText = aField.text,
let bText = bField.text,
let a = Float(aText),
let b = Float(bText) else {
return
}
let answer = sqrt(a*a + b*b)
answerLabel.text = "\(answer)"
}