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

Calling function from child view controller not working

您好,我有一个带有 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(),但没有崩溃,但也没有更改标签。

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

您正在启动一个视图控制器,就像它是一个常规模型一样 class。这将启动视图控制器,但您不会实例化视图控制器以显示在故事板中。因此,您的视图生命周期未被使用,项目标签将不会启动,因此为零。

我假设容器视图是当前视图控制器的唯一子视图。如果这是 richt,您应该像这样在 viewDidLoad 中实例化 AddressViewController:

let addressViewController = self.childViewControllers.first as! AddressViewController

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

由于您需要隐藏您的容器视图,您可以创建一个到父级的出口 viewcontroller,当用户点击标记时,您取消隐藏容器并像这样调用 loadAddressView:

addressViewController.loadAddressView

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

亲切的问候, MacUserT