I can't use instance member array within property initializer - xcode

import UIKit
class ViewController: UIViewController {
#IBOutlet var Text1: UITextField!
#IBOutlet var Text2: UITextField!
#IBOutlet var Text3: UITextField!
#IBOutlet var Label: UILabel!
let array = ["Frodo", "sam", "wise", "gamgee"]
let randomIndex = Int(arc4random_uniform(UInt32(array.count))) //Problem is here
#IBAction func button(_ sender: Any) {
Label.text = array[randomIndex]
}
}

You didn't ask any question so I assume you have problem with accessing count of array.
In general you can't access any of instance members until init is completed.
There are (at least) three solutions for your problem.
First is to override all init required by UIViewController and set randomIndex there.
Second is to use lazy for randomIndex:
lazy var randomIndex = {
Int(arc4random_uniform(UInt32(array.count)))
}()
Third is to use some model (class/struct) for those data and inject it to ViewController

You cannot run the line to get the random index on the top level of the class.
It must be located within a function / method:
#IBAction func button(_ sender: Any) {
let randomIndex = Int(arc4random_uniform(UInt32(array.count)))
Label.text = array[randomIndex]
}
And please conform to the naming convention that variable names start with a lowercase letter (text1, label).

Related

How to call function in NSViewController?

class CustViewController: NSViewController {
#IBOutlet weak var tableView: NSTableView!
#IBOutlet weak var statusLabel: NSTextField!
fileprivate var selectedOptionFromMenu = ""
#objc var contacts:[Person] = []
#objc var backUpContacts:[Person] = []
#IBAction func printCustomers(_ sender: Any?) {
I would like to call the printCustomers function from another class (NSWindowController). How is this coded in the NSWindowController class?
I tried the following:
let printAction = CustViewController.printCustomers(<#T##self: CustViewController##CustViewController#> )
but don't know how to code argument in this and this may be not be the way to do this?
I used an observer to notify when to run the code in the ViewController
The following is the code I used to accomplish this:
In the main WindowController
public let printNotification = Notification.Name("printNotification")
#IBAction func cashToMePrinting(_ sender: Any?) {
switch activeWindow {
case activeView.customerView:
let printCustNC = NotificationCenter.default
printCustNC.post(name: printNotification, object: nil)
default:
print()
}
}
Added the #IBAction to the responder chain using toolbar print item
Then in the ViewController I added:
#objc func reactToNotification(_ sender: Notification) {
// Do what you need, including updating IBOutlets
printCustomers(Any?.self)
}

Multiple UISwitches To Turn On/Off

I am new to swift and attempting to place 5 UISwitches on one View Controller. I would like each one to turn the other 4 (or other 1) switches off. I am having a pretty rough go of figuring this one out.. Each one I have named with a label of switch1, switch2, etc. through 5. However, when i type switch1 into the ViewController.swift the variable is not recognized. I assumed I'd be able to type switch1.enabled = false or something to that effect but I only get an error indicating switch1 is not recognized. Help!
You are doing wrong, if you want use switch in controller you must create outlet in view controller.
e.g.
class SwitchDemo: UIViewController{
#IBOutlet weak var switch1: UISwitch!
#IBOutlet weak var switch2: UISwitch!
#IBOutlet weak var switch3: UISwitch!
#IBOutlet weak var switch4: UISwitch!
#IBOutlet weak var switch5: UISwitch!
override func viewDidLoad() {
super.viewDidLoad()
}
// Create Switch Toggle Action
#IBAction func onClickSwitch1(_ sender: Any) {
if self.contactSwitch.isOn {
self.switch2.isOn = false
self.switch3.isOn = false
self.switch4.isOn = false
self.switch5.isOn = false
}else {
}
}
}

Passing a value from inputField to NSTextField

I'd like to pass string value from one NSTextField to another NSTextField pressing a button. I used for this for-in loop. I need to pass a value from inputField to visibleText1, then to visibleText2 and then to visibleText3. But it doesn't work.
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
#IBOutlet weak var inputField: NSTextField!
#IBOutlet weak var visibleText1: NSTextField!
#IBOutlet weak var visibleText2: NSTextField!
#IBOutlet weak var visibleText3: NSTextField!
func applicationDidFinishLaunching(aNotification: NSNotification) { }
func applicationWillTerminate(aNotification: NSNotification) { }
#IBAction func applyButton(sender: AnyObject) {
for u in (visibleText1.stringValue...visibleText3.stringValue) {
visibleText.stringValue[u] = inputField.stringValue
inputField.stringValue = ""
}
}
}
Xcode gives me an error:
// Type 'ClosedInterval<String>' does not conform to protocol 'SequenceType'
How how to do it right?
No you can't do that because you can't create a range of string values of different text fields.
You could make an array of the three fields and enumerate that:
#IBAction func applyButton(sender: AnyObject) {
for field in [visibleText1, visibleText2, visibleText3] {
field.stringValue = inputField.stringValue
}
inputField.stringValue = ""
}
or with the forEach function
#IBAction func applyButton(sender: AnyObject) {
[visibleText1, visibleText2, visibleText3].forEach {
$0.stringValue = inputField.stringValue
}
inputField.stringValue = ""
}
Resetting the inputField in the repeat loop would always apply an empty string after the first iteration.
There are several things wrong with this, but I will start with what will work:
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
#IBOutlet weak var inputField: NSTextField!
#IBOutlet weak var visibleText1: NSTextField!
#IBOutlet weak var visibleText2: NSTextField!
#IBOutlet weak var visibleText3: NSTextField!
func applicationDidFinishLaunching(aNotification: NSNotification) { }
func applicationWillTerminate(aNotification: NSNotification) { }
#IBAction func applyButton(sender: AnyObject) {
for u in [visibleText1, visibleText2, visibleText3] {
u.stringValue = inputField.stringValue
}
}
}
So what's wrong with the original?
1) Your (visibleText1.stringValue...visibleText3.stringValue) is of type String ... String, which is not what you intended. You need to have an array of NSTextFields.
2) visibleText.stringValue[u] is not even a thing. There is no variable visibleString, and even if it was an NSTextField - which I think is what you want it to be, it's .stringValue is a String, and not an array.
3) What are you doing setting inputField.stringValue = "" inside the for loop? If your construct worked, only the first field would be set.
4) Not an error, but why are you doing all of this inside NSApplicationDelegate, rather than a viewController?

