I have a view controller which with a button to restore the default settings. Contained within the same VC is the function restoreDefaults()
@IBAction func resetBtnAct(_ sender: Any) {
let alert = AlertGenFromVC(sendingVC: self).generateAlert(
titleIn: "Warning!",
messageIn: "You are about to reset to the default settings. You will not be able to undo this action.",
actionTitle1: "Reset", actionAct1: #selector(self.restoreDefaults), actionTitle2: "Cancel", actionAct2: nil)
self.present(
alert,
animated: false,
completion: nil)
}
I am passing this to another class which is then used to present the alert controller
class AlertGenFromVC {
var originVC: AnyObject?
var originTextField: UITextField?
init(sendingVC: AnyObject) {
originVC = sendingVC
}
func generateAlert(titleIn: String, messageIn: String, actionTitle1:String, actionAct1:Selector, actionTitle2:String?, actionAct2:Selector?) -> UIAlertController {
let alert = UIAlertController(
title: titleIn,
message: messageIn,
preferredStyle: .alert)
// Add first action
let action1 = UIAlertAction(title: actionTitle1, style: UIAlertAction.Style.default, handler: {(action) in actionAct1
})
alert.addAction(action1)
//Action 2
if actionTitle2 != nil && actionAct2 != nil {
print("act2")
let action2 = UIAlertAction(title: actionTitle2, style: UIAlertAction.Style.default, handler: {action in actionAct2
})
alert.addAction(action2)
} else if actionTitle2 != nil && actionAct2 == nil {
print("action 2 nil")
let action2 = UIAlertAction(title: actionTitle2, style: UIAlertAction.Style.default, handler: nil)
alert.addAction(action2)
}
let popover = alert.popoverPresentationController
popover?.sourceView = self.originVC as? UIView
popover?.sourceRect = CGRect(x: 32, y: 32, width: 64, height: 64)
return alert
}
}
Action 1 and 2 both show a warning "Expression of type 'Selector' is unused".
The alert is presented fine but there is no action on clicking the button. Am i defining the selectors incorrectly or am I doing something else wrong? All suggestions gratefully received.
CodePudding user response:
An extra class to create an alert controller to be presented by an UIViewController
is an unswifty approach.
A better one is an extension of UIViewController
extension UIViewController {
func showAlert(titleIn: String,
messageIn: String,
actionTitle1: String,
actionAct1: (() -> Void)? = nil,
actionTitle2: String?,
actionAct2: (() -> Void)? = nil) {
let alert = UIAlertController(
title: titleIn,
message: messageIn,
preferredStyle: .alert)
// Add first action
let action1 = UIAlertAction(title: actionTitle1, style: .default, handler: { _ in actionAct1?() })
alert.addAction(action1)
//Action 2
if let title2 = actionTitle2 {
print(title2)
let action2 = UIAlertAction(title: title2, style: .default, handler: { _ in actionAct2?() })
alert.addAction(action2)
}
let popover = alert.popoverPresentationController
popover?.sourceView = self.view
popover?.sourceRect = CGRect(x: 32, y: 32, width: 64, height: 64)
self.present(alert, animated: true, completion: nil)
}
and use it
func restoreDefaults() {
// do something
}
func resetBtnAct(_ sender: Any) {
self.showAlert(
titleIn: "Warning!",
messageIn: "You are about to reset to the default settings. You will not be able to undo this action.",
actionTitle1: "Reset",
actionAct1: restoreDefaults,
actionTitle2: "Cancel")
}
CodePudding user response:
You can directly pass the function as a parameter. For example like this:
let alert = AlertGenFromVC(sendingVC: self).generateAlert(
titleIn: "Warning!",
messageIn: "You are about to reset to the default settings. You will not be able to undo this action.",
actionTitle1: "Reset", actionAct1: self.restoreDefaults, actionTitle2: "Cancel", actionAct2: nil)
The function generateAlert would look like this:
func generateAlert(titleIn: String, messageIn: String, actionTitle1:String, actionAct1: @escaping ((UIAlertAction) -> Void), actionTitle2:String?, actionAct2: ((UIAlertAction) -> Void)? = nil) -> UIAlertController {
let alert = UIAlertController(
title: titleIn,
message: messageIn,
preferredStyle: .alert)
// Add first action
let action1 = UIAlertAction(title: actionTitle1, style: UIAlertAction.Style.default, handler: actionAct1)