如何从 UIView 推送 UIViewController

Posted

技术标签:

【中文标题】如何从 UIView 推送 UIViewController【英文标题】:How to push a UIViewController from a UIView 【发布时间】:2017-11-08 10:00:42 【问题描述】:

我是 ios 开发的新手,我正在制作像许多应用程序一样的左侧菜单栏。我明白了,但现在我被困住了。请帮忙。

我有一个名为 LeftMenu 的类,它的声明如下:

类 LeftMenu: UIView, UITableViewDelegate, UITableViewDataSource

原因是我在多个 UIViewControllers 中使用相同的 LeftMenu

有一个 tableView 代表 scrollMenu,我正在观察选择的行,如下所示:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    switch self.menuItems[indexPath.row] 
    case "Wever":
        print(self.menuItems[indexPath.row])
    case "Payments":
        print(self.menuItems[indexPath.row])
    case "Profile":
        print(self.menuItems[indexPath.row])
    case "Trip History":
        print(self.menuItems[indexPath.row])
    case "Referral":
        print(self.menuItems[indexPath.row])
    case "Help":
        print(self.menuItems[indexPath.row])
    case "Settings":
        print(self.menuItems[indexPath.row])
    case "About":
        print(self.menuItems[indexPath.row])
    default:
        break
    

我使用 LeftMenu 在每个视图控制器中调出菜单。

我想做的是在选择 tableView 中的单元格时打开相应的视图控制器。请帮忙。

【问题讨论】:

你对应的视图控制器在哪里?在故事板中??你在故事板中定义了segue 吗?? 与问题无关的注释;您可以通过将 menuItems 对象分配给字符串并对其执行切换来优化 didSelectRowAt 方法!祝你未来好运:) @Bilal 我没有使用故事板。我正在以编程方式制作界面。 您好,欢迎来到 SO。你的问题已经被问过很多次了。例如。 ***.com/questions/39450124/… 你似乎对你真正的问题是什么感到困惑。这是“我如何以编程方式打开视图控制器”。请专注于您的主要问题,因为有关侧视图和应用工作方式的所有详细信息都与您的主要问题无关。 @FreeNickname 感谢您的链接。我不确定如何在 UIView 的子类中使用 self.pushViewController。 【参考方案1】:

您可以为 LeftMenu 视图创建一个委托协议,并让任何显示 LeftMenu 的视图控制器实现该协议,因此它们负责推送新的视图控制器。

在 LeftMenu.swift 中

protocol LeftMenuDelegate: class 
    func leftMenuDidSelectViewController(_ viewController: UIViewController)


class LeftMenu: UIView, UITableViewDelegate, UITableViewDataSource 
    public weak var delegate: LeftMenuDelegate?
    ...

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        switch self.menuItems[indexPath.row] 
        case "Wever":
            let viewController = WeverViewController() // or whatever it is named
            self.delegate?.leftMenuDidSelectViewController(viewController)
            ...
        
    
    ...

然后在所有显示 LeftMenu 的视图控制器中:

class SomeViewController: UIViewController, LeftMenuDelegate 
    ...
    // wherever you create you left menu, do this
    let leftMenu = LeftMenu()
    leftMenu.delegate = self
    ...

    // Add this method to be called from LeftMenu through the delegate protocol
    func leftMenuDidSelectViewController(_ viewController: UIViewController) 
        self.navigationController?.pushViewController(viewController, animated: true)
    

您可以创建一个基类,为所有包含 LeftMenu 视图的视图控制器执行此操作,因此您不必多次执行此实现。

【讨论】:

解决方法是什么? 我已经编辑了答案,以便更清楚地说明您应该在创建 LeftMenu 的视图控制器中做什么。如果有不明白的地方请告诉我 我已经实现了这个,但是当我按下一个单元格时,视图控制器不会在 case 语句中被推送。但是我在 case 块中有一个打印语句,它会打印到控制台。 它有效,但我不想拥有顶部导航栏 您不必推送新的视图控制器。您也可以使用此方法对视图控制器中的视图进行任何更改。所以不用让 LeftMenu 发送一个新的视图控制器,你可以让它调用一个方法,比如 setupWeverView() 或者你需要的任何东西。

以上是关于如何从 UIView 推送 UIViewController的主要内容,如果未能解决你的问题,请参考以下文章

UIView 自动向上 - 从 TabbarController 推送时

从 UIView 子类推送导航控制器会导致崩溃

以编程方式从 UiView 推送新视图控制器的问题

从 UIView ios 推送视图控制器

了解 UIView 是不是是从 UITabBar 的更多菜单中推送的

从 presentModalViewController 推送 uiviewcontroller