Updating/Refreshing ContainerView 的内容
Updating/Refreshing the contents of a ContainerView
我目前有一个视图控制器,它有一个容器视图,其功能类似于 iOS 地图应用程序中的底部抽屉。扫描图像时,抽屉会在屏幕上显示动画(它开始在 (0,700) 处隐藏在屏幕外)并显示来自 Firebase 的信息。在这个容器中,我有另一个容器允许我进行 PageViewController 设置。此设置允许用户在两组不同的信息之间滑动(所有这些都需要从 Firebase 加载)。
I don't know how to reset the data within the second PageViewController so that whenever the drawer is dismissed through a button, the PageViewController system resets and I can use my function inside the secondPageViewController to reload the tableView it has inside.
TL;DR/更多信息
扫描图像是将信息加载到 ViewController 的过程。
我有一个独立的 VC (ViewController),里面有一个容器视图 (BottomDrawerViewController)。 BottomDrawerViewController 内部还有一个容器,它是一个包含 2 页的 PageViewController (Swipe1ViewController & Swipe2ViewController)
PageViewController 设置的第一页工作正常(很可能是因为该信息是使用 NSNotification 加载的)
我无法使用 NSNotification 以相同的方式发送和刷新此数据,因为这不是我 post 我的通知后出现的第一个视图控制器。
我无法在第二页中单独加载我的所有信息ViewController,因为我从我的原始 ViewController[=16= 获得了通往 Firebase 信息的途径]
问题:如何重置此数据和页面ViewController,以便每当用户关闭底部抽屉时,第二页上的信息能够在下一页刷新扫描并且 PageViewController 从第一页开始? 我想也许可以通过强制视图消失,以便在它出现在屏幕上时调用 ViewDidLoad 但我意识到这是不可能的。
我在图像和 JSON 表格中附上了所有视图控制器的一些重要代码和我的 Firebase 代码,以防万一。
ViewController: -- 这是获取要发送到容器的信息以及在主容器中设置动画的部分
ref.child("Directory").child(imageName).observeSingleEvent(of: .value, with: { (snapshot) in
print(snapshot)
let content = ImageInformation(snapshot: snapshot)
// TODO: Deliver Image Metadata here
let imageInfo = ["eventTitle": imageName, "source": content.Source, "date": content.Date] as [String : Any]
NotificationCenter.default.post(name: Notification.Name.drawerVC, object: nil, userInfo: imageInfo)
NotificationCenter.default.post(name: Notification.Name.newsVC, object: nil, userInfo: imageInfo)
})
UIView.animate(withDuration: 0.50) {
self.bottomDrawer.frame = CGRect(x: self.bottomPosition.x, y: self.bottomPosition.y, width: self.bottomDrawer.frame.size.width, height: self.bottomDrawer.frame.size.height)
}
BottomDrawerViewController: -- 这会收到来自 ViewController 的通知并更改抽屉标题。它还会在按下视图时将通知发送回 ViewController,以便可以将其关闭。
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(appeared), name: Notification.Name.drawerVC, object: nil)
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
view.addGestureRecognizer(tap)
}
@objc func appeared(_ notification: NSNotification) {
if let eventTitle = notification.userInfo?["eventTitle"] as? String {
self.eventTitleLabel.text = eventTitle
}
}
@objc func handleTap(_ sender: UITapGestureRecognizer) {
NotificationCenter.default.post(name: Notification.Name.mainVC, object: nil, userInfo: nil)
}
PageViewController: -- 这控制着我的 PageViewController 设置。由于一切都与我没有包括的正常设置相同。这一行允许我将变量从第一页发送到第二页。
var eventTitle: String = ""
Swipe1ViewController: -- 从 ViewController 接收通知并使用它来填充屏幕上的标签。它还将事件标题(数据库中的"Test Input")发送到页面ViewController以供Swipe2ViewController使用(未显示代码)
Swipe2ViewController:——截至目前,它从 PageViewController 获取 eventTitle 变量并使用它从 Firebase 获取数据,但是这多次不起作用,因为 viewDidLoad() 仅在向上滑动 BottomDrawerViewController 时运行一次。我也试过将 fetchHeadlines() 函数放在 viewDidAppear() 中,但如果用户关闭并扫描完全不同的图片,它就不会更新。
override func viewDidLoad() {
super.viewDidLoad()
self.newsTableView.delegate = self
self.newsTableView.dataSource = self
// fetchHeadlines()
}
override func viewDidAppear(_ animated: Bool) {
//
fetchHeadlines()
}
override func viewDidDisappear(_ animated: Bool) {
}
func fetchHeadlines() {
let pageVC = self.parent as! DrawerPageViewController
let eventTitle = pageVC.eventTitle
print("Title: " + eventTitle)
ref.child("Directory").child(eventTitle).child("News").observeSingleEvent(of: .value) { (newsSnapshot) in
for news in newsSnapshot.children.allObjects as! [DataSnapshot] {
print("Key: \(news.key)", "Value: \(news.value)")
//self.headlines.append(news)
DispatchQueue.global().async {
DispatchQueue.main.async {
// self.tableView.reloadData()
}
}
}
}
}
您不应该使用通知将数据从一个视图传播到另一个视图。如您所见,它工作得不是很好,容易出错,调试起来也很困难。相反,您应该接受父视图控制器和子视图控制器之间的关系。也就是说,ViewController应该将数据传递给BottomViewController,BottomViewController将数据传递给PageViewController,这是PageViewController的工作来设置子页面中的数据。这使您可以在将每个视图控制器放在屏幕上时将数据放在它所属的位置。
请注意,父视图控制器可以使用 childViewControllers
数组访问子视图。所以 ViewController 可以直接访问 BottomViewController 使用:
if let bottomViewController = childViewControllers.first as? BottomViewController {
// set up the bottomViewController here
}
我目前有一个视图控制器,它有一个容器视图,其功能类似于 iOS 地图应用程序中的底部抽屉。扫描图像时,抽屉会在屏幕上显示动画(它开始在 (0,700) 处隐藏在屏幕外)并显示来自 Firebase 的信息。在这个容器中,我有另一个容器允许我进行 PageViewController 设置。此设置允许用户在两组不同的信息之间滑动(所有这些都需要从 Firebase 加载)。
I don't know how to reset the data within the second PageViewController so that whenever the drawer is dismissed through a button, the PageViewController system resets and I can use my function inside the secondPageViewController to reload the tableView it has inside.
TL;DR/更多信息
扫描图像是将信息加载到 ViewController 的过程。
我有一个独立的 VC (ViewController),里面有一个容器视图 (BottomDrawerViewController)。 BottomDrawerViewController 内部还有一个容器,它是一个包含 2 页的 PageViewController (Swipe1ViewController & Swipe2ViewController)
PageViewController 设置的第一页工作正常(很可能是因为该信息是使用 NSNotification 加载的)
我无法使用 NSNotification 以相同的方式发送和刷新此数据,因为这不是我 post 我的通知后出现的第一个视图控制器。
我无法在第二页中单独加载我的所有信息ViewController,因为我从我的原始 ViewController[=16= 获得了通往 Firebase 信息的途径]
问题:如何重置此数据和页面ViewController,以便每当用户关闭底部抽屉时,第二页上的信息能够在下一页刷新扫描并且 PageViewController 从第一页开始? 我想也许可以通过强制视图消失,以便在它出现在屏幕上时调用 ViewDidLoad 但我意识到这是不可能的。
我在图像和 JSON 表格中附上了所有视图控制器的一些重要代码和我的 Firebase 代码,以防万一。
ViewController: -- 这是获取要发送到容器的信息以及在主容器中设置动画的部分
ref.child("Directory").child(imageName).observeSingleEvent(of: .value, with: { (snapshot) in
print(snapshot)
let content = ImageInformation(snapshot: snapshot)
// TODO: Deliver Image Metadata here
let imageInfo = ["eventTitle": imageName, "source": content.Source, "date": content.Date] as [String : Any]
NotificationCenter.default.post(name: Notification.Name.drawerVC, object: nil, userInfo: imageInfo)
NotificationCenter.default.post(name: Notification.Name.newsVC, object: nil, userInfo: imageInfo)
})
UIView.animate(withDuration: 0.50) {
self.bottomDrawer.frame = CGRect(x: self.bottomPosition.x, y: self.bottomPosition.y, width: self.bottomDrawer.frame.size.width, height: self.bottomDrawer.frame.size.height)
}
BottomDrawerViewController: -- 这会收到来自 ViewController 的通知并更改抽屉标题。它还会在按下视图时将通知发送回 ViewController,以便可以将其关闭。
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(appeared), name: Notification.Name.drawerVC, object: nil)
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
view.addGestureRecognizer(tap)
}
@objc func appeared(_ notification: NSNotification) {
if let eventTitle = notification.userInfo?["eventTitle"] as? String {
self.eventTitleLabel.text = eventTitle
}
}
@objc func handleTap(_ sender: UITapGestureRecognizer) {
NotificationCenter.default.post(name: Notification.Name.mainVC, object: nil, userInfo: nil)
}
PageViewController: -- 这控制着我的 PageViewController 设置。由于一切都与我没有包括的正常设置相同。这一行允许我将变量从第一页发送到第二页。
var eventTitle: String = ""
Swipe1ViewController: -- 从 ViewController 接收通知并使用它来填充屏幕上的标签。它还将事件标题(数据库中的"Test Input")发送到页面ViewController以供Swipe2ViewController使用(未显示代码)
Swipe2ViewController:——截至目前,它从 PageViewController 获取 eventTitle 变量并使用它从 Firebase 获取数据,但是这多次不起作用,因为 viewDidLoad() 仅在向上滑动 BottomDrawerViewController 时运行一次。我也试过将 fetchHeadlines() 函数放在 viewDidAppear() 中,但如果用户关闭并扫描完全不同的图片,它就不会更新。
override func viewDidLoad() {
super.viewDidLoad()
self.newsTableView.delegate = self
self.newsTableView.dataSource = self
// fetchHeadlines()
}
override func viewDidAppear(_ animated: Bool) {
//
fetchHeadlines()
}
override func viewDidDisappear(_ animated: Bool) {
}
func fetchHeadlines() {
let pageVC = self.parent as! DrawerPageViewController
let eventTitle = pageVC.eventTitle
print("Title: " + eventTitle)
ref.child("Directory").child(eventTitle).child("News").observeSingleEvent(of: .value) { (newsSnapshot) in
for news in newsSnapshot.children.allObjects as! [DataSnapshot] {
print("Key: \(news.key)", "Value: \(news.value)")
//self.headlines.append(news)
DispatchQueue.global().async {
DispatchQueue.main.async {
// self.tableView.reloadData()
}
}
}
}
}
您不应该使用通知将数据从一个视图传播到另一个视图。如您所见,它工作得不是很好,容易出错,调试起来也很困难。相反,您应该接受父视图控制器和子视图控制器之间的关系。也就是说,ViewController应该将数据传递给BottomViewController,BottomViewController将数据传递给PageViewController,这是PageViewController的工作来设置子页面中的数据。这使您可以在将每个视图控制器放在屏幕上时将数据放在它所属的位置。
请注意,父视图控制器可以使用 childViewControllers
数组访问子视图。所以 ViewController 可以直接访问 BottomViewController 使用:
if let bottomViewController = childViewControllers.first as? BottomViewController {
// set up the bottomViewController here
}