On iOS13 I've noticed that after a textfield is cleared programatically the value for that textfield in the UI tests doesn't update.
In my UI test:
Text is entered into the textfield.
Some action happens which causes my code to clear the textfield (in this case tapping return on the on screen keyboard).
The value of the textfield is checked and it still contains the text that was present before it was cleared.
Here is the code I'm using to clear the textfield:
func clearInput() {
textField.text = nil
}
Here is the check I'm using in my UI test:
XCTAssert((createPasswordPage.passwordSecureTextField.value as? String) == "")
This fails on iOS13 but passes on older versions such as iOS12.
Any idea why this might be happening?
Example:
Code
class PasswordViewController: UIViewController {
#IBOutlet weak var textField: UITextField!
#IBOutlet weak var button: UIButton!
...
#IBAction func buttonTapped(_ sender: Any) {
// Clear the text
textField.text = nil
}
}
UI Test
func testTextClearing() {
let page = PasswordPage()
// Enter text
page.passwordTextField.tap()
page.passwordTextField.typeText("some text")
// Tap button causing text to clear from the textfield
page.button.tap()
XCTAssert((page.passwordTextField.value as? String) == "")
}
Related
I am trying to implement one button- one click to display the first message, the second click would change to second message, the third click would change to the third message.
I looked up to one possible solution is to use UITapGestureRecognizer - single tap and double tap, which means I can trigger the button (single tap to display the first message and double tap to display the second message).
However, if I have more than two lines and I just want to display them by clicking each one (like animation). Would that be possible to just deal with that inside one UIView and UIbutton?
I currently have 3 simple messages:
#IBOutlet weak var Textfield: UITextView!
#IBOutlet weak var Changingbutton: UIButton!
#IBAction func ChangingTapped(_ btn: UIButton) {
Textfield.text = "Changing to driving"
Textfield.text = "Changing to walking"
Textfield.text = "Changing to cycling"
}
The problem now is when I click the button it would just go the last message. That might not be a clever way to do so.
Thanks so much for the inputs and I am sorry if that is a rather simple question.
You can implement a custom CaseIterable enumeration to perform a loop so that you can get the next element every time you press a button:
extension CaseIterable where Self: Equatable {
var allCases: AllCases { Self.allCases }
var nextCase: Self {
let index = allCases.index(after: allCases.firstIndex(of: self)!)
guard index != allCases.endIndex else { return allCases.first! }
return allCases[index]
}
#discardableResult
mutating func next() -> Self {
self = nextCase
return self
}
}
Create a enumeration with your transportation modes:
enum Mode: String, CaseIterable {
case cycling, driving, walking
}
add a mode property to your view controller and set the initial value
var mode: Mode = .cycling
Now you can simply call the next mode method every time you press the button:
func ChangingTapped(_ btn: UIButton) {
Textfield.text = "Changing to " + mode.next().rawValue
}
Note: It is Swift naming convention to name your methods and properties starting with a lowercase letter.
Why not just set a counter and increment it every time your IBAction is activated?
var x = 0
#IBAction func ChangingTapped(_ btn: UIButton) {
if(x==0){
Textfield.text = "Changing to driving"
}
else if(x==1){
Textfield.text = "Changing to walking"
}
else{
Textfield.text = "Changing to cycling"
}
x +=1
//if x needs to be reset
/*
if(x > 2) x = 0
*/
}
I have a UITextView and a UIButton in my app and I'm trying to get the text content of the UITextView to be cleared when the UIButton is tapped.
My code:
#IBOutlet weak var textView: UITextView!
#IBAction func ClearButtonTapped(_ sender: UIButton) {
// I want to clear the text content of textView
}
Is there built-in function for that, in the UITextView class? I didn't find anything when I searched the UITextView class in Xcode.
My app is on Xcode 10.1 and Swift 4.2.
Small improvement:
textView.text = nil
Try using textView.text = "". If that's not working it could be that you're using a placeholder. Try textView.placeholder = ""
I didn't find a ready function to clear the text content of an UITextView so I created this code to do that:
The UITextView variable:
#IBOutlet weak var textView: UITextView!
Function to clear the UITextView:
#IBAction func ClearButtonTapped(_ sender: UIButton) {
textView.selectAll(textView)
if let range = textView.selectedTextRange { textView.replace(range, withText: "") }
}
When the clear-button is tapped, the function checks is there any text in the UITextView and if there is some, it will select all the text in the UITextView and replace it with an empty String.
EDIT:
There is also the simple way to do it, which, for some reason, didn't work when I tried it before (probably because the bugs in Xcode 10.1), but this way the user can't undo it, if they accidentally tap the clear button:
#IBAction func ClearButtonTapped(_ sender: UIButton) {
textView.text = ""
}
Or with extension:
extension UITextView {
func clear() {
self.text = ""
}
}
Call textView.clear() when you want to clear the text.
This is a very basic question but I'm not sure what the problem is. I'm trying to make a simple "hello world" program where the user inputs what they want into the textfield and whatever they enter goes into the label. However, nothing seems to be happening and I'm unsure why since my push function worked exactly how I expected it to.
import UIKit
class ViewController: UIViewController {
#IBOutlet var PopUp: UITextField!
#IBOutlet weak var HelloWorld: UILabel!
#IBAction func Push(_ sender: UIButton) {
PopUp.isHidden = false
PopUp.text = "hello World"
}
#IBAction func send(_ sender: UITextField) {
HelloWorld.text = sender.text
}
}
Based on the code you provided, func send is an unknown to me, as to whether or not it is even firing. func send might be called, might not, either way, it is strange to see a _ sender: UITextField for an IBAction.
What event are you firing related to the UITextField? Are you trying to update your HelloWorld UILabel as the user types in the UITextfield?
To update your UILabel with whatever has been typed in your UITextField, you just need a UIButton Touch Up Inside IBAction. I think you can delete IBAction func send completely, unless you are trying to update the UILabel as the user types in the UITextField. Make sure you remove the IBAction Outlet from your Storyboard if I am correct about this point.
Based on the code you provided the Push func does not set text in your UILabel. I am assuming Push is an UIButton Touch Up Inside IBAction. You can set your HelloWorld UILabel text, in func Push, you do not need to use the sender of the event, try this and you will see the HelloWorld UILabel text populated:
#IBAction func Push(_ sender: UIButton) {
//PopUp.isHidden = false //why are you doing this? the UITextField PopUp should already be visible if you are typing text into it, so this code is superfluous as the value of PopUp.isHidden is already false
HelloWorld.text = PopUp.text
PopUp.text = "hello World"
}
If you are trying to have your UILabel display the text as you type into the UITextField you should clarify your question. And if it is the case you will need to make your UIViewController a UITextFieldDelegate
Here is the one way of approach :
override func viewDidLoad() {
super.viewDidLoad()
PopUp.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged) // when textfield is edited this will call
}
func textFieldDidChange(_ textField: UITextField) {
HelloWorld.text = textField.text
}
I am struggling for some hours at a problem. Basically, I have a simple Swift app. It goes like this. In my 1st view controller I have 3 text fields I want to fill them with information and a "Next" button.
Pressing the "Next" button will send me to a new UIViewController where I will have a "Back" button. Upon pressing the back button, I will be send back to 1st page with the 3 text fields.
What I want is: if I complete the text fields with informations, press Next and then Back, I want the text fields to be filled with that information.
I managed to move between the views with buttons, but I can't save the information. Can you provide me a little help?
#IBOutlet weak var txtb1: UITextField!
#IBOutlet weak var txtb2: UITextField!
#IBOutlet weak var txtb3: UITextField!
#IBAction func next(sender: AnyObject) {
text1 = self.txtb1.text!
text2 = self.txtb2.text!
text3 = self.txtb3.text! }
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if (!text1)
{
txtb1.text = text1
}
}
If you are wanting to pass variables to different views you will have to use the prepareForSegue function before you segue into that view controller.
This allows the variables to be accessed by the view controller.
Override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!)
{
if segue.identifier == "segue_name"
{
let theDestination = segue.destinationViewController as! newViewController
theDestination.variable = "testing"
theDestination.variable2 = "testing2"
}
}
Then inside your second view controller you will have to declare variable and variable2 as shown:
var variable:String!
var variable2:String!
These will then be able to be used in the second view controller inside the viewDidLoad method.
Ok. I managed to fix a little of the problem, that button wasn't linked accordingly so the function was not executing. Here it is the code:
var text1 = ""
#IBOutlet weak var txtb1: UITextField!
#IBAction func next(sender: AnyObject) {
text1 = self.txtb1.text! // text1 = "I am taking value"
}
// when i press the back button
override func viewDidLoad() {
super.viewDidLoad()
if (!numarInmatriculare.isEmpty)
{
txtb1.text = text1 //here text1 = Null. the value is not saved
}
}
I want the value to be saved and displayed back on text field.
I also tried to use static varibiles but I am prompet with error.
static var numar:String = ""
numar = text1
//static member 'numar'cannot be used on instance of type 'viewcontroller'
You no need to do anything for this case, once text field filed then you clicking next button you wrote some code below i shown
text1 = self.txtb1.text!
text2 = self.txtb2.text!
text3 = self.txtb3.text!
Please first you remove the code,Once data filled in text filed, its automatically retain, after you clicking next button then come back it automatically it will retain, when your current view is poping then only your data will deallocate.
I created a simple app where the user enters their name into a TextField, clicks a button, and then a label above the textField changes its text to "Hello Name!".
I'm trying to verify that this works correctly with a UI Automation Instrument. I am able to enter text and click a button but when I try to verify the labels new value it doesn't return the correct value. Here is the code,
var input = target.frontMostApp().mainWindow().textFields()["NameInput"];
var button = target.frontMostApp().mainWindow().buttons()["SubmitButton"];
input.setValue("Sonny");
button.tap();
// This is not returning the labels correct value!
var label = target.frontMostApp().mainWindow().elements()["HelloLabel"].value();
if(label != "Hi Sonny!")
{
UIALogger.logFail("The Hello Label did not have the correct value! "+label);
}
else
{
UIALogger.logPass("The Hello Label was correct :D ");
}
I've tried using label() and value() but they both return the "HelloLabel". Has anyone encountered this and found a solution to retrieve the labels updated value?
Here is the xcode code if its needed...
#IBOutlet weak var MyLabel: UILabel!
#IBOutlet weak var MyName: UITextField!
#IBAction func sayHi(sender: AnyObject) {
MyLabel.text = "Hi \(MyName.text)!"
}