I am trying to add users names that they have put in a textfield to a basic array. I don’t even know where to start!
The functionality basically is this:
User adds a name in text field
Name is stored in an array so it can be referenced again somewhere else.
As you can tell I’m new to Xcode. I have been taking classes all of which have failed to explain this process. Any help is good Help ! Please :):)
// my view controller so far
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var name1: UITextField!
#IBOutlet weak var name2: UITextField!
#IBOutlet weak var name3: UITextField!
var namesArray : [String] = []
override func viewDidLoad() {
super.viewDidLoad()
name1.delegate = self
name2.delegate = self
name3.delegate = self
self.namesArray.append(self.name1.text!)
self.namesArray.append(self.name2.text!)
self.namesArray.append(self.name3.text!)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
if textField.returnKeyType == UIReturnKeyType.done {
self.namesArray.append(self.name1.text!)
print(namesArray)
}
return true
}
I am going to assume you have all your logic mashed into one view controller since you are still learning and not worried about larger architecture decisions yet.
At the top of your class, you need an array variable:
// Creates an array and initializes it to be empty.
var userNames: [String] = []
I suspect you also have a button, so that when you press on the button, it grabs the text from the textfield and stores it in the array. You need to set up an IBAction method for that button, and in that method...
// Grab the text, save it in the array, and clear the text.
self.userNames.append(self.myTextField.text)
self.myTextField.text = ""
Later on, you can easily see the list of userNames by accessing self.userNames. e.g.:
let firstUser = self.userNames.first
let lastUser = self.userNames.last
let user47 = self.userNames[46] // assuming you have that many users
Related
I'm currently having problems for my label to read the addition of 3 textfield values automatically, without a button function action. As such i only want my textfield to be an Int input only. There's a screenshot attached below for better reference. Appreciate those who can help me with this. Thanks!
ViewController
import UIKit
class TryingoutController: UIViewController {
#IBOutlet var impact: UITextField!
#IBOutlet var rigour: UITextField!
#IBOutlet var response: UITextField!
#IBOutlet var total: UILabel!
One way is to add self as the target to the text fields, for the control event .editingChanged
impact.addTarget(self, action: #selector(textChanged), for: .editingChanged)
// do the same for other textfields
Then declare a textChanged method. This should handle what happens when the texts in the text fields change. One implementation would be to add up all the values in the text fields (if any, and is valid) and display it in the label.
func textChanged() {
let impactValue = Int(impact.text!)
let rigourValue = Int(rigour.text!)
let responseValue = Int(response.text!)
total.text = String(describing:
(impactValue ?? 0) + (rigourValue ?? 0) + (responseValue ?? 0)
)
}
Optionally, you can conform to UITextFieldDelegate:
class TryingoutController: UIViewController, UITextFieldDelegate {
}
and implement shouldChange according to this answer by Thuggish Nuggets. Then, set the delegates of the text fields to self:
impact.delegate = self
// do the same for other text fields.
I'm a new one to learn RxSwift.
I modified the Simple Numbers example in the RxSwift Example App, which will add three numbers into a result number.
I add a testStr UITextField, and an upperCase UILabel. I map testStr to uppercase and bindTo the upperCase label, that's good. And I also map testStr to its length, and bindTo the num1 field. Strange things happen, although the contents of the num1 field changes, it does not emit any event, so it has no effect on the result label. Even if I input some number into another number field, the result number does not count the num1.
Have I made any wrong use of bindTo? In what way can I make the num1 emit an event?
Thanks!!!
#IBOutlet weak var num1: UITextField!
#IBOutlet weak var num2: UITextField!
#IBOutlet weak var num3: UITextField!
#IBOutlet weak var result: UILabel!
#IBOutlet weak var testStr: UITextField!
#IBOutlet weak var upperCase: UILabel!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Observable.combineLatest(num1.rx_text, num2.rx_text, num3.rx_text) {
(textval1, textval2, textval3) -> Int in
return (Int(textval1) ?? 0) + (Int(textval2) ?? 0) + (Int(textval3) ?? 0)
}
.map{$0.description}
.bindTo(result.rx_text)
.addDisposableTo(disposeBag)
let obStr = testStr.rx_text
obStr
.map {$0.uppercaseString}
.bindTo(upperCase.rx_text)
.addDisposableTo(disposeBag)
obStr
.map{ $0.characters.count }
.map{ $0.description }
.bindTo(num1.rx_text)
.addDisposableTo(disposeBag)
}
You need to use a Subject such as Variable to store the value. You can see an example of this in this answer in the section called Using Variables.
The reason it doesn't work is because rx_text will only omit a next element when it's changed by the user, not programmatically (as you're doing). This is because rx_text is really using this method from UIControl to get notified of changes to the field:
public class UIControl : UIView {
public func addTarget(target: AnyObject?, action: Selector, forControlEvents controlEvents: UIControlEvents)
}
However, that method does not call the action method on target when the change happens programmatically. Only when it happens due to a user changing something.
So, you should see a next event if you were to change the field programmatically and then the user were to tap into (or out of) the field. However, that's not what you want.
Instead, refer to that answer I linked you to and it will work.
I am trying to store a variable named total which holds the number of rows in UITableView. Since the user types strings for UITableView, the variable is listTable which is String array.
I have my total as total = listTable.count
ISSUE:
Every time the app launches it displays 0 as number of rows used, however once you go to the UITableView ViewController and come back to the main ViewController it automatically corrects its self to the current amount of rows.
Code Used:
import UIKit
var listTable = [String]()
var total = listTable.count
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var numberOfRows: UILabel!
#IBOutlet weak var TypeToCreateRow: UITextField!
#IBOutlet weak var AddRow: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
total = listTable.count
NSUserDefaults.standardUserDefaults().setObject(total, forKey: "rows")
let showRow = NSUserDefaults.standardUserDefaults().objectForKey("rows")!
numberOfRows.text = "\(showRow)"
print(showRow)
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func RowAdd(sender: UIButton) {
listTable.append(TypeToCreateRow.text!)
TypeToCreateRow.text = " "
numberOfRows.text = "\(total)" }
As simple as :
[[NSUserDefaults standardUserDefaults]setObject:value forKey:#"key"];
and to find it after :
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
[user objectForKey:#"login"]
You set the object first before reading it. That's why you write 0 first and read it immediately.
These two lines don't achieve anything.
NSUserDefaults.standardUserDefaults().setObject(total, forKey: "rows")
let showRow = NSUserDefaults.standardUserDefaults().objectForKey("rows")!
You need to setObject after you have the correct value, later in code. Not at the start.
Also as JAL mentioned you should use setInteger instead of object, as it is more optimized.
I wrote a Model file for my basic app and I'm in the process of applying the model to the UI. It has 3 manual inputs and a text area for the "results" once the calculate button has been pressed.
I'm really struggling with making the UI do what I want it to do, I just want the results displaying, I tried print() but get unresolved identifiers in view controller.
How do I get the .value of my results from the Model file in the view controller? Or have to initialize those again?
Model File (Struct)
struct FuelMaths {
var rate: Double = 3.7 //set initialValvue
var tank: Int = 110
var laps: Int = 13
var totalFuel: Double
var totalStops: Double
init (rate: Double, tank: Int, laps: Int) {
self.rate = rate // declare an instance
self.tank = tank
self.laps = laps
totalFuel = rate * Double(laps)
totalStops = totalFuel / Double(tank)
}
func result () {
print(totalFuel.value)
print(totalStops.value)
}
}
View Controller
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var rate: UITextField!
#IBOutlet weak var laps: UITextField!
#IBOutlet weak var tank: UITextField!
let calculate = FuelMaths(rate: 3.7, tank: 110, laps: 13)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func calculate(sender: UIButton) {
}
#IBOutlet weak var display: UITextView!
}
Thanks all.
(Edit: I originally said you didn't instantiate the model at class scope; you did, but you misnamed it as a verb calculate rather than a good noun like fuelCalculationModel. But anyway, I'm using it the way you've written it: which is as sort of a one-off where the values are passed in at construction time and those values are assumed final so that the result is calculated immediately. It is possible to write a model that is designed to persist and adjust to changes in its source value over time, but you need to understand property observers or computed properties for that.)
See if the solution is helpful:
#IBAction func calculate(sender: UIButton) {
if let rateVal = Double(rate.text!),
tankVal = Int(tank.text!),
lapVal = Int(laps.text!) {
let fuelModel = FuelMaths(rate: rateVal, tank: tankVal, laps: lapVal)
display.text = "Total fuel: \(fuelModel.totalFuel) Total Stops: \(fuelModel.totalStops)"
}
else {
display.text = "One of the text fields did not have a valid number."
}
}
Ultimately you want the model to be a persistent object at class-level scope, not function scope, and you want it to recalculate its results whenever its source values are changed, but wait on that until you understand this, especially if-let when constructing numbers out of parsed Strings.
I have a tab bar controller as the starting point of my app, where one of the tab and what happens subsequently is meant for admins only. So I was password protecting a tab. I thought of adding a little modal dialogue in the viewDidLoad function of my view controller (which by the way is a UITableViewController),
Suppose I can get the text that the user entered in the dialogue box in the variable inputTextField.
The relevant section of the code from viewDidLoad():
if inputTextField?.text != "secret" {
return
}
super.viewDidLoad()
But it does not work. Any hint appreciated. Sorry if it is too basic, I am completely new to iOS and Swift programming, so pardon my ignorance folks.
Here is a simple example. Lots of ways. I dropped two UIViews in Storyboard on the first tab's VC. The one in the back I gave a dark color to simulate the hidden secret view (secretView). Inside of the view on top (entryView) I dragged a label "Enter Passcode" and a text field (passCode). I just hid the back view unless the secret code was correct.
import UIKit
class FirstViewController: UIViewController, UITextFieldDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.passCode.delegate = self
entryView.hidden = false
secretView.hidden = true
}
#IBOutlet weak var entryView: UIView!
#IBOutlet weak var secretView: UIView!
let secretCode = "X"
#IBOutlet weak var passCode: UITextField!
func textFieldShouldReturn(textField: UITextField!) -> Bool {
if textField.text == secretCode {
entryView.hidden = true
secretView.hidden = false
} else {
self.passCode.text = "Try Again!"
}
textField.resignFirstResponder()
return true
}
}