我一直在做一个应用程序。 我是一个初学者,所以请忽略任何错误。
问题是我有一个视图控制器,它有2个容器视图控制器,由一个分段控件控制。
在此处输入图像说明
他们三个都有各自的类:(比方说)
在main view controller中,我从firebase获取一些数据,我将这些数据存储在一个数组中,这个数组将被传递给第一个和第二个容器视图,这两个容器视图有它们的表视图,这些表视图将基于传递的数组加载数据。
现在,在数据返回MainViewController之前,第一个和第二个视图控制器已经传递了一个空数组,并且没有数据加载到它们的表视图中(显然是因为数组是空的)。
我希望容器视图控制器在收到数据并加载数组之后加载。 有什么需要帮忙的吗?谢谢
另外,我不执行任何segue,因为这些是容器视图,它们作为主视图容器加载自动加载。
编辑:使用原始代码更加精确和清晰:最初我有3个视图控制器
在主VC中,我使用了一个分段控件来查看屏幕上的容器VC,如下所示:
import UIKit
import Firebase
class SearchResultsScreenViewController: UIViewController
{
@IBOutlet weak var GuideListView: UIView!
@IBOutlet weak var ServicesListView: UIView!
var searchQueryKeyword: String?
var guidesDataArray = [GuideDM]()
override func viewDidLoad()
{
super.viewDidLoad()
ServicesListView.isHidden = true
populateGuidesList()
}
@IBAction func SegmentChanged(_ sender: UISegmentedControl)
{
switch sender.selectedSegmentIndex
{
case 0:
GuideListView.isHidden = false
ServicesListView.isHidden = true
break
case 1:
GuideListView.isHidden = true
ServicesListView.isHidden = false
break
default:
break
}
}
func populateGuidesList()
{
let dbRef = Firestore.firestore().collection("guide")
dbRef.getDocuments
{ (snapshot, error) in
if let err = error
{
print(err.localizedDescription)
print("Error: Unable to find guides list")
}
else
{
if let snap = snapshot
{
print("List is started now")
for doc in snap.documents
{
if doc.exists
{
let data = doc.data()
let city = data["city"] as? String ?? ""
let province = data["province"] as? String ?? ""
let country = data["country"] as? String ?? ""
if city.localizedCaseInsensitiveContains(self.searchQueryKeyword!) || province.localizedCaseInsensitiveContains(self.searchQueryKeyword!) || country.localizedCaseInsensitiveContains(self.searchQueryKeyword!)
{
let guideId = doc.documentID
let guideEmail = data["email"] as? String ?? ""
let name = data["name"] as? String ?? ""
let dob = data["dob"] as? String ?? ""
let feeCurrency = data["feeCurrency"] as? String ?? ""
let status = data["status"] as? String ?? ""
let totalReviews = data["totalReviews"] as? Int ?? 0
let rating = data["rating"] as? Int ?? 0
let baseFee = data["baseFee"] as? Int ?? 0
let isGuideFeatured = data["isGuideFeatured"] as? Bool ?? false
//make a model of guide and append in array
let guide = GuideDM(id: guideId, email: guideEmail, name: name, dob: dob, city: city, province: province, country: country, feeCurrency: feeCurrency, status: status, baseFee: baseFee, rating: rating, totalReviews: totalReviews, isGuideFeatured: isGuideFeatured)
self.guidesDataArray.append(guide)
}
}
}
print("list is finalized now")
}
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "searchScreentoGuideListSegment"
{
let guidesListContainerVC = segue.destination as! GuidesListSearchScreenViewController
guidesListContainerVC.guidesDataArray = self.guidesDataArray
}
}
}
在上面的类中,我的代码调用函数“populateGuidesList()”,该函数进行网络调用以获取数据,同时加载我的容器视图。 问题是,在网络调用返回数据之前,空数组会被传递给我的“GuidesListSearchScreenViewController”,即(第一个容器VC),它是一个表视图,并加载一个空表,因为数组尚未填充。
我的第一堂容器VC课:
import UIKit
import Firebase
class GuidesListSearchScreenViewController: UIViewController
{
@IBOutlet weak var guidesListTableView: UITableView!
var guidesDataArray = [GuideDM]()
override func viewDidLoad()
{
super.viewDidLoad()
guidesListTableView.delegate = self
guidesListTableView.dataSource = self
guidesListTableView.register(UINib(nibName: "GuidesListCellSearchScreenTableViewCell", bundle: nil), forCellReuseIdentifier: "guidesListCell")
}
}
extension GuidesListSearchScreenViewController: UITableViewDataSource, UITableViewDelegate
{
// below functions are to setup the table view
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return guidesDataArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = guidesListTableView.dequeueReusableCell(withIdentifier: "guidesListCell") as! GuidesListCellSearchScreenTableViewCell
//adding properties to cell and then returning cell
return cell
}
}
目标:要么在数组中接收到数据后加载容器视图,要么通过再次将数组传递给容器VC并重新加载表来刷新表。
其他解决方案:我曾尝试在第一个容器VC类中加载所有这些数组数据,然后从那里重新加载表视图数据,这工作得非常好,但对我来说这是一个非常低效的方法,因为我在两个容器视图中都需要这个数组,所以为每个容器VC进行网络调用似乎非常低效。 因此,我尝试一次获取数据,并传入两个容器视图。 如果你觉得我错了,请纠正我。
另外,我已经删除了其他功能并简化了代码。 我们将非常感谢您的帮助。
我只能在没有看到代码的情况下推测,所以这里什么都没有。。。 这是一个非常重要的问题
尝试在MainViewController的viewDidLoad()上执行以下操作:
>
使用与FirstViewController相关的属性(为了便于解释,我们假设它名为'first VC')。 您要做的是转到,firstvc.view.IsHidden=true
对SecondViewController执行相同操作。
为什么? 这样做将从MainViewController的视图中隐藏容器VC的(ViewController)。
这将使它返回查看,您获取的数据已经填充了它。
希望这能帮到你。
容器视图控制器将在主视图控制器加载时加载。 因此,当主视图控制器接收到数据时,您必须更新容器视图控制器。
一种简单的方法是更新容器视图控制器中的数组,并在数组上使用didset
强制容器视图控制器重新加载自己。
例如,如果FirstViewController在表视图中显示数组数据,则可以执行以下操作:
var array: [ArrayItem] {
didSet {
tableView.reloadData()
}
}
然后在主视图控制器中,当接收到数据时,设置此属性:
getData() { resultArray in
firstViewController.array = resultArray
}
请注意,由于您没有提供任何代码,这些只是示例,您将不得不调整它们以适合您的具体情况。
编辑:根据下面的注释,您应该注意不要在FirstViewController的视图加载之前设置该数组,否则对TableView.ReloadData()
的调用将导致应用程序崩溃。