I have a form with two textfields and I want to validate those as I type. For example: I have an email textfield and as soon as I start typing it tells me whether the email has been previously used or not. If it is already used it shows an 'X' icon in the textfield and if it's not it shows a 'check mark'. The validation works fine. The problem I am facing is when I try to clear the textfield by pressing the delete button(not holding down) it clears the textfield and shows no icon because it's empty. But if it try to clear the textfield by holding down the delete button, then the icon does not disappear. Here's the code:
EmailAvailable.get(["email": newString], handler: {(result: [BaseModel]?, error: NSError?) in
if let available = result as? [EmailAvailable] {
self.emailImageView.image = available[0].available ? UIImage(named: "success") : UIImage(named: "failed")
} else {
self.emailImageView.image = UIImage(named: "failed")
}
})
I am making an API call here to check whether the email is valid or not. NOTE: The validation works fine.
the above image shows the check mark even after the textfield is cleared and only happens when I hold down the delete button. Any help is appreciated, thanks!
Related
I'm building an app which which has built in with 2 different tabs. First tab is is "Home" which basically has a tableview with cells that configured from an api.(The api gets me country names for now)
Those cells also have a "Star" button which prints the data of the specific cell for now.
Second tab is "Saved" tab(SavedViewController), where I want to show the "starred" countries, using a tableview.
You can see the image below in order to get an idea for the app.
App simulation Image
The star button has a function in my CountriesTableViewCell. I'm using a saveButtonDelegate in order to let the SavedViewController know about an item is going to be saved. The code in CountriesTableViewCell for star button is as below.
#objc func buttonTapped() {
//If Button is selected fill the image. Else unfill it.
if !isSaveButtonSelected {
saveButton.setImage(UIImage(systemName: "star.fill"), for: .normal)
isSaveButtonSelected = true
saveButtonDelegate?.saveButtonClicked(with: countryData) //Checking if save button is clicked
}
}
countryData is the data that I get from the api, and this is the data I want to pass to SavedViewController.
struct CountryData: Codable {
let name : String
}
So on the SavedViewController, I'm handling the data using the SaveButtonProtocol conformance as below:
extension SavedViewController: SaveButtonProtocol {
func saveButtonClicked(with data: CountryData) {
countryDataArray.append(data)
print("saveButtonClicked")
print("countryData in savevc is \(countryDataArray)")
DispatchQueue.main.async {
self.countriesTableView.reloadData()
}
}
}
Whenever I click the star button on the first tab, this function is getting called on SavedViewController. So whenever I click to button, those print statements above work fine.
The problem is, whenever the star button is clicked, it should append the data of the current clicked cell to countryDataArray in SavedViewController. But the array is not populating as it should.
Let's say I pressed the first cell's star button, my print("countryData in savevc is (countryDataArray)") statement prints : ["Vatican City"], then I press the second cell's star button it only prints ["Ethiopia"] while it should print ["Vatican City", "Ethiopia"]
Why this issue is happening? My best guess is I'm delegating SavedViewController from the cell class so it behaves differently for every other cell. If that is the problem what should I do to solve it?
Many Thanks.
You should store your data in a shared (static array) object so you only have one source and add the saved indicator in your country struct so you do not rely on what is displayed in one view controller.
I currently have four text fields. At the beginning, only one text field shows. After the user enters text to the first text field and taps a button a new text field is presented and the previous one is hidden with the text field hidden property. My current code only shows the first text field, hides it and shows a new one, and stays in the second text field. There are still two more text fields that need to have the same functionality.
Can you explain why my current code is not working?
Thank you
This is my current code
if nameTextField.text != nil {
nameTextField.resignFirstResponder()
emailTextField.isHidden = false
nameTextField.isHidden = true
emailTextField.becomeFirstResponder()
} else if emailTextField.text != nil {
emailTextField.resignFirstResponder()
emailTextField.isHidden = true
firstPasswordTextField.isHidden = false
firstPasswordTextField.becomeFirstResponder()
} else if firstPasswordTextField.text != nil {
firstPasswordTextField.resignFirstResponder()
firstPasswordTextField.isHidden = true
phoneNumberTextField.isHidden = false
phoneNumberTextField.becomeFirstResponder()
} else if phoneNumberTextField.text != nil {
phoneNumberTextField.resignFirstResponder()
}
Hi Mathew the condition what you have written is incorrect . Lets say user first enter in nameTextField and then you are checking emailTextField not equal to nil.. Sone ones user enter in both the textfield , it is always going to satisfy the first condition only.. Just put a brteakpoint and check your logic.
I have a textField called titleTextField in which the user can enter the title of their choice before saving a note. What I want to do is automatically fill this field with the text "Untitled" if the user has left this field blank.
I've tried several solutions, but they either do nothing or set the title always to Untitled even if the user has entered text.
This is the closest I've gotten, but it's still not working right:
if(![self.titleTextField.text isEqual:#""]){
self.titleTextField.text = #"Untitled";
}
My thought was that this would check whether the titleTextField is empty, and if so, it would populate the field with the text "Untitled." I've tried applying this in the viewDidLoad, viewWillAppear, and viewWillDisappear -- I really don't care whether the "Untitled" text is populated when the screen loads or after the user is finished with the page; I just want the end result to be an empty title field saving with the text "Untitled".
Is the coding wrong, or am I just applying it in the wrong place?
Solution as per the way you are looking for is :
if([self.titleTextField.text isEqualToString:#""]){
self.titleTextField.text = #"Untitled";
}
You can also use below :
if([self.titleTextField.text length] == 0){
self.titleTextField.text = #"Untitled";
}
My table view contains four textfields
first TextField contains lab name
second textfield contains picker view (with options < ,> , <>, =)
if user selects <> then we are showing two text fields other wise
only one
if selectedValue._conditionSymbol == "<>" {
textField2.isHidden = false
}else {
textField2.isHidden = true
}
this is initial screen
if user click on cancel or close buttons then i need to clear the data in last two text fields.
i have used
textfield2.clear()
textfield1.clear()
tableview.reloadData
but it is not working
after clicking cancel or close button then also getting two textfields.
but i should get pickerview data as "<" and only one texfield should be visible
try this:
textfield2.text = ""
textfield1.text = ""
tableviewOutlet.reloadData
Situation as it should be
We have a today widget that shows a maximum of 6 buttons depending on data set in the corresponding app. This data is shared using app-groups. If at least one button is configured it will show up as shown in the image above. If the user is not logged in, or if no buttons are configured, it will show a message as shown in the image below.
Problem
After several hours (somewhere between 4 and 7) of not having opened the app, the widget reverts to the 'No buttons configured' view.
Analysis so far
The way the data is loaded from the app-group is done using the code as shown below. (gist for full code) In the way I had written it, the only way the 'No buttons configured' view can be shown is if the buttons array actually exists but has a length of zero.
I expected something like a cache clearing or a background service stopping, but as far as I can see, exceptions should be caught earlier:
If no connection could be made to the app-group data, userDefaults should be nil, so it should show the 'Not logged in view'.
In case the buttons were never defined, buttons should be nil and so again it should show the 'Not logged in view'
Considering the app does nothing in the background, the app itself could not be changing the buttons.
I tried reproducing this while having the debugger connected, but the problem will not reproduce.
Does anyone even have the slightest idea on how to fix this issue or how to start debugging this?
Relevant files:
TodayViewController
Cordova Plugin
Relevant code:
private struct sharedData {
static var baseUrl: String?
static var token: String?
static var phoneDeviceId: String?
static var buttons: Array<Button>?
}
func loadData() {
let groupIdentifier = "group." + NSBundle.mainBundle().bundleIdentifier!
var groupIdArray = groupIdentifier.componentsSeparatedByString(".")
groupIdArray.removeAtIndex(groupIdArray.count - 1)
let appGroupIdentifier = groupIdArray.joinWithSeparator(".");
let userDefaults = NSUserDefaults.init(suiteName: appGroupIdentifier)
if (userDefaults == nil) {
print("Error in user defaults")
setButtonTitle("Not logged in. Open Triggi to continue.")
return false
}
sharedData.baseUrl = userDefaults?.valueForKey("baseUrl") as? String
sharedData.token = userDefaults?.valueForKey("token") as? String
sharedData.phoneDeviceId = userDefaults?.valueForKey("phoneDeviceId") as? String
let buttons = userDefaults?.valueForKey("buttons") as? NSArray
if (sharedData.baseUrl == nil || sharedData.token == nil || sharedData.phoneDeviceId == nil || buttons == nil) {
print("Missing data")
setButtonTitle("Not logged in. Open Triggi to continue.")
return false
}
if (buttons?.count == 0) {
print("No buttons configured")
setButtonTitle("No buttons configured. Open Triggi to continue.")
return false;
}
// More things are done with the data here
}
Today Extension Controller is a UIViewController and thus follows the same lifecycle as that of a UIViewController. So, the lifecycle method viewDidLoad() is called everytime whenever the widget is loaded.
Also, widgetPerformUpdateWithCompletionHandler is called:
when widget is updated in background
before widget snapshot is taken
So, instead of just calling loadData() in widgetPerformUpdateWithCompletionHandler, also call it from viewDidLoad().
Also, where have you written the code to add/remove UIButtons from superview and to show "No buttons configured" in your code?