【问题标题】:Presenting UIAlertController from UITableViewCell从 UITableViewCell 呈现 UIAlertController
【发布时间】:2015-08-09 13:50:38
【问题描述】:

我正在尝试向自定义UITableViewCell 添加警报以呈现UIAlertView 我需要从UIViewController 调用presentViewController。但是,我不知道如何从 UITableViewCell 类访问当前的 UIViewController 实例。下面的代码是我尝试通过扩展来做到这一点。

我收到这个错误

表达式解析为未使用的函数。

extension UIViewController
{

    class func alertReminden(timeInterval: Int)
    {
        var refreshAlert = UIAlertController(title: "Refresh", message: "All data will be lost.", preferredStyle: UIAlertControllerStyle.Alert)

        refreshAlert.addAction(UIAlertAction(title: "Ok", style: .Default, handler: { (action: UIAlertAction!) in
            Alarm.createReminder("Catch the Bus",
                timeInterval: NSDate(timeIntervalSinceNow: Double(timeInterval * 60)))
        }))

        refreshAlert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: { (action: UIAlertAction!) in
            println("Handle Cancel Logic here")
        }))

        UIViewController.presentViewController(refreshAlert)


    }
}

class CustomRouteViewCell: UITableViewCell {

【问题讨论】:

    标签: ios uitableview swift uiviewcontroller


    【解决方案1】:

    您可以使用此扩展来查找呈现单元格的 viewController

    extension UIView {
    var parentViewController: UIViewController? {
        var parentResponder: UIResponder? = self
        while parentResponder != nil {
            parentResponder = parentResponder!.nextResponder()
            if parentResponder is UIViewController {
                return parentResponder as! UIViewController!
            }
        }
        return nil
    }
    }
    

    或使用rootViewController 进行演示:

    UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(refreshAlert, animated: true, completion: nil)
    

    Swift 4.2 更新

    extension UIView {
        var parentViewController: UIViewController? {
            var parentResponder: UIResponder? = self
            while parentResponder != nil {
                parentResponder = parentResponder!.next
                if parentResponder is UIViewController {
                    return parentResponder as? UIViewController
                }
            }
            return nil
        }
    }
    

    或使用rootViewController 进行演示:

    UIApplication.shared.keyWindow?.rootViewController?.present(alertVC, animated: true, completion: nil)
    

    【讨论】:

      【解决方案2】:

      尝试替换为这行代码:

      斯威夫特 2

      UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(refreshAlert, animated: true, completion: nil)
      

      斯威夫特 3

      UIApplication.shared.keyWindow?.rootViewController?.present(refreshAlert, animated: true, completion: nil)
      

      【讨论】:

      • 感谢朋友们的努力。
      • 这不起作用,因为我的 tableview 也在导航控制器中。我能够使用 if let topController = UIApplication.topViewController() { topController.present(alertController, animated: true, completion: nil) } 进行演示
      【解决方案3】:

      另一种方法是在表格视图单元格类中声明协议和委托属性,将控制器设置为单元格委托并在能够呈现警报视图控制器的控制器中实现协议。

      【讨论】:

      • 我认为这种方法是最干净的。
      • 但是如果您想在警报解除后操作 tableviewcell 中的某些控件,您将无法访问它们
      • 嘿,我想使用你的建议,但不完全理解。我创建了一个协议并在单元类中声明了委托属性。当您说:“将控制器设置为单元委托并在控制器中实现协议”时,我迷路了。另外我必须在协议中创建什么功能?我使用了“func alert(vc: UIViewController)”。那会奏效吗?谢谢。
      【解决方案4】:

      Leo 的解决方案对我有用。我已经使用它从自定义集合视图单元格中呈现 AlertView。

      Swift 3.0 更新:

      extension UIView {
          var parentViewController: UIViewController? {
              var parentResponder: UIResponder? = self
              while parentResponder != nil {
                  parentResponder = parentResponder!.next
                  if parentResponder is UIViewController {
                      return parentResponder as! UIViewController!
                  }
              }
              return nil
          }
      }
      

      希望对你有帮助。

      【讨论】:

        【解决方案5】:

        您可以尝试使用协议和委托,使用此方法不仅可以让您有机会呈现警报,还可以让您与视图控制器进行更好的交互,以防您将来需要它。例如:

        protocol alerts: class{
        
            func presentAlert(title:String, message:String)
        
        }
        

        然后在您的 tableViewCell 中,您将创建如下内容:

        var alertsDelegate : alerts? 
        
        //And whenever you need to present a message call something inside the cell like:
        
        alertsDelegate?.presentAlert(title:"Your title", message:"Your message")
        

        然后在您的 viewController 中,首先将您的 viewController 设置为警报

        class yourClassName : ViewController, alerts {
        
            //And add the functions of the protocol
            func presentAlert(title:String, message:String){
                //This is the function that'll be called from the cell
                //Here you can personalize how the alert will be displayed
        
            }
        }
        

        其次,在“cellForRowAt”方法中为单元格设置委托

        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
            let cell = tableView.dequeueReusableCell(withIdentifier: "yourIdentifier") as! yourCellClass
        
            cell.alertsDelegate = self
        
        }
        

        就像这样,您可以创建多个函数来适应您与 viewController 或 viewController 通信的需要。

        【讨论】:

          【解决方案6】:

          必须在CustomTableViewCell Class and called these properties at the place of UIAlertViewController 中声明协议及其委托属性,并在UIViewController 中实现这些协议属性。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-01-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-05-06
            相关资源
            最近更新 更多