【问题标题】:Protocol not being executed协议未执行
【发布时间】:2018-08-22 11:45:05
【问题描述】:

我正在尝试在整个应用程序中实现明暗主题。我的问题是它不能正常工作。我有一个 ContainerVC,其中包含 2 个 ContainerViews - SidebarMenuVCDashboardVCSidebarMenuVC 是偏移量,因此最初显示的是用户 DashboardVC

ContainerVC 嵌入在UINavigationController 中,并且有一个汉堡式菜单。当用户点击该菜单按钮时,将显示SidebarMenuVC。这一切都很好。

SidebarMenuVC 包含负责更改应用主题的图像。当用户点击图像时,它会从亮变为暗,反之亦然。点击的那一刻改变了SidebarMenuVC 的主题,但是当你隐藏菜单(通过滑动)时,DashboardVC 的主题没有被应用。我尝试使用protocol 来做到这一点,但我认为我做得不对(好吧,它不起作用,所以我知道我搞砸了)。

protocol ReloadTheme {
    func reload()
}

class ContainerVC: UIViewController, SidebarDelegate {

    var delegateReloadTheme: ReloadTheme?
    func hideMenu() {
        sideBarMenuLeadingConstraint.constant = -300
        applyTheme()
        animateConstraint()
        delegateReloadTheme?.reload() // when I put a breakpoint here, it shows it's nil
    }
}

extension DashboardVC : ReloadTheme {
    func reload() {
        applyTheme()
    }
}

所以,大局是:当用户向右滑动到hideMenu()(在ContainerVC中,它需要访问DashboardVC并调用applyTheme()

协议/代表总是让我感到困惑,因此欢迎提供一点帮助。

好的,按照要求,sidebarMenu 的连接方式如下:

protocol SideBarDelegate: class {
      func showMenu()
      func hideMenu()
}
class DashboardVC: UIViewController {
   static weak var delegateSideBar: SideBarDelegate?

    @IBAction func sideMenuButtonPressed(_ sender: UIBarButtonItem) {
         Dashboard.delegateSideBar?.showMenu()
     }    
} 

然后在ContainerVC

class ContainerVC: UIViewController, SideBarDelegate {
  override func viewDidLoad() {
    super.viewDidLoad()
    DashboardVC.delegateSideBar = self
  }

 func hideMenu() {
    sideBarMenuLeadingConstraint.constant = -300
    dimView.isHidden = true
    applyTheme()
    animateConstraint()
  //  delegateReloadTheme?.reloadTheme()
}
func showMenu() {
    sideBarMenuLeadingConstraint.constant = 0
    dimView.isHidden = false
    applyTheme()
    animateConstraint()
}

func animateConstraint() {
    UIView.animate(withDuration: 0.3) {
        self.view.layoutIfNeeded()
    }
  }
}

这就是滑动菜单的工作原理和连接方式。

【问题讨论】:

  • 为此,必须为属性delegateReloadTheme 分配一个对象,该对象在代码中的某个位置实现ReloadTheme 协议。是这样吗?
  • 不,但我知道它需要完成,我只是不知道在哪里做......
  • @Dani 当您在此处放置断点时它显示为零,因为您的委托是您从未设置过的可选对象。
  • 尝试在 viewDidLoad 中设置您的代理
  • @Dani 看看答案。另外,请提供以某种方式连接 DashboardVC 和侧菜单的代码

标签: swift uiviewcontroller protocols


【解决方案1】:

您需要在某处分配您的委托 - 它是可选类型。

例如,在viewDidLoad 中,您可以说item.delegateReloadTheme = self

您需要显示更多关于DashboardVC 的代码。

基本上,当您创建委托时,您正在为需要委托的工作创建接口,并将其委托给其他类。因为您几乎可以在代码中的任何位置实现委托,所以您需要告诉谁负责实现该委托(接口)。

例如:

protocol RefresherDelegate {
    func refreshUI()
}

在这里我们定义了哪些函数将被委托。

class MyView : UIView {
    var delegate: RefresherDelegate?
}

在这里,我们创建一个变量来保存实际上符合RefresherDelegate 的对象。

class MyObject : RefresherDelegate {
    var myView = MyView()

这里你说MyObject 将实现RefresherDelegate 并创建简单的 MyView 实例(不会在 UI 上显示,只是简单的示例)

func assignDelegate() {
    myView.delegate = self
}

这是至关重要的部分 - 将委托分配给它的实现 - 在本例中为 MyObject

assignDelegate()之后,当你实际调用refreshUI()时,它会被MyObject调用。

【讨论】:

  • 谢谢你的解释,我真的看了这么多,看了视频,还是不太明白。我已经从DashboardVC 添加了连接侧边栏菜单的代码
  • 让我做对了 - 显示/隐藏可以正常工作,但更改主题不行?
  • 是的,没错。菜单工作得很好,如果用户更改主题,它不会相应地实现为DashboardVC。让我绊倒的是有 3 个UIViewControllers 参与其中。 ContainerVC 负责侧边栏菜单,SidebarMenuVC 负责更改主题,然后是第三个 - DashboardVC,其中主题没有被更改(除非您切换视图,但那是因为我调用 @ 987654341@ in viewWillAppear() 在同一个视图控制器中)
  • 好的,你仍然需要你在原始帖子中声明的委托 - 现在它只是 SideControl -> Dashboard 之间的连接问题。您可以使用与仪表板 VC 相同的方式:static weak var delegateReloadTheme: ReloadTheme? (即使这是不好的方式,但由于我对布局视图几乎一无所知,所以这会起作用)然后,你可以在通话时展示你可以在那里分配它。
  • @IBAction func sideMenuButtonPressed(_ sender: UIBarButtonItem) { ContainerVC. delegateReloadTheme = self Dashboard.delegateSideBar?.showMenu() }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-14
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
相关资源
最近更新 更多