IQKeyboardManager unexpected behavior - xcode

i have a simple chat view that contain table view, text field and a send button
i'm using IQKeyboardManager to handle keyboard appearance but the unexpected behavior is that when i click on send button the keyboard disappear that behavior don't happen on chat apps like whatsApp the keyboard remain appear'
how to handle this behavior to be like whatsApp
Update : here is the send button code
#IBAction func sendPressed(_ sender: AnyObject) {
//TODO: Send the message to Firebase and save it in our database
if (messageTextfield.text?.isEmpty)!{
showAlert(alertTitle: "", alertMessage: "can't send empty Message", actionTiltle: "Ok")
}
else{
messageTextfield.isEnabled=false
sendButton.isEnabled=false
let messageDB=Database.database().reference().child("Messages")
let dictionary:[String:String]=["Sender":(Auth.auth().currentUser?.email)!,"MessageBody":messageTextfield.text!]
messageDB.childByAutoId().setValue(dictionary)
messageTextfield.text=""
messageTextfield.isEnabled=true
sendButton.isEnabled=true
}
}

The issue is with isEnable property used isUserInteration property instead of that
#IBAction func sendPressed(_ sender: AnyObject) {
//TODO: Send the message to Firebase and save it in our database
if (messageTextfield.text?.isEmpty)!{
showAlert(alertTitle: "", alertMessage: "can't send empty Message", actionTiltle: "Ok")
}
else{
messageTextfield.isUserInteractionEnabled=false
sendButton.isUserInteractionEnabled=false
let messageDB=Database.database().reference().child("Messages")
let dictionary:[String:String]=["Sender":(Auth.auth().currentUser?.email)!,"MessageBody":messageTextfield.text!]
messageDB.childByAutoId().setValue(dictionary)
messageTextfield.text=""
messageTextfield.isUserInteractionEnabled=true
sendButton.isUserInteractionEnabled=true
}
}

Related

xcode 12 firebase notification when app in background how to do a reload if the app have a opened webview

I implemented firebase notification in Xcode 12 via cocoapod and basic step by step... notification ARE working all nice and good, even when app in background.
this tutorial : https://www.appcoda.com/firebase-push-notifications/
the only thing I need is this condition : when App in background and user hit the notification, it opens the APP, but I want the webview to reload.
i think it would be in this part of the code
// [START receive_message]
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics
// Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
but what code and I add to reload the view ?
// [START receive_message]
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics
// Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: (messageID)")
}
// Print full message.
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}

WatchOS 7.1 WKLongPressGesture detected, alert presented, but action closures not firing

I am trying to implement a WKLongPressGestureRecognizer in my app. The long press gesture is recognized and the alert it presented. However, when I select the option to clear the table (I'm using Realm), the alert controller is dismissed, but the take is not cleared. When I tried to debug by adding breakpoints in the code, it seemed that the code inside the closure was being skipped completely. Any idea what I'm missing? (Should I be using an action sheet sided of an alert sheet?) I've tried so many different things. Here's the code with the print statements that I've been using to debug. None of the print statements inside the closures are currently being triggered.
#IBAction func handleLongPress(_ sender: Any) {
print("long press pressed")
WKInterfaceDevice.current().play(.click)
let clearAction = WKAlertAction(title: "Clear", style: .destructive) {
print("clear button pressed")
}
let cancelAction = WKAlertAction(title: "Cancel", style: .default) {
print("cancel button pressed")
}
presentAlert(withTitle: "Are you sure?", message: "Action cannot be undone", preferredStyle: .alert, actions: [clearAction, cancelAction])
print("exiting long press")}
Thanks for any input or advice.
The gesture recognizer will call selector handleLongPress twice, once with state == began, and once with state cancelled. I found that this causes the problems with presentAlert that you're describing.
Try checking for the began state:
#IBAction func handleLongPress(_ sender: WKGestureRecognizer) {
guard sender.state == .began else {
return
}
// rest of handleLongPress implementation goes here
}
This should ensure your alert is presented exactly once.

TouchId and FaceId authorization conditions

