Ios 从单元格中显示UIAlertController
我想通过点击单元格上的菜单按钮来演示UIAlertControllerIos 从单元格中显示UIAlertController,ios,swift,uitableview,protocols,uialertcontroller,Ios,Swift,Uitableview,Protocols,Uialertcontroller,我想通过点击单元格上的菜单按钮来演示UIAlertController class FeedViewCell: UITableViewCell { // some code... lazy var menuButton: UIButton = { let btn = UIButton() btn.addTarget(self, action: #selector(menuTapped), for: .touchUpInside) return
class FeedViewCell: UITableViewCell {
// some code...
lazy var menuButton: UIButton = {
let btn = UIButton()
btn.addTarget(self, action: #selector(menuTapped), for: .touchUpInside)
return btn
}()
@objc func menuTapped() {
let actionSheet = UIAlertController(title: "", message: "", preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Dismiss", style: .cancel, handler: { action in
print("tap dismiss")
}))
actionSheet.addAction(UIAlertAction(title: "Follow", style: .default, handler: { action in
print("tap follow")
}))
present(actionSheet, animated: true)
}
}
这是一个FeedViewController:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellid", for: indexPath) as! FeedViewCell
return cell
}
但是,我收到错误“在范围中找不到“present”
我不知道如何使用委托和协议来表示它。请帮助我解决问题对于单元内的当前警报,您应该获得父控制器。警报控制器只能出现在其他父控制器上 让我们做吧。首先,添加扩展名。它允许使用以下方式获取视图的控制器:
公共扩展视图{
var viewController:UIViewController{
弱var parentResponder:UIResponder?=自身
而parentResponder!=零{
parentResponder=parentResponder!。下一步
如果让viewController=parentResponder作为?UIViewController{
返回视图控制器
}
}
归零
}
}
现在您可以在单元内部获取控制器。让我们这样做:
@objc func menutaped(){
//你在这里添加了警报,你的代码
guard let parentController=self.viewController else{return}
parentController.present(操作表,动画:true)
}
所有这些。对于单元内的当前警报,您应该获得父控制器。警报控制器只能出现在其他父控制器上 让我们做吧。首先,添加扩展名。它允许使用以下方式获取视图的控制器:
公共扩展视图{
var viewController:UIViewController{
弱var parentResponder:UIResponder?=自身
而parentResponder!=零{
parentResponder=parentResponder!。下一步
如果让viewController=parentResponder作为?UIViewController{
返回视图控制器
}
}
归零
}
}
现在您可以在单元内部获取控制器。让我们这样做:
@objc func menutaped(){
//你在这里添加了警报,你的代码
guard let parentController=self.viewController else{return}
parentController.present(操作表,动画:true)
}
所有这些。Ivan寻找UIViewController响应者链的方法都是可行的,但我建议采用另一种方法 修改您的
FeedViewCell
类以具有可选的viewController属性:
class FeedViewCell: UITableViewCell {
// Note that the pointer to the view controller should be weak
// To avoid a retain cycle, as pointed out by Matt.
weak var viewController: UIViewController? = nil
// some code...
}
并修改IBAction方法:
@IBAction func menuTapped() {
// Make sure `viewController` is not nil.
guard let viewController = viewController else {
print("No view controller found. Exiting.")
return
}
let actionSheet = UIAlertController(title: "", message: "", preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Dismiss", style: .cancel, handler: { action in
print("tap dismiss")
}))
actionSheet.addAction(UIAlertAction(title: "Follow", style: .default, handler: { action in
print("tap follow")
}))
// Change your code to send the `present(_:animated:)` message to
// the cell's `viewController`.
viewController.present(actionSheet, animated: true)
}
}
然后在配置FeedViewCell单元格的视图控制器中,设置单元格的viewController属性:
func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Replace with the correct reuse identifier
guard let cell = tableView.dequeueReusableCell(withIdentifier: yourIdentifier) as? FeedViewCell else {
return UITableViewCell()
}
cell.viewController = self // Or, if the data source is not the main view controller for the window, pass in some other view controller.
}
Ivan寻找UIViewController响应者链的方法是可行的,但我建议采用另一种方法 修改您的
FeedViewCell
类以具有可选的viewController属性:
class FeedViewCell: UITableViewCell {
// Note that the pointer to the view controller should be weak
// To avoid a retain cycle, as pointed out by Matt.
weak var viewController: UIViewController? = nil
// some code...
}
并修改IBAction方法:
@IBAction func menuTapped() {
// Make sure `viewController` is not nil.
guard let viewController = viewController else {
print("No view controller found. Exiting.")
return
}
let actionSheet = UIAlertController(title: "", message: "", preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Dismiss", style: .cancel, handler: { action in
print("tap dismiss")
}))
actionSheet.addAction(UIAlertAction(title: "Follow", style: .default, handler: { action in
print("tap follow")
}))
// Change your code to send the `present(_:animated:)` message to
// the cell's `viewController`.
viewController.present(actionSheet, animated: true)
}
}
然后在配置FeedViewCell单元格的视图控制器中,设置单元格的viewController属性:
func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Replace with the correct reuse identifier
guard let cell = tableView.dequeueReusableCell(withIdentifier: yourIdentifier) as? FeedViewCell else {
return UITableViewCell()
}
cell.viewController = self // Or, if the data source is not the main view controller for the window, pass in some other view controller.
}
你的整个方法是错误的;一个细胞在周围指挥视图控制器是不合适的。但是,如果您坚持,请使用此实用程序:
extension UIResponder {
func next<T:UIResponder>(ofType: T.Type) -> T? {
let r = self.next
if let r = r as? T ?? r?.next(ofType: T.self) {
return r
} else {
return nil
}
}
}
你的整个方法是错误的;一个细胞在周围指挥视图控制器是不合适的。但是,如果您坚持,请使用此实用程序:
extension UIResponder {
func next<T:UIResponder>(ofType: T.Type) -> T? {
let r = self.next
if let r = r as? T ?? r?.next(ofType: T.self) {
return r
} else {
return nil
}
}
}
只有视图控制器才能显示警报。添加回调闭包,将操作移动到控制器中,并从那里显示警报。下面是一个示例:使用视图控制器执行此操作。在cellForRowAt委托方法中添加闭包。您可以在下面的链接中找到一些方法:只有视图控制器才能显示警报。添加回调闭包,将操作移动到控制器中,并从那里显示警报。下面是一个示例:使用视图控制器执行此操作。在cellForRowAt委托方法中添加一个闭包。您可以在下面的链接中找到一些方法:这种方法通常是有效的,但它是脆弱的。如果视图控制器层次结构中有多个父视图控制器,则代码可能会选择错误的父视图控制器。最好给单元格一个viewController属性并让父视图控制器填充它。我不同意。它不易碎。我们知道所需的类。这种方法通常是有效的,但它是脆弱的。如果视图控制器层次结构中有多个父视图控制器,则代码可能会选择错误的父视图控制器。最好给单元格一个viewController属性并让父视图控制器填充它。我不同意。它不易碎。我们知道想要的类。在这里保留循环?这是真的。是的,返回视图控制器的指针应该很弱。在这里保留循环?这是真的。是的,返回视图控制器的指针应该很弱。