从子视图控制器调用函数不起作用

Posted

技术标签:

【中文标题】从子视图控制器调用函数不起作用【英文标题】:Calling function from child view controller not working 【发布时间】:2021-01-28 14:03:37 【问题描述】:

您好,我有一个带有mapView 的父视图控制器和一个子视图控制器,作为底部的一个小容器视图,并且该容器视图通常是隐藏的。当我从父视图控制器点击mapView 上的标记时,我想显示该容器视图并将子视图控制器上的标签更改为我从数据库中获取的值。

现在,我在这里调用父视图控制器的函数(当点击标记时)以更改子视图控制器上的标签。

在我的父视图控制器中:

 func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool 
        
        
        
        AddressViewController.ID.selectedID = marker.snippet ?? ""
        
        
        UIView.transition(with: AddressView, duration: 1, options: .transitionFlipFromBottom, animations: self.AddressView.isHidden = false, completion: nil)
    
        let AddressViewController = AddressViewController()
        AddressViewController.loadAddressView()
        
        
        let camera = GMSCameraPosition.camera(withTarget: marker.position, zoom: 16)
        mapView.animate(to: camera)

        return true
    

在 AddressViewController(子视图控制器)中

func loadAddressView() 
        
        if ID.selectedID == "" 
            print("ID did not pass")
            return
        
        else 
            print("function worked")
            
            ref = Database.database().reference().child("Items").child(ID.selectedID)
            ref?.observeSingleEvent(of: .value, with: (snapshot) in
                
                let value = snapshot.value as? NSDictionary  
            
                self.ItemNameLabel.text = value?["ItemName"] as? String ?? ""
                self.addressLabel.text = value?["AddressDisplay"] as? String ?? ""

            )
            
        
    

发生的情况是,当我运行它并按下标记时,它崩溃了,它告诉我 ItemNameLabel 是“在展开可选值时意外发现 nil”。但是,我可以告诉该函数仍然被调用,因为“函数有效”(上图)仍然被打印,只有标签被发现为零。所以我尝试了诸如使用委托和协议来调用函数之类的方法,虽然它没有崩溃,但由于某种原因从未调用过委托(我可能做错了——如果这是解决问题的方法,如果有人请解释一下我的情况,我会很高兴的)。我还尝试将我的标签设置为子视图控制器的 viewDidLoad 中的数据库数据,并从父视图控制器调用子视图控制器的 loadView() ,这没有崩溃,但也没有更改标签。

有人知道如何解决这个问题吗?提前致谢。

【问题讨论】:

AddressViewController() 不是故事板中的实例。您需要通过 segue 或实例化的 真实 引用。 @vadian 我确实尝试过实例化,但我的标签出现了同样的错误。 在实例化之后标签尚未连接。您必须使用临时变量并在viewDidLoad中设置标签 @vadian 你能举个例子吗? 请看***.com/questions/44445895/… 【参考方案1】:

您正在启动一个视图控制器,就像它是一个常规模型类一样。这将启动视图控制器,但您不会实例化视图控制器以显示在情节提要中。由于这个原因,您的视图生命周期没有被使用,并且项目标签不会被启动,因此是 nil。

我将假设容器视图是您的 prent 视图控制器的唯一子级。如果这很丰富,您应该像这样在 viewDidLoad 中实例化您的 AddressViewController:

let addressViewController = self.childViewControllers.first as! AddressViewController

我假设子视图控制器在那里并且可以进行显式解包。

由于您需要隐藏容器视图,您可以创建一个到父视图控制器的插座,当用户单击标记时,您取消隐藏容器并调用 loadAddressView,如下所示:

addressViewController.loadAddressView

由于您的 AddressViewController 已正确启动,所有标签都已初始化并且可以正常工作。

亲切的问候, Mac用户T

【讨论】:

这可行,但它将我的容器视图显示为整个屏幕,我只想将我的容器视图显示为子视图控制器,或者换句话说,就像中间的一个小框我的屏幕。有什么办法可以做到吗?我现在在我的父视图控制器上将它设置为容器视图。 对不起,你是对的。稍等,将更新答案。 非常感谢!有效!唯一的小问题是 childViewControllers 已被弃用并更改为 children

以上是关于从子视图控制器调用函数不起作用的主要内容,如果未能解决你的问题,请参考以下文章

回调闭包函数在单元格中不起作用

如果从另一个类调用 removeFromSuperview 将不起作用

导航推送视图控制器不起作用

UIButton 子类@IBAction 不起作用

当前路径具有子目录或 url 参数时,使用 AJAX 调用视图函数不起作用(Django)

在控制器内部调用函数时,codeigniter 404 函数不起作用