I need the authentication via TouchID and FaceID and various "else" requests in my app. I managed to integrate it, so that after pressing the "button" to proceed, you move on to another VIEW.
The problem is that if the "cancel" item is pressed, however, the button that is connected to the next VIEW continues to work. I would like if the user presses "cancel" it will be shown on the home page. The Button is connected via Main.Storyboard to the second VIEW Controller created.
Below is the part of the code I wrote:
#IBAction func touchID(_ sender: Any){
let context:LAContext = LAContext()
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)
{
context.evaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, localizedReason: "Autorization Required", reply: { (wasSuccessful, error) in
if wasSuccessful {
print("Correct")
//let vc = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewControllerID") as! SecondViewController
//self.present(vc, animated: true, completion: nil)
}
else
{
print("Incorrect")
}
})
}else{
print("TouchID/Facec ID not configured")
}
}
}
I am a beginner.
Try to do this:
Your "button" to proceed must call to your TouchID function. When you print "correct", you must create the navigation by code. If you print "Incorrect", dont create the navigation.
If you print "TouchID/Face ID not configured", you should show an alertview and maybe open the app settings configuration to enable/disable touch/faceId.

Mac NSTextField won't resign firstResponder

I have a window with some NSTextFields. When I click in one and edit the value and press return, I want the focus to go back to what it was before. I don't want the blue ring around the text field and I don't want further keystrokes going to that text field. I would have thought this would happen automatically.
I tried these, and none of them work
sender.resignFirstResponder()
sender.window?.makeFirstResponder(nil)
InspectorWindowController.window?.makeFirstResponder(nil)
AnotherWindowController.window?.becomeFirstResponder()
I'm doing these at the end of my IBAction associated with the text field. Maybe I have to do it from somewhere else?
Thanks
I figured this out. I guess the sent action is happening on another thread. So you have to call makeFirstResponder using Dispatch async.
DispatchQueue.main.async { //omg
sender.window?.makeFirstResponder(nil)
}
I needed to dismiss first responder in my SwiftUI macOS app and here what I found working in a way I need:
func controlTextDidEndEditing(_ obj: Notification) {
DispatchQueue.main.async {
guard let window = self.textField.window else {
return
}
// https://stackoverflow.com/questions/5999148/how-to-determine-whether-an-nssearchfield-nstextfield-has-input-focus
// We need to make sure that our text field is still first responder.
guard let textView = window.firstResponder as? NSTextView,
textView.delegate === self.textField else {
return
}
window.makeFirstResponder(nil)
}
}

Prevent an UIAlertView from closing on PositiveButton click

I am developing mobile application using Xamarin.Forms. I have requirement of getting input in the dialog box. So, i have used UIAlertView for getting text input as like below.
I need to prevent an UIAlertView from closing on button click. I need to retain the UIAlertView dialog box even after the action initiated.
Can anyone please help me on this?
Regards,
Karthikeyan
You could create a custom UIView for this using a Xib file, however if you have no objection to the dialog closing and reopening should it encounter a validation issue then the following would work fine.
EDIT: Adjusted to allow you to pass back the validation message, as the primary message on the UIAlertView.
private string message = string.Empty();
public void recursiveDialog()
{
string input = string.Empty();
if(message == string.Empty()) { message = "Please enter the view name"}
var alert = UIAlertController.Create ("Save View", message, UIAlertControllerStyle.Alert);
alert.AddTextField ((field) => {
field.Placeholder = "view name";});
alert.AddAction (UIAlertAction.Create ("Cancel", UIAlertActionStyle.Cancel, null));
alert.AddAction (UIAlertAction.Create ("Save", UIAlertActionStyle.Default, action => {
input = alert.TextFields[0].Text
}));
if (alert.PopoverPresentationController != null)
alert.PopoverPresentationController.BarButtonItem = myItem;
PresentViewController (alert, animated: true,
action => {
// when a dialog is selected and returns, run validation
if(input == [whatever you want to use to validate it against])
{
// it failed because it already exists for example so change our message
message = "That view name already exists, try again.";
// already exists, so re-run method.
recursiveDialog();
}
else
{
// doesn't alread exist so carry on with whatever you want to do with the name provided.
// clear your message variable
message = string.Empty();
}
});
}

Resources