Ionic : Prevent alert auto dismiss when clicked on 'OK' - ionic-framework

Clicking on 'OK' automatically dismisses the alert. I want to add some logic inside 'OK' click handler and then decide if I want to dismiss the alert or not.
let inputsAlert = this.alertCtrl.create({
...
buttons: [
{
text: 'OK',
handler: inputsData => {
// Some logic here
if (canDismiss) {
this.inputsAlert.dismiss();
} else {
// Do nothing
}
}
}
]
})

In the array of buttons, each button includes properties for its text, and optionally a handler. If a handler returns false then the alert will not automatically be dismissed when the button is clicked.
From https://ionicframework.com/docs/api/alert#buttons
Simply return false if you do not want the alert to be dismissed.

Related

SwiftMessage: how to handle action when user tap on outside of message view?

I'm using SwiftMessage in my project. when the specific message is showing on the screen, I want when the user tap on outside of the message view (anywhere else on message view), some actions happening. how can I do this?
update
I forgot to say I'm using SwiftMessage with one button.
Unfortunately, there isn't a way to add an action on tap outside of the MessageView.
However, if your dimMode is interactive (has tap outside to dismiss enabled) you can easily catch .willHide and .didHide events using eventListeners of SwiftMessages.Config:
let view = MessageView.viewFromNib(layout: .cardView)
var config = SwiftMessages.defaultConfig
config.dimMode = .gray(interactive: false)
config.eventListeners.append { event in
switch event {
case .willHide:
// Handle will hide
case .didHide:
// Handle did hide
default:
break
}
}
SwiftMessages.show(config: config, view: view)
Those events will be triggered on tap outside of the MessageView.
Update: In your particular case where you have a button which have a different action from the tap outside action, you can use something like this:
func showMessageView(buttonHandler: #escaping () -> Void, dismiss: #escaping () -> Void) {
var buttonTapped = false
let view = MessageView.viewFromNib(layout: .cardView)
view.buttonTapHandler = { sender in
buttonHandler()
buttonTapped = true
}
var config = SwiftMessages.defaultConfig
config.dimMode = .gray(interactive: false)
config.eventListeners.append { event in
if !buttonTapped, event == .didHide {
dismiss()
}
}
SwiftMessages.show(config: config, view: view)
}
That way when the button is tapped the dismiss closure will never run.

How to add a clickable button in a List without triggering NavigationLink event?

I have a button in a list item and when I click on it, the NavigationLink's event is also being triggered.
I only want to trigger the button event. How to do it?
following is my code:
ForEach(self.cares,id:\.id){ care in
HStack{
if(care.markMode == "打卡"){
Button("今日未打卡"){
}
else{
Button("新增记录"){
self.care = care
self.showSheetNewMark.toggle()
}
}
NavigationLink(destination:CareDetailView(care: care)){
Text("\(care.nickname!)的\(care.subject!)")
}
}
}
Add PlainButtonStyle for button, as in below example
Button("新增记录"){
self.care = care
self.showSheetNewMark.toggle()
}
.buttonStyle(PlainButtonStyle()) // << here !!

Why is it that after showing an NSAlert nothing works?

Why is it that after showing an NSAlert nothing works until I close the NSAlert?
I was trying to print a statement after the display of an NSAlert but print is not working.
Below I have attached my code:
let alert: NSAlert = NSAlert()
alert.messageText = "Hello I am Message text"
alert.informativeText = "i am information"
alert.addButton(withTitle: "OK") // First Button
alert.addButton(withTitle: "Cancel") // 2nd Button
alert.alertStyle = NSAlert.Style.warning
alert.delegate = self
if alert.runModal() == .alertFirstButtonReturn {
print("First Button clicked")
} else {
print("Cancel button clicked")
}
print("after NSAlert >>>>>>> ")
My question is why.
Notice how runModal returns the result of the modal as a NSModalResponse. Code after the line alert.runModal() must be able to access the value that it returns, e.g.
let result = alert.runModal()
print(result)
If the code after runModal were run as soon as the modal is displayed, what would result be? The user has not clicked any buttons on the modal yet, so no one knows!
This is why when runModal is called, code execution kind of just pauses there, at that line, until the user chooses one of the options. runModal is synchronous and blocking.
Compare this with alert.beginSheetModal, which accepts a completionHandler closure, and the modal response is not returned, but passed to the completionHandler. This allows the code after the call to continue to run while the modal is presented, because the code after the call does not have access to the modal response. Only the code in the completionHandler does. beginSheetModal is asynchronous.
If you have something you want to print as soon as the alert is displayed, write it before the runModal call, and (optionally) wrap it in a DispatchQueue.asyncAfter/DispatchQueue.async call, so that your print is asynchronous.
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) {
print("Hello")
}
alert.runModal()
if alert.runModal()
This is executed in application-wide modal session
Here is from doc:
Summary
Runs the alert as an app-modal dialog and returns the constant that
identifies the button clicked. Declaration
open func runModal() -> NSApplication.ModalResponse