Xcode 7 missing setter or instance variable

I just have a strange trouble. I written a test app, that searches min & max of array values. In first times apps works normally, but only had a warning: "Array MinMax[554:5057] Failed to connect (exitNow) outlet from (Array_MinMax.ViewController) to (NSButton): missing setter or instance variable"
Now, several days later, i started app again, enter some values, pushed button and app instantly crush with same error:
2016-06-15 12:11:40.910 Array MinMax[829:18846] Failed to connect (exitNow) outlet from (Array_MinMax.ViewController) to (NSButton): missing setter or instance variable
(lldb)
Here is the code:
import Cocoa
class ViewController: NSViewController {
#IBOutlet weak var inputArrayValues: NSTextField!
#IBOutlet weak var minLabel: NSTextField!
#IBOutlet weak var maxLabel: NSTextField!
#IBAction func exitNow(sender: AnyObject) {
NSApplication.sharedApplication().terminate(self)
}
#IBAction func arrayMinMax(sender: AnyObject) {
let someData: String? = inputArrayValues.stringValue
let separators = NSCharacterSet(charactersInString: " ,;:|")
let parts = someData!.componentsSeparatedByCharactersInSet(separators)
let intArray = parts.map{Double($0)}
let minArray = intArray.minElement({$0 < $1}) // - stops on that line (thread 1: breakpoint 1.1)
let maxArray = intArray.maxElement({$0 < $1})
let minString = String(minArray!)
let maxString = String(maxArray!)
minLabel.stringValue = "The minimal value is \(minString)!"
maxLabel.stringValue = "The maximal value is \(maxString)!"
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
}
What to do with that, i can't understand! Is it a bug of Xcode 7.3.1??
Already solved this trouble. Just recreated the button using "NSButton" instead of "Any Object". Then, error goes away!

sending data to viewcontroller shows nil data

for some reason i cannot get the Value to send to my AddParticipant View.
Here's the Data before "ValuetoPass" and after the segue:"LAbelText"
ValuetoPass = GXEuoAkhjP
LabelText =
TableView Code for segue:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//CODE TO BE RUN ON CELL TOUCH
let indexPath = tableView.indexPathForSelectedRow!;
let currentCell = tableView.cellForRowAtIndexPath(indexPath) as UITableViewCell!;
let valueToPass = self.participantId[indexPath.row] as String
print("ValuetoPass = ",valueToPass)
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "editParticipant") {
let viewController = segue.destinationViewController as! AddViewController
viewController.LabelText = valueToPass; }
}
}
Code for AddViewController:
#IBOutlet weak var firstnameTF: UITextField!
#IBOutlet weak var lastnameTF: UITextField!
#IBOutlet weak var gradeTF: UITextField!
#IBOutlet weak var teacherTF: UITextField!
#IBOutlet weak var emailTF: UITextField!
#IBOutlet weak var phoneTF: UITextField!
#IBOutlet weak var transportationTF: UITextField!
#IBOutlet weak var userSchoolTF: UITextField!
var LabelText = String()
#IBOutlet weak var qrCode: UIImageView!
#IBOutlet weak var userPicture: UIImageView!
override func viewDidAppear(animated: Bool) {
}
override func viewDidLoad() {
super.viewDidLoad()
print("LabelText = ", LabelText)
let currentUser = PFUser.currentUser()
currentUser!.refreshInBackgroundWithBlock { (object, error) -> Void in
// print("Refreshed")
currentUser!.fetchIfNeededInBackgroundWithBlock { (result, error) -> Void in
self.userSchoolTF.text = currentUser!.objectForKey("school") as? String
}
}
So I have the Data before it is sent, but it shows as nil after the segue?
I suppose you created segue in Storyboard, am I right?
Put your prepareForSegue function out of tableView func. Also prepareForSegue should Override. Try using code below
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if( segue.identifier == "editParticipant" ){
if let destinationVC = segue.destinationViewController as? AddViewController {
destinationVC.LabelText = valueToPass
}
}
}
Does Swift have NSString objects? Or is String the same thing?
In objective c, assigning to an object pointer is creating a reference to the previous object. When you make it weak, it doesn't add to the reference count, so if you deallocate the original pointer, you deallocate both. Strong means that it does add to the reference count, so deallocating the first will not actually deallocate the object.
If String and NSString are two different things, try making your type NSString instead, and see if it is retained.
I work in Obj-C, not Swift, and I'm not sure of the nuances between the two.

Resources