I am trying to print my input from textfields I have setup to the console before I print them to a label. I've tried string interpolation and various other methods, but I can't seem to get it to print the inputs themselves. I know force unwrapping is frowned upon but I will handle it properly after I get this to work. I've checked other asks extensively but found nothing specific to this in particular
To be clearer, when I press submit I want the text from the textfields to print to the console. Right now what happens is the values only show up at (UITextfield)
class SPProfileViewController: UIViewController {
#IBOutlet weak var typeOfCompany: UITextField!
#IBOutlet weak var firstName: UITextField!
#IBOutlet weak var lastName: UITextField!
#IBOutlet weak var email: UITextField!
#IBOutlet weak var cellPhone: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
typeOfCompany.delegate = self
firstName.delegate = self
lastName.delegate = self
email.delegate = self
cellPhone.delegate = self
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
cellPhone.resignFirstResponder()
}
#IBAction func onSubmit(_ sender: UITextField) {
print(self.typeOfCompany.text!)
print(self.firstName.text!)
print(self.lastName.text!)
print(self.email.text!)
print(self.cellPhone.text!)
}
}
extension SPProfileViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
You are watching variables view, Click on "show the console" icon at bottom right corner to view console area.
If that is not your problem than make sure IBAction onSubmit is connected to storyboard.
Related
This question already has an answer here:
Declaration is only valid at file scope (extension)
(1 answer)
Closed 3 years ago.
I've got a problem with 'Declaration is only valid at file scope' error
I was not modifying any other files than mainstoryboard. Those are all places. (whiteout one 'If != nil') where I was using TextFields. I've been trying nearly everything. Thanks for any help
Code:
class ViewController: UIViewController {
//inputs
#IBOutlet weak var creditValueInput: UITextField! //wartość kredytu, input
#IBOutlet weak var procentageInput: UITextField! //oprocentowanie, input
#IBOutlet weak var yearsInput: UITextField! //ile lat/miesiecy, input
#IBOutlet weak var creditOverallOutput: UILabel!
#IBOutlet weak var creditCalculationOutput: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
self.creditValueInput.delegate = (self as! UITextFieldDelegate)
self.procentageInput.delegate = (self as! UITextFieldDelegate)
self.yearsInput.delegate = (self as! UITextFieldDelegate)
// Do any additional setup after loading the view.
}
......
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
creditValueInput.resignFirstResponder()
procentageInput.resignFirstResponder()
yearsInput.resignFirstResponder()
.....
extension ViewController: UITextFieldDelegate { !Declaration is only valid at file scope!
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
}
Thanks for any help
It seems like you are writing your extension inside your class.
While extensions are valid at file scope, so you should cut your extension block and paste it outside your class.
Assuming the braces of touchesBegan func are closed correctly.
I've found a few threads here about this, and some videos online about it as well, but every solution seems to have problems reported by others. The simplest solution I've found is the one below.
import UIKit
class SignupController: UIViewController, UITextFieldDelegate {
// Outlets
#IBOutlet weak var logoImage: UIImageView!
#IBOutlet weak var nameTF: CustomTextField!
#IBOutlet weak var emailTF: CustomTextField!
#IBOutlet weak var passwordTF: CustomTextField!
#IBOutlet weak var confirmPassTF: CustomTextField!
// Actions
#IBAction func signupButton(_ sender: UIButton) {
}
override func viewDidLoad() {
super.viewDidLoad()
logoImage.image = UIImage(named: "logo2")
nameTF.delegate = self
emailTF.delegate = self
passwordTF.delegate = self
confirmPassTF.delegate = self
}
// Moves to next text field each time return key is pressed
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField == nameTF {
textField.resignFirstResponder()
emailTF.becomeFirstResponder()
} else if textField == emailTF {
textField.resignFirstResponder()
passwordTF.becomeFirstResponder()
} else if textField == passwordTF {
textField.resignFirstResponder()
confirmPassTF.becomeFirstResponder()
}else if textField == confirmPassTF {
textField.resignFirstResponder()
}
return true
}
// Dismisses keyboard when tapped
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
}
It works, is very simple, but my project and coding experience are in their infancy, so I'm not sure if this is the best method simply because it's short, or if there's something I'm missing due to lack of experience/knowledge?
Anybody know of a better solution, or is this one just fine?
just do this:
class viewController: UIViewController, UITextFieldDelegate {
// Outlets
#IBOutlet weak var logoImage: UIImageView!
#IBOutlet weak var nameTF: CustomTextField!
#IBOutlet weak var emailTF: CustomTextField!
#IBOutlet weak var passwordTF: CustomTextField!
#IBOutlet weak var confirmPassTF: CustomTextField!
// Actions
#IBAction func signupButton(_ sender: UIButton) {
}
override func viewDidLoad() {
super.viewDidLoad()
logoImage.image = UIImage(named: "logo2")
nameTF.delegate = self
emailTF.delegate = self
passwordTF.delegate = self
confirmPassTF.delegate = self
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dissMissKeyboard))
view.addGestureRecognizer(tap)
}
func dissMissKeyboard() {
view.endEditing(true)
}
I prefer to use UITextField delegate method:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
view.endEditing(true)
return true
}
or setup inputAccessoryView which have 'done' or 'exit' button.
Then you need to implement the gesture recognition for this . Or you can do like this :
override func viewDidLoad() {
super.viewDidLoad()
//Looks for single or multiple taps.
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dissMissKeyboard))
//Uncomment the line below if you want the tap not not interfere and cancel other interactions.
//tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
//Calls this function when the tap is recognized.
func dissMissKeyboard() {
//Causes the view (or one of its embedded text fields) to resign the first responder status.
view.endEditing(true)
}
How do I find out if the keyboard is of type numeric, Twitter, email, etc...?
edit: Is there a way to detect keyboard type without using an outlet?
Consider that you have tow textFields in the ViewController, You will need to implement textFieldShouldBeginEditing method from UITextFieldDelegate protocol, as follows:
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var tfEmail: UITextField!
#IBOutlet weak var tfPassword: UITextField!
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField.keyboardType == .emailAddress {
// this is the tfEmail!
}
if textField.isSecureTextEntry {
// this is tfPassword!
}
}
}
Make sure their delegates are connected to the ViewController, programmatically:
tfEmail.delegate = self
tfPassword.delegate = self
or from the Interface Builder.
Note that you can recognize the keyboard type for the current textField by checking its keyboardType property, which is an instance of UIKeyboardType enum:
The type of keyboard to display for a given text-based view. Used with
the keyboardType property.
What about UITextView?
The same exact functionality should be applied when working with UITextViews, but you need to implement textViewDidBeginEditing(_:) method from UITextViewDelegate protocol instead of implementing textFieldShouldBeginEditing. Again, make sure the delegate of the textView is connected to the ViewController.
Also,
If your main purpose of checking the keyboard type is just for recognizing what is the current responded textField/textView, I suggest to do a direct check:
class ViewController: UIViewController, UITextFieldDelegate, UITextViewDelegate {
#IBOutlet weak var tfEmail: UITextField!
#IBOutlet weak var tfPassword: UITextField!
#IBOutlet weak var textViewDescription: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
tfEmail.delegate = self
tfPassword.delegate = self
textViewDescription.delegate = self
}
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField === tfEmail {
// this is the tfEmail!
}
if textField === tfPassword {
// this is tfPassword!
}
}
func textViewDidBeginEditing(_ textView: UITextView) {
if textView === textViewDescription {
// this is description textview
}
}
}
For more information about === operator you might want to check this question/answers.
Hope this helped.
In addition to Ahmad F 's great answer, this is my approach of getting the current keyboard type, at any time:
Step 1: Delegate UITextField
class File: UIViewController, UITextFieldDelegate{//...}
Update viewDidLoad() to this:
#IBOutlet weak var normalTextField: UITextField!
#IBOutlet weak var numberTextField: UITextField!
#IBOutlet weak var emailTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
numberTextField.keyboardType = .numberPad
normalTextField.keyboardType = .default
emailTextField.keyboardType = .emailAddress
numberTextField.delegate = self
normalTextField.delegate = self
emailTextField.delegate = self
}
Step 2: Working with UITextField's methods:
Add a variable called keyboardType, as below:
var keyboardType: UIKeyboardType? = nil
Then, change it whenever a new textField begins editing:
func textFieldDidBeginEditing(_ textField: UITextField) {
keyboardType = textField.keyboardType
}
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
keyboardType = nil
return true
}
Step 3: Create and call a function like below:
func getCurrentKeyboard() -> String{
if keyboardType == nil{
return "no current keyboard"
}
else if keyboardType == .numberPad{
return "number"
}
else if keyboardType == .emailAddress{
return "email"
}
else{
return "default"
}
}
#IBAction func displayCurrentKeyboard(_ sender: UIButton) {
print(self.getCurrentKeyboard())
}
And this outputs: email / number / no current keyboard / default, depending on the case.
If you want to check which type of keyboard it is with if-else statements, you can change your displayCurrentKeyboard() method to this:
#IBAction func displayCurrentKeyboard(_ sender: UIButton) {
let keyboardString = self.getCurrentKeyboard()
if keyboardString == "number"{
//...
}
else if keyboardString == "email"{
//...
}
else{
//...
}
}
And that's it! You can call this wherever you want in your code with this usage:
let keyboardString = self.getCurrentKeyboard()
NOTE: This method also handles the case of no keyboard visible on the screen, returning no current keyboard, in this case.
Let me know if this helps!
I have the following in the ViewController:
a) a long viewScroller ( 1000 Height)
b) This long viewScroller contain a UIView Which is 1000 Height, called it 1stView
c) In this 1st UIView (1000 Height), it contain another UiView ( called it 2ndView)
d) in this 2ndUIView( the size: W300x H290) , it contains 5 textFields.
The problems:
1) How to I move the 5 textFields above the Keyboard when user click any one of the textFields to enter data?
for problem (v1) as below
2) below code for problem (V2).
When click outside ( 2ndView or in 2ndView ) the keyboard wont go away.
3) current codition without any implementation for moving the Keyboard up, the 1st TextField can be seen above the keyboard when user click the textField and need to scroll to see the others. Will AppStore approve this User experience?
class ItemViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var textField1: UITextField!
#IBOutlet weak var textField2: UITextField!
#IBOutlet weak var textField3: UITextField!
#IBOutlet weak var textField4: UITextField!
#IBOutlet weak var textField5: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
textField1.delegate = self
textField2.delegate = self
textField3.delegate = self
textField4.delegate = self
textField5.delegate = self
}
//-(V1)- handle textfield
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func textFieldDidBeginEditing(textField: UItextField) {
}
func textFieldDidEndEditing(textField: UITextField) {
}
//-(V2) Called when the user click on the view (outside the UITextField).
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
}
Thanks
So I have added targets to my IBActions I have created that occur when the value of a text field changes. When these actions occur, the system should check if the two text fields are both integers. I have set two variables set to false, and they are set to true when both of them are an int. In the IBActions, I have if statements that tell a button to be enabled if both of the variables contain integers. When I run the simulator, this button doesn't enable when both of the text fields contain an integer.
I am new to swift, so if possible, please write all of the code out and where it should be in my code. Here is what I have so far:
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var calculatorButton: UIButton!
#IBOutlet weak var inspirationLabel: UILabel!
#IBOutlet weak var beginningLabel: UILabel!
#IBOutlet weak var calculatorContainer: UIView!
#IBOutlet weak var answer1Label: UILabel!
#IBOutlet weak var doneButton: UIButton!
#IBOutlet weak var yourWeightTextField: UITextField!
#IBOutlet weak var calorieNumberTextField: UITextField!
#IBOutlet weak var menuExampleButton: UIButton!
#IBOutlet weak var aboutButton: UIButton!
#IBOutlet weak var calculateButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib
yourWeightTextField.delegate = self
calorieNumberTextField.delegate = self
calculateButton.enabled = false
// Calling the textfield valueChanged Methods
yourWeightTextField.addTarget(self, action:"yourWeightValueChanged:", forControlEvents:.ValueChanged);
calorieNumberTextField.addTarget(self, action:"calorieNumberValueChanged:", forControlEvents:.ValueChanged);
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func calculatorButtonTapped(sender: AnyObject) {
calculatorContainer.hidden = false
inspirationLabel.hidden = true
beginningLabel.hidden = true
menuExampleButton.hidden = true
aboutButton.hidden = true
}
var yourWeightFilled = false
var calorieNumberFilled = false
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// Find out what the text field will be after adding the current edit
let text = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
// If the textfields have the properties of the function
if textField == yourWeightTextField {
yourWeightFilled = text.toInt() != nil
} else if textField == calorieNumberTextField {
calorieNumberFilled = text.toInt() != nil
}
return true
}
func textFieldShouldReturn(textField: UITextField) -> Bool
{
textField.resignFirstResponder();
return true;
}
// The methods to close the keyboard when editing is finished
#IBAction func yourWeightEditingDidEnd(sender: AnyObject) {
yourWeightTextField.resignFirstResponder()
}
#IBAction func calorieNumberEditingDidEnd(sender: AnyObject) {
calorieNumberTextField.resignFirstResponder()
}
#IBAction func yourWeightValueChanged(sender: AnyObject) {
// If both variables are true and the text fields contain integers, enable button
if self.yourWeightFilled && self.calorieNumberFilled {
self.calculateButton.enabled = true
}
}
#IBAction func calorieNumberValueChanged(sender: AnyObject) {
// If both variables are true and the text fields contain integers, enable button
if self.yourWeightFilled && self.calorieNumberFilled {
self.calculateButton.enabled = true
}
}
}
You should look for EditingChaged event, not ValueChanged
EDIT:
What I mean is to change from:
yourWeightTextField.addTarget(self, action:"yourWeightValueChanged:", forControlEvents:.ValueChanged);
calorieNumberTextField.addTarget(self, action:"calorieNumberValueChanged:", forControlEvents:.ValueChanged);
to :
yourWeightTextField.addTarget(self, action:"yourWeightValueChanged:", forControlEvents:.EditingChanged);
calorieNumberTextField.addTarget(self, action:"calorieNumberValueChanged:", forControlEvents:.EditingChanged);
You simply are looking for wrong event.
If you are looking for a text changed event , then Right Click on the text field select Editing Did End from the Sent Events . You can see a circle on the right end click the circle Hold Down Ctrl and Drag it to your ViewController file. Name the Action you want and . I have provided some screen shots for this.
Here i name the Action TextChanged
I am Using Xcode 7 Swift 2 here
Right Click on the Text Box and You can see Something Like this
Finally You can see the TextChanged event Created. when you type something on a text box and click return this event fires.