Passing a value from inputField to NSTextField - macos

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?

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)
}

I can't use instance member array within property initializer

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).

What's the correct syntax of passing an IBAction from a UICollectionViewCell to its host UIViewController?

Scenario: processing a button action originating from a UICollectionViewCell in its hosting UIViewController.
The Cell:
Here's my code:
protocol CellProtocol {
func doSomething()
}
...
class ItemCollectionCell:UICollectionViewCell {
var delegate:CellProtocol?
var itemData:ItemData?
#IBOutlet weak var descLabel: UILabel!
#IBOutlet weak var priceLabel: UILabel!
#IBOutlet weak var imageView: UIImageView!
#IBAction func addToCartAction() {
delegate?.doSomething()
print("Add to Cart")
}
}
class ShopViewController:UIViewController, CellProtocol {
let kCellID = "ItemCell"
#IBOutlet weak var featuredItemLabel: UILabel!
#IBOutlet weak var featuredItemPriceLabel: UILabel!
#IBOutlet weak var featuredItemImageView: UIImageView!
#IBOutlet weak var collectionView: UICollectionView!
override var prefersStatusBarHidden: Bool {
return true
}
func doSomething() {
print("Howdy Batman!")
}
// -----------------------------------------------------------------------------------
// MARK: - Action Methods
#IBAction func addToCartAction(_ sender: UIButton) {
}
}
This isn't working.
I know it has something to do with delegation.
I merely sent 'self' to my custom UICollectionViewCell class during the cell-loading phase.

Change textcolor for UITextField

I am trying to change the textColor.Though I enter the numbers correctly into the textfields,it is working only for "else" condition but not for 'if'. Here is my code.
Can anyone fix this issue. Thanks
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var questionOne: UILabel!
#IBOutlet weak var fieldOne: UITextField! // textFields should be set as labels
#IBOutlet weak var questionTwo: UILabel!
#IBOutlet weak var fieldTwo: UITextField!
#IBOutlet weak var questionThree: UILabel!
#IBOutlet weak var fieldThree: UITextField!
#IBOutlet weak var questionFour: UILabel!
#IBOutlet weak var fieldFour: UITextField!
#IBAction func submitButton(sender: UIButton) {
fieldOneColorChange()
fieldTwoColorChange()
fieldThreeColorChange()
fieldFourColorChange()
}
#IBAction func resetButton(sender: UIButton) {
}
// Text color changes
func fieldOneColorChange() {
if fieldOne == 1 {
questionOne.textColor = UIColor.redColor()
} else {
questionOne.textColor = UIColor.blueColor()
}
}
func fieldTwoColorChange() {
if fieldTwo == 2 {
questionTwo.textColor = UIColor.brownColor()
} else {
questionTwo.textColor = UIColor.redColor()
}
}
func fieldThreeColorChange(){
if fieldThree == 3 {
questionThree.textColor = UIColor.blueColor()
} else {
questionThree.textColor = UIColor.purpleColor()
}
}
func fieldFourColorChange(){
if fieldFour == 4 {
questionFour.textColor = UIColor.blueColor()
} else {
questionFour.textColor = UIColor.redColor()
}
}
Change your if statement like this
if fieldOne.text=="1"
so on for every if statement respectively

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