我有一个带有按钮的表格视图单元格。单击该按钮后,我要显示一个警报控制器。我现在实现的是一个委托模式,如下所示:
https://stackoverflow.com/a/49199783/6724161
问题是我在多个视图控制器中的整个应用程序中使用此表视图单元,因此我不想将相同的警报控制器代码复制并粘贴到每个视图控制器中。
当单击表格视图单元格中的按钮时,如何在任何视图控制器上显示警报控制器?
答案 0 :(得分:1)
您可以使用注释中指出的通知,但我会做其他事情。
1。。在您的自定义单元格类中,我将添加一个类型为uint
的名为parentVC
的属性:
UIViewController
2。然后,当您使单元出队时,我将单元的class YourTableViewCell: UITableViewCell {
var parentVC: UIViewController!
...
}
设置为parentVC
,如下所示:
self
3。最后,每当单击自定义单元格的按钮时,只需从func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell! = tableView.dequeueReusableCell(withIdentifier: "YourCellIdentifier") as! YourTableViewCell
//`self` is the view controller that the cell's table view is held in
cell.parentVC = self
return cell
}
中显示警报控制器即可:
parentVC
另一种变化形式(由rmaddy建议)
您只需更改class YourTableViewCell: UITableViewCell {
var parentVC: UIViewController!
@IBAction func customButtonPressed(_ sender: Any) {
let alertController = UIAlertController(title: "Your alert title.", message: "Your alert message.", preferredStyle: .alert)
parentVC.present(alertController, animated: true, completion: nil)
}
...
}
中的按钮即可递归检查下一个响应者,直到其类型为UITableViewCell
。
首先将以下扩展名添加到UIViewController
。这将找到UIView
的父视图控制器:
UIView
您只需更改extension UIView {
var parentViewController: UIViewController? {
var parentResponder: UIResponder? = self
while parentResponder != nil {
parentResponder = parentResponder!.next
if let viewController = parentResponder as? UIViewController {
return viewController
}
}
return nil
}
}
中的按钮即可递归检查下一个响应者,直到其类型为UITableViewCell
。找到此UIViewController
后,您可以让它显示UIViewController
或任何其他视图控制器:
来源:Given a view, how do I get its viewController?
找到此UIAlertController
后,您可以让它显示UIViewController
或任何其他视图控制器:
UIAlertController
答案 1 :(得分:0)
您可以使用AppDelegates窗口属性进行显示。
let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alert.addAction(action)
UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true, completion: nil)
最好基于应用程序rootViewController类型进行验证,以避免 问题。例如,
如果rootViewController是navigationController,则可以使用navigationController的顶部viewController并显示警报。
如果rootViewController是UIViewController,则可以直接从rootViewController呈现。
答案 2 :(得分:0)
您可以使用Notification
模式解决问题。
首先,我强烈建议您为通知内容扩展Notification.Name
来构建通知图。
extension Notification.Name {
static let notificationForAlertingStuff = Notification.Name("isAlertReallyAlert")
}
然后创建警报内容的观察者通知。
override func viewDidLoad() {
NotificationCenter.default.addObserver(self, selector: #selector(onDidReceiveData(_:)), name: Notification.Name("isAlertReallyAlert"), object: nil)
}
创建自己的通知处理程序功能。
@objc private func onDidReceiveData(_ notification: NSNotification){
print("notification has fired. user info => \(notification.userInfo) ")
// present alert
}
我认为您必须扩展UIViewController
并添加一个简单的函数来获取title
和description
参数来发出警报。目前,仅从Notification.
然后,当您触发任何通知时,请在按钮单击或行单击中使用此功能。
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var alertData = ["title": "Alert Title", "description": "Alert Description"]
NotificationCenter.default.post(name: Notification.Name("isAlertReallyAlert"), object: self, userInfo: alertData)
}
因此,也许您可以为用户信息指定并添加功能以准备任何警报。
最后这是UIViewController
使用UIAlertController
efficiently
的扩展名。
extension UIViewController{
func shotAlert(title:String, description:String){
// Create Alert Controller
}
}
//良好点:
让我们假设您的视图控制器A, B and C
与UINavigationController
一样生活在A -> B -> C
堆栈中,因此,如果您在A控制器中添加观察者,则可以按照您描述的{{ 1}}。