UITextField text not appearing when set by delegate method - ios

I'm implementing a barcode scanner for my app using the google books api. The data gets fetched successfully and stored in the proper textfields:
func readInJSON(controller: UIViewController, title: String, author: String, imageLink: String) {
self.titleTextField.text = title
self.authorTextField.text = author
}
However the text does not actually appear in the textFields until I tap on the them, then the text populates. I'm wondering if there is some way to have the text appear without having a user tap on the text fields themselves.

Maybe you are not on the main thread. UI operation should be done on the main thread.
Try this
dispatch_async(dispatch_get_main_queue()) {
self.titleTextField.text = title
self.authorTextField.text = author
}

Related

How to disable UIControlEventEditingChanged

I have a UIViewController with several UITextFields. When tap one text field, it should present the barcode scanning view controller. Once the scanning is completed, my barcode scanning viewcontroller is disappearing (used "dismissViewcontroller") and the scanned value should entered into the text field I tapped. This is working fine. I have set the delegate for each text field like this.
[field addTarget:metrixUIViewControllerIn action:#selector(executeScriptOnTextFieldChange:) forControlEvents:UIControlEventEditingChanged];
The problem is this :
Lets say I have set an alert to display inside this executeScriptOnTextFieldChange method. Once I tapped on the 1st text field, then the barcode scanner comes. Once I scanned barcode scanner closes and set the value for the first text field and fire the alert.Thats ok. But then if scanned by tapping the 2nd textfield and the string will set to that textfield and fire the alert related to 2nd textfield also fire the alert related to first textfield as well. I want to stop happening this. Is there any way to disable the delegate for one textfield? This happens because I am refreshing the view in the viewDidAppear. But I have to do that as well. Please help me.
UIControlEventEditingChanged for a textField can fire at many different events that are not even directly related to that textField, but related inderectly.
For instance, when your ViewController is presenting the barcodeScanner it may trigger a "resignFirstResponder" event on the textField. Also when the 2nd textField is tapped, cause the 2nd becomes first responder and the 1st suffers a "resignFirstResponder".
I suggest trying to use a UITapGestureRecognizer in your textField instead. Example:
Swift 4
#IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.textField.tag = 1
self.textField.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(fireTextField(_:))))
}
#objc func fireTextField(_ sender: UIGestureRecognizer){
let view = sender.view
guard view != nil else{
//Do nothing
return
}
let condition = view!.tag == 1
if condition{
//or do whatever other stuff you need
self.textField.becomeFirstResponder()
}else{
//Whatever for other textFields
}
}
This way, you could use the "tag" attribute to determine which textField is firing and so adjust "condition". You could also filter the flow with a switch using the "tag".
Not sure if any of this will really help as I would need more info about the flow you need to accomplish. Hope it does help!

How to Send Text in an UIInputViewController

so I've got the following code to insert text:
func insert(text: String) {
(textDocumentProxy as UIKeyInput).insertText(text)
}
But how do I actually get it to send to the chat window?
If you are looking to access all the text entered in the UIInputViewController, the following code may help:
var totalText = "" // complete text entered
if let before: String = self.textDocumentProxy.documentContextBeforeInput {
totalText += before
}
if let after: String = self.textDocumentProxy.documentContextAfterInput {
totalText += after
}
Now that you have complete text entered, you can send it to chat window. There are some limitations here which I can share if this is what you're looking for. Please let me know
Edit
To send text to whatsapp, you need to press send button which is outside the custom keyboard extension. If you want to enter text into the UITextView of whatsapp, it is pretty straightforward to do so. But, the custom keyboard extension can't control the send button of whatsapp

Adding two of the same values to array instead of one - swift

I am trying to make a search bar, where you can search for users names. The cell is showing two things - and image and a label.
The label is showing the users name and the image is showing the profile picture. The image needs the user userID to display his/her picture.
The countryAndCode contains the users userID called country, and the users name called code.
My problem is that it is adding the first user twice and I do not know why or how to change it.
Here is the relevant code, let me know if you would like to see more:
func startObersvingDB() {
FIRDatabase.database().reference().child("UserInformation").observeEventType(.ChildAdded, withBlock: { snapshot in
let title = snapshot.value!["usersUID"] as? String
let name = snapshot.value!["userName"] as? String
self.tableData.append(title!)
self.tableDataNames.append(name!)
for i in 0..<self.tableData.count {
print(self.tableDataNames.count)
print(self.tableData.count)
self.countryAndCode.append((self.tableData[i], code: self.tableDataNames[i]))//this shows error in XCode some times
//if the above code doesn't compile then use the below code
print("DONE")
print(self.countryAndCode)
}
self.tableView.reloadData()
})
}

how to find a string property that corresponds to a gesture.view in Swift?

I have a json file containing an array of dictionaries:
"question":"Question text",
"answers":["Yes", "No"],
"answerTracker":["1a", "1b"]
I have created a Question Class & an Answer Button View Class to display the questions & answers in the view.
In the view controller I have so far displayed the questions, created the answer buttons, and finally, added a tapGestureRecogniser to each button.
func answerTapped(gesture:UITapGestureRecognizer) {
// Get access to the button that was tapped
let selectionButtonThatWasTapped:SelectionButtonView? = gesture.view as? SelectionButtonView
if let actualButton = selectionButtonThatWasTapped {
// Find out the index for the button that has been tapped
let selectionTappedIndex:Int? = find(self.selectionButtonArray, actualButton)
**// Find the answer tracker for the button that has been tapped?**
// Append the tracker for the selected button to the User Generated Code
if let actualAnswerTracker:String = self.answerTracker as String! {
self.userGeneratedCode.append(actualAnswerTracker)
}
In the tapGestureRecognizer method above I now need to find the corresponding answerTracker (String) for the answer button that is tapped (UIView) but can't find a way? The answerTracker string corresponding to the tapped answer is to be appended into a String array property called userGeneratedCode.
Any suggestions?
you do not need to add a tapGestureRecogniser to a button, you can add a target and selector to button anyway. If you want to know which button is pressed, you can use tag property on UIButton to check against.

update text field ui in swift ios

i meet a question when i'm using swift of ios SDK 8
I used a callback to fetch data background and when data fetched, i want to set a text field value and update screen.
here is my code:
#IBOutlet var txtTest: UITextField!
#IBAction func login() {
let username = "aaa";
let password = "bbb";
var res = ServiceClient.login(username, password: password){
(res:String, error:String?) -> Void in if(error == nil){
self.txtTest.text = res;
}
}
}
Run this code and the data is correctly fetched and the txtTest did not updated, but when i tap txtTest, the value will be shown. So is there any way to force update UI? or send a message to UI thread?
Same issue that everyone is having when wanting to do UI updates in Swift: do not ever update the UI in any secondary thread. And that means anything with closures. Since Swift is using closures so much, that issue is being seen a lot more but it isn't new.
See Swift Update Label (with HTML content) takes 1min for the correct way of doing things.
UIKit is not thread-safe and should only be updated from the main thread. Downloads are done on the background thread, and you cannot update UI from there. Try:
For swift 3 and swift 4
DispatchQueue.main.async {
self.txtTest.text = "Your text"
}
Related duplicate question but with specific answer
iOS label does not update text with function in Swift

Resources