Disable the auto dismissal of the alert when tapping on a button

func showAlert(...) {
let alertController = UIAlertController(...)
let add = UIAlertAction(title: "Add", style: .default) { (action) in
onAdd?()
}
alertController.addAction(ok)
...
}
I would like to keep the popup alert after click on Add. But it seem iOS will auto close the popup. How to make it work?
The only way to prevent a UIAlertController's alert from being dismissed when a button is tapped is to disable the button.
If you don't like that, don't use UIAlertController; use your own presented view controller. That's all a UIAlertController is, after all. So it's easy to write your own if you need to.

Cannot manually set the highlighted state of a UIButton in an IBAction method

Inside my ViewController, I have two IBOutlets signUpButton and memberButton, and both buttons are linked to same signUpOrMemberButtonPressed() IBAction func. I am trying to set highlighted property to these 2 buttons so I can do subsequent work accordingly inside my submitPressed() IBAction func. But I noticed odd behavior between signUpOrMemberButtonPressed() and submitPressed() IBActions. After tapping on either signUpButton or memberButton, the button was highlighted inside my signUpOrMemberButtonPressed(), but by the time it executed submitPressed(), debug showed it's not highlighted. Here is my signUpOrMemberButtonPressed():
#IBAction func signUpOrMemberButtonPressed(sender: AnyObject) {
var button = sender as UIButton
button.highlighted = true
if signUpButton.highlighted {
memberButton.highlighted = false
} else {
signUpButton.highlighted = false
}
if (signUpButton.highlighted) {
println("signUpButton is highlighted inside 1st button")
} else if (memberButton.highlighted) {
println("memberButton is highlighted inside 1st button")
} else {
println("nothing is highlighted inside 1st button")
}
}
My submitPressed function:
#IBAction func submitPressed(sender: AnyObject) {
if (signUpButton.highlighted) { println("signUpButton is highlighted inside 2st button") }
else if (memberButton.highlighted) { println("memberButton is highlighted inside 2st button") }
else { println("nothing is highlighted inside 2nd button")
}
When run my app, I tapped on memberButton and then tapped on submit button. Here is the log output:
memberButton is highlighted inside 1st button
nothing is highlighted inside 2nd button
Nothing was set to run between these two func calls.
What is happening here is that the button is "un-highlighting" itself (after you manually set highlighted = true).
From the documentation of the highlighted property:
UIControl automatically sets and clears this state automatically when
a touch enters and exits during tracking and when there is a touch up.
You can set the highlighted state manually but you would have to do it after the UIButton unsets the highlighted state. You would have to do this on the next run loop which you can do by using dispatch_async.
The following should work:
var button = sender as UIButton
dispatch_async(dispatch_get_main_queue()) {
self.memberButton.highlighted = button == self.memberButton
self.signUpButton.highlighted = button == self.signUpButton
}