mega-noob question:
So right now I'm just trying to test my variable system in my gpa project. When popup button is altered it alters the value of a courses point total for example
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
func UPDTmathG(_ sender: Any) {
if let title = (sender as AnyObject).titleOfSelectedItem, title == "A+" {
mathPoints = 4.3;
}
if let title = (sender as AnyObject).titleOfSelectedItem, title == "A" {
mathPoints = 4;
}
Now to test that these variables are actually changing an learn how to change string values.
testLabel.stringValue = String(mathPoints);
Ideally, when this added to the func UPDTmathG(_ sender: Any) {.
It would update the string value of the label to be the value of the variable, but the string isn't updating. Any ideas?
Thanks:)
Related
I am trying to store the value of the textfield String to Firebase but the debugger says "unable to read data (String)." Here is my code.
#IBAction func btnSelect(_ sender: Any) {
var Description: String = TextField.text ?? ""
}
Try declaring Description first outside of viewDidLoad(), then initialize it inside the function btnSelect()
I created an example without using the storyBoard and it is working
let TextField : UITextField = {
let txt = UITextField()
txt.text = "Hello World"
return txt
}()
var Description: String?
override func viewDidLoad() {
btnSelect()
}
func btnSelect() {
Description = TextField.text
print(Description)
}
If this does not work for you, it must be something to do with either how you are initializing TextField or something with your storyBoard.
I have 13 images named 1 to 13 in my project. I would like the UIImageView to change from image 1 to 2, then 3, then 4 and so on, at the click of a UIButton.
My current code when the UIButton is clicked:
#IBAction func button(sender: Any) {
cardImage.image = UIImage(named: 1)
}
So I know I need to store the value in a variable and initially set the value to 1. Add 1 to the value every time I click the UIButton. That value needs to be somehow linked to cardImage.Image = UIImage. How can I achieve this?
So create an array of your filenames in your view controller, and an index into that array:
class ViewController: UIViewController {
lazy var filenames: [String] = {
return Array(1...13).map {String($0)}
}()
var filenameIndex = 0
Then write a function to load one of your images and increment the index:
func fetchImage() -> UIImage? {
let result = UIImage(named: filenames[filenameIndex])
filenameIndex = (filenameIndex + 1) % filenames.count
return result
}
(You could also use Yury's approach of managing an integer index and converting that to a filename, but my approach will let you manage cycling through any array of image filenames, whether they are sequential numbers or not.)
You need to store your current image number value in a variable and increase in when the button is pressed.
let imagesCount: Int = 13
var currentImageNumber: Int = 1
#IBAction func didPressButton(sender: Any) {
cardImage.image = UIImage(named: "\(currentImageNumber)")
currentImageNumber += 1
if currentImageNumber > imagesCount {
currentImageNumber = 1
}
}
Or you can use a shorter version without if condition.
let imagesCount: Int = 13
var currentImageNumber: Int = 0
#IBAction func didPressButton(sender: Any) {
cardImage.image = UIImage(named: "\(currentImageNumber + 1)")
currentImageNumber += 1
currentImageNumber %= imagesCount
}
I am really struggling to pass the contents of one array from a view controller to another to set up the contents of a nscombobox. I have tried everything I can think of, prepare for segue, init; but nothing seems to work.
the program flow is as follows: the user enter a number into a text field and based on it an array with the size of the number is created. Once the user presses a button the next VC appears that has a combo box and inside that combo box those numbers need to appear. All my attempts result in an empty array being passed. Could someone please take a bit of time and help me out. Im sure I'm doing a silly mistake but cannot figure out what.
Code listing below:
Class that take the user input. At this stage I'm trying to pass the contents of the array in the next class as I gave up on prepare for segue because that one crashes because of nil error. Please note that prepare for segue is uncommented in the code listing just for formatting purposes here. Im my program it is commented out as I am using perform segue at the moment.
Any solution would be nice please. Thank you.
import Cocoa
class SetNumberOfFloorsVC: NSViewController {
//MARK: - Properties
#IBOutlet internal weak var declaredNumber: NSTextField!
internal var declaredFloorsArray = [String]()
private var floorValue: Int {
get {
return Int(declaredNumber.stringValue)!
}
}
//MARK: - Actions
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction private func setNumberOfFloors(_ sender: NSButton) {
if declaredNumber.stringValue.isEmpty {
let screenAlert = NSAlert.init()
screenAlert.messageText = "Please specify the number of floors!"
screenAlert.addButton(withTitle: "Got it!")
screenAlert.runModal()
} else if floorValue == 0 || floorValue < 0 {
let screenAlert = NSAlert.init()
screenAlert.messageText = "Please input a correct number of floors!"
screenAlert.addButton(withTitle: "Got it!")
screenAlert.runModal()
} else {
for i in 0...floorValue - 1 {
declaredFloorsArray.append(String(i))
}
print("\(declaredFloorsArray)")
let declareNumberOfRoomsVC = SetNumberOfRoomsForFloorVC(boxData: declaredFloorsArray)
declareNumberOfRoomsVC.boxData = declaredFloorsArray
performSegue(withIdentifier: "set number of rooms", sender: self)
}
}
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
if segue.identifier == "set number of rooms" {
if let addRoomsVC = segue.destinationController as? SetNumberOfRoomsForFloorVC {
addRoomsVC.floorBox.addItems(withObjectValues: declaredFloorsArray)
}
}
}
}
this is the class for the next VC with the combo box:
import Cocoa
class SetNumberOfRoomsForFloorVC: NSViewController, NSComboBoxDelegate, NSComboBoxDataSource {
//MARK: - Properties
#IBOutlet internal weak var floorBox: NSComboBox!
#IBOutlet private weak var numberOfRoomsTxtField: NSTextField!
internal var boxData = [String]()
//MARK: - Init
convenience init(boxData: [String]) {
self.init()
self.boxData = boxData
}
//MARK: - Actions
override func viewDidLoad() {
super.viewDidLoad()
floorBox.usesDataSource = true
floorBox.dataSource = self
floorBox.delegate = self
print("\(boxData)")
}
#IBAction private func setRoomsForFloor(_ sender: NSButton) {
}
//MARK: - Delegates
func numberOfItems(in comboBox: NSComboBox) -> Int {
return boxData.count
}
func comboBox(_ comboBox: NSComboBox, objectValueForItemAt index: Int) -> Any? {
return boxData[index]
}
}
First you should remove the following code.
let declareNumberOfRoomsVC = SetNumberOfRoomsForFloorVC(boxData: declaredFloorsArray)
declareNumberOfRoomsVC.boxData = declaredFloorsArray
I assume you think that the viewController you created here is passed to prepareForSegue. However the storyboard instantiates a new viewController for you.
After that you need to set your declaredFloorsArray as the the boxData of the new viewController in prepareForSegue and you should be good to go.
I would like to call a function which is coded on another class.
So far I have made a struct on the file structs.swift for my data:
struct defValues {
let defCityName: String
let loadImages: Bool
init(defCity: String, loadImgs: Bool){
self.defCityName = defCity
self.loadImages = loadImgs
}
}
I have made the file Defaults.swift containing:
import Foundation
class DefaultsSet {
let cityKey: String = "default_city"
let loadKey: String = "load_imgs"
func read() -> defValues {
let defaults = NSUserDefaults.standardUserDefaults()
if let name = defaults.stringForKey(cityKey){
print(name)
let valuesToReturn = defValues(defCity: name, loadImgs: true)
return valuesToReturn
}
else {
let valuesToReturn = defValues(defCity: "No default city set", loadImgs: true)
return valuesToReturn
}
}
func write(city: String, load: Bool){
let def = NSUserDefaults.standardUserDefaults()
def.setObject(city, forKey: cityKey)
def.setBool(load, forKey: loadKey)
}
}
in which I have the two functions read, write to read and write data with NSUsersDefault respectively.
On my main ViewController I can read data with:
let loadeddata: defValues = DefaultsSet().read()
if loadeddata.defCityName == "No default city set" {
defaultCity = "London"
}
else {
defaultCity = loadeddata.defCityName
defaultLoad = loadeddata.loadImages
}
But when I try to write data it gives me error. I use this code:
#IBOutlet var settingsTable: UITableView!
#IBOutlet var defaultCityName: UITextField!
#IBOutlet var loadImgs: UISwitch!
var switchState: Bool = true
#IBAction func switchChanged(sender: UISwitch) {
if sender.on{
switchState = true
print(switchState)
}else {
switchState = false
print(switchState)
}
}
#IBAction func saveSettings(sender: UIButton) {
DefaultsSet.write(defaultCityName.text, switchState)
}
You need an instance of the DefaultsSet class
In the view controller add this line on the class level
var setOfDefaults = DefaultsSet()
Then read
let loadeddata = setOfDefaults.read()
and write
setOfDefaults.write(defaultCityName.text, switchState)
The variable name setOfDefaults is on purpose to see the difference.
Or make the functions class functions and the variables static variables and call the functions on the class (without parentheses)
From the code you posted, it seems you either need to make the write method a class method (just prefix it with class) or you need to call it on an instance of DefaultsSet: DefaultsSet().write(defaultCityName.text, switchState).
Another issue I found is that you also need to unwrapp the value of the textField. Your write method takes as parameters a String and a Bool, but the value of defaultCityName.text is an optional, so String?. This results in a compiler error.
You can try something like this:
#IBAction func saveSettings(sender: UIButton) {
guard let text = defaultCityName.text else {
// the text is empty - nothing to save
return
}
DefaultsSet.write(text, switchState)
}
This code should now compile and let you call your method.
Let me know if it helped you solve the problem
I have the following code written in SWIFT for OS X App, the code is working fine (NSComboBox are select able only, not editable)
I have these two IBOutlet projNewProjType and projNewRouter, when I change the the selection of either of the NSComboBox, I can see the correct selected Index value and String value but how to check that the returned Index value is from projNewProjType NOT projNewRouter in the comboBoxSelectionDidChange()
import Cocoa
class NewProjectSetup: NSViewController, NSComboBoxDelegate {
let comboxProjValue: [String] = [“No”,”Yes”]
let comboxRouterValue: [String] = ["No","Yes"]
#IBOutlet weak var projNewProjType: NSComboBox!
#IBOutlet weak var projNewRouter: NSComboBox!
#IBAction func btnAddNewProject(sender: AnyObject) {
print(“Add New Button Pressed!”)
}
#IBAction func btnCancel(sender: AnyObject) {
self.dismissViewController(self)
}
override func viewDidLoad() {
super.viewDidLoad()
addComboxValue(comboxProjValue,projNewProjType)
addComboxValue(comboxRouterValue,projNewRouter)
self.projNewProjType.selectItemAtIndex(0)
self.projNewRouter.selectItemAtIndex(0)
self.projNewProjType.delegate = self
self.projNewRouter.delegate = self
}
func comboBoxSelectionDidChange(notification: NSNotification) {
let comboBox: NSComboBox = (notification.object as? NSComboBox)!
print("comboBox comboBox: \(comboBox)")
/* This printed “<NSComboBox: 0x6000001e1a00>”*/
print("comboBox objectValueOfSelectedItem: \(comboBox.objectValueOfSelectedItem)")
/* This printed the correct selected String value */
print("comboBox indexOfSelectedItem: \(comboBox.indexOfSelectedItem)")
/* This printed the correct selected Index value */
}
/* Add value to Combo box */
func addComboxValue(myVal:[String],myObj:AnyObject){
let myValno: Int = myVal.count
for i in 0..<myValno{
myObj.addItemWithObjectValue(myVal[i])
}
}
}
You already know the addresses of your two NSComboBox outlets and you know the address of which NSComboBox caused that notification to trigger, so why not do something like:
func comboBoxSelectionDidChange(notification: NSNotification) {
let comboBox: NSComboBox = (notification.object as? NSComboBox)!
if comboBox == self.projNewProjType
{
print("selection changed via self.projNewProjType")
}
if comboBox == self.projNewRouter
{
print("selection changed via self.projNewRouter")
}
You can set identifiers to your NSComboBoxes in IB. Select your combo box and choose identity inspector and name identifier. Then you are able to do like this:
if comboBox.identifier == "someIdentifier" {
// Do something
}