如何创建可重用的 UIAlert ActionSheet 作为 UIViewController 扩展?
How to create a reusable UIAlert ActionSheet as an UIViewController extension?
我想创建一个可以在我的代码中多次使用的操作 sheet。为此,我需要能够根据操作 sheet 标题使用函数。有没有办法像 "title" 参数一样将函数作为参数数组传递?
//MARK: - UIAlert action sheet title
enum ActionSheetLabel: String {
case camera = "Camera"
case photoLibrary = "Album"
case cancel = "Cancel"
}
class CameraHandler {
static let cameraHandler = CameraHandler()
func openCamera() { }
func openPhotoLibrary() { }
}
//MARK: - Alert that shows an action sheet with cancel
extension UIViewController {
func showActionSheetWithCancel(vc: UIViewController, title: [ActionSheetLabel] /*Make a function parameter here to match title*/) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
for value in title {
actionSheet.addAction(UIAlertAction(title: value.rawValue, style: .default, handler: {
(alert: UIAlertAction!) -> Void in
//Use the parameter function here to match title
}))
}
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.cancel.rawValue, style: .cancel, handler: nil))
vc.present(actionSheet, animated: true, completion: nil)
}
}
您可以传递闭包并在处理程序中调用它,这样应该可以。
也不确定你为什么要传递 UIViewController
,因为你已经在 extension UIViewController
中定义了函数,因此我允许自己删除它并使用 self.present
代替.
extension UIViewController {
func showActionSheetWithCancel(title: [ActionSheetLabel], action: @escaping () -> ()?) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
for value in title {
actionSheet.addAction(UIAlertAction(title: value.rawValue, style: .default, handler: {
(alert: UIAlertAction!) -> Void in
// action
action()
}))
}
let alertAction = UIAlertAction(title: ActionSheetLabel.cancel.rawValue, style: .cancel) { (_) in
action() // or for cancel call it here
}
actionSheet.addAction(alertAction)
self.present(actionSheet, animated: true, completion: nil)
}
}
如您所见,@escaping () -> ()?
是可选的,因此您也可以传递 nil
。
对于 UIAlert,您只需更改 preferredStyle .alert 它即可用于 UIAlert 而下面的代码只需复制并粘贴即可用于 UIActionSheet。
extension UIViewController {
func popupAlert(title: String?, message: String?, actionTitles:[String?], actionStyle:[UIAlertAction.Style], actions:[((UIAlertAction) -> Void)?], vc: UIViewController) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .actionSheet)
for (index, title) in actionTitles.enumerated() {
let action = UIAlertAction(title: title, style: actionStyle[index], handler: actions[index])
alert.addAction(action)
}
vc.present(alert, animated: true, completion: nil)
}
}
检查下面的代码使用
self.popupAlert(title: "Alert"), message: “Error in Loading”, actionTitles: ["Okey", "Email"], actionStyle: [.default, .default], actions: [nil,{ action in
// I have set nil for first button click
// do your code for second button click
}], vc: self)
如果您有任何疑问,请评论我。谢谢
据我了解,您需要在警报标题更改时调用特定函数,并且您还希望能够从不同的 viewController 执行此操作,
我希望这会有所帮助
extension UIViewController {
func showActionSheetWithCancel(vc: UIViewController, title: [ActionSheetLabel] ) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cameraHandler = CameraHandler()
for value in title {
switch value.rawValue {
case ActionSheetLabel.camera.rawValue:
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.camera.rawValue, style: .default, handler: { (alert) in
cameraHandler.openCamera()
}))
case ActionSheetLabel.photoLibrary.rawValue:
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.photoLibrary.rawValue, style: .default, handler: { (alert) in
cameraHandler.openPhotoLibrary()
}))
default:
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.cancel.rawValue, style: .cancel, handler: nil))
}
vc.present(actionSheet, animated: true, completion: nil)
}
}
}
函数的调用将是这样的:
showActionSheetWithCancel(vc: self, title: [UIViewController.ActionSheetLabel.camera])
我找到了添加操作 sheet 的最佳方法,可以取消并根据需要添加尽可能多的操作。
使用类型别名创建 UIViewController 扩展:
//MARK: - Alert that shows an action sheet with cancel
extension UIViewController {
typealias AlertAction = () -> ()
typealias AlertButtonAction = (ActionSheetLabel, AlertAction)
func showActionSheetWithCancel(titleAndAction: [AlertButtonAction]) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
for value in titleAndAction {
actionSheet.addAction(UIAlertAction(title: value.0.rawValue, style: .default, handler: {
(alert: UIAlertAction!) -> Void in
value.1()
}))
}
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.cancel.rawValue, style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
}
然后,在class或者其他你想使用的地方,这样添加方法:
//MARK: - UIAlert action sheet title
enum ActionSheetLabel: String {
case camera = "Camera"
case photoLibrary = "Album"
case cancel = "Cancel"
}
//MARK: - Class example where to use the action sheet action
class CameraHandler {
fileprivate let currentVC: UIViewController!
func openCamera() {
// Open user camera
}
func openPhotoLibrary() {
// Open user photo library
}
// Method example of this action sheet
func showActionSheetWithCameraAndLibrary(vc: UIViewController) {
//This is the way to use the extension
vc.showActionSheetWithCancel(titleAndAction: [
(ActionSheetLabel.camera, { [weak self] in self?.openCamera() }),
(ActionSheetLabel.photoLibrary, { [weak self] in self?.openPhotoLibrary() })
])
}
}
我想创建一个可以在我的代码中多次使用的操作 sheet。为此,我需要能够根据操作 sheet 标题使用函数。有没有办法像 "title" 参数一样将函数作为参数数组传递?
//MARK: - UIAlert action sheet title
enum ActionSheetLabel: String {
case camera = "Camera"
case photoLibrary = "Album"
case cancel = "Cancel"
}
class CameraHandler {
static let cameraHandler = CameraHandler()
func openCamera() { }
func openPhotoLibrary() { }
}
//MARK: - Alert that shows an action sheet with cancel
extension UIViewController {
func showActionSheetWithCancel(vc: UIViewController, title: [ActionSheetLabel] /*Make a function parameter here to match title*/) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
for value in title {
actionSheet.addAction(UIAlertAction(title: value.rawValue, style: .default, handler: {
(alert: UIAlertAction!) -> Void in
//Use the parameter function here to match title
}))
}
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.cancel.rawValue, style: .cancel, handler: nil))
vc.present(actionSheet, animated: true, completion: nil)
}
}
您可以传递闭包并在处理程序中调用它,这样应该可以。
也不确定你为什么要传递 UIViewController
,因为你已经在 extension UIViewController
中定义了函数,因此我允许自己删除它并使用 self.present
代替.
extension UIViewController {
func showActionSheetWithCancel(title: [ActionSheetLabel], action: @escaping () -> ()?) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
for value in title {
actionSheet.addAction(UIAlertAction(title: value.rawValue, style: .default, handler: {
(alert: UIAlertAction!) -> Void in
// action
action()
}))
}
let alertAction = UIAlertAction(title: ActionSheetLabel.cancel.rawValue, style: .cancel) { (_) in
action() // or for cancel call it here
}
actionSheet.addAction(alertAction)
self.present(actionSheet, animated: true, completion: nil)
}
}
如您所见,@escaping () -> ()?
是可选的,因此您也可以传递 nil
。
对于 UIAlert,您只需更改 preferredStyle .alert 它即可用于 UIAlert 而下面的代码只需复制并粘贴即可用于 UIActionSheet。
extension UIViewController {
func popupAlert(title: String?, message: String?, actionTitles:[String?], actionStyle:[UIAlertAction.Style], actions:[((UIAlertAction) -> Void)?], vc: UIViewController) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .actionSheet)
for (index, title) in actionTitles.enumerated() {
let action = UIAlertAction(title: title, style: actionStyle[index], handler: actions[index])
alert.addAction(action)
}
vc.present(alert, animated: true, completion: nil)
}
}
检查下面的代码使用
self.popupAlert(title: "Alert"), message: “Error in Loading”, actionTitles: ["Okey", "Email"], actionStyle: [.default, .default], actions: [nil,{ action in
// I have set nil for first button click
// do your code for second button click
}], vc: self)
如果您有任何疑问,请评论我。谢谢
据我了解,您需要在警报标题更改时调用特定函数,并且您还希望能够从不同的 viewController 执行此操作, 我希望这会有所帮助
extension UIViewController {
func showActionSheetWithCancel(vc: UIViewController, title: [ActionSheetLabel] ) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cameraHandler = CameraHandler()
for value in title {
switch value.rawValue {
case ActionSheetLabel.camera.rawValue:
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.camera.rawValue, style: .default, handler: { (alert) in
cameraHandler.openCamera()
}))
case ActionSheetLabel.photoLibrary.rawValue:
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.photoLibrary.rawValue, style: .default, handler: { (alert) in
cameraHandler.openPhotoLibrary()
}))
default:
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.cancel.rawValue, style: .cancel, handler: nil))
}
vc.present(actionSheet, animated: true, completion: nil)
}
}
}
函数的调用将是这样的:
showActionSheetWithCancel(vc: self, title: [UIViewController.ActionSheetLabel.camera])
我找到了添加操作 sheet 的最佳方法,可以取消并根据需要添加尽可能多的操作。
使用类型别名创建 UIViewController 扩展:
//MARK: - Alert that shows an action sheet with cancel
extension UIViewController {
typealias AlertAction = () -> ()
typealias AlertButtonAction = (ActionSheetLabel, AlertAction)
func showActionSheetWithCancel(titleAndAction: [AlertButtonAction]) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
for value in titleAndAction {
actionSheet.addAction(UIAlertAction(title: value.0.rawValue, style: .default, handler: {
(alert: UIAlertAction!) -> Void in
value.1()
}))
}
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.cancel.rawValue, style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
}
然后,在class或者其他你想使用的地方,这样添加方法:
//MARK: - UIAlert action sheet title
enum ActionSheetLabel: String {
case camera = "Camera"
case photoLibrary = "Album"
case cancel = "Cancel"
}
//MARK: - Class example where to use the action sheet action
class CameraHandler {
fileprivate let currentVC: UIViewController!
func openCamera() {
// Open user camera
}
func openPhotoLibrary() {
// Open user photo library
}
// Method example of this action sheet
func showActionSheetWithCameraAndLibrary(vc: UIViewController) {
//This is the way to use the extension
vc.showActionSheetWithCancel(titleAndAction: [
(ActionSheetLabel.camera, { [weak self] in self?.openCamera() }),
(ActionSheetLabel.photoLibrary, { [weak self] in self?.openPhotoLibrary() })
])
}
}