我正在构建一个在公共仓库here上托管的天气应用。
此问题最重要的文件是PageView和RepresentedPageViewController。
我创建了一个UIPageViewController
,可以通过UIViewControllerRepresentable
与SwiftUI进行交互。它允许用户在不同的城市中滑动并查看每个城市的天气数据,就像Apple的Weather应用程序一样。当我的页面视图控制器的makeUIViewController
方法被调用时,我设置了它的视图控制器(在这种情况下,首先有3个,每个代表一个城市):
pageViewController.setViewControllers([controllers[0]],
direction: .forward,
animated: false)
这很好用,我可以在不同页面之间导航(滑动)。
然后,在应用程序的搜索菜单中,用户可以点击他们想要获取天气的新城市。这会将新城市添加到应用程序的城市数据源中,页面视图控制器将其用于为每个城市创建页面。
由于保存城市的数据对象是有状态的,因此在设置该对象时(用户添加新城市时)将重新计算UI。这将触发页面视图控制器中的updateUIViewController
方法。在这种方法中,我重置了页面视图控制器的viewcontrollers(现在有4个,因为用户添加了一个新城市):
func updateUIViewController(_ uiViewController: UIPageViewController, context: UIViewControllerRepresentableContext<RepresentedPageViewController>) {
// Check that the view controllers of the page view controller need to be reset.
// This is true when a user has added a new city because we'll create a new
// view controller to be added to the page view controller. We perform this check because
// we don't want to reset the viewcontrollers in all cases where the updateUIViewController method is called.
if shouldResetControllers {
uiViewController.setViewControllers([controllers[0]],
direction: .forward,
animated: false)
shouldResetControllers = false
}
}
我的问题是,一旦完成此操作,用户将只能看到视图控制器的第一个城市。页面视图控制器仍在那儿,因为用户仍可以滑动,但是只有一个城市(第一个城市)。我已经为结果创建了一个屏幕记录,您可以查看here。
答案 0 :(得分:3)
认为问题仍然存在于协调员中:
当您在pageviewcontroller中更新控制器时,Coordinator的parent
属性保持不变(并且由于它是一个struct,因此他的所有属性)。因此,您只需在updateUIViewController
方法中添加以下代码行即可:
context.coordinator.parent = self
还请记住,pageViewController.setViewControllers
的动画将发生,因此您必须将animation设置为false或正确处理它。
还有许多其他方法可以解决此问题(我写了最直观的解决方案), 重要的是要知道错误的来源。
答案 1 :(得分:0)
似乎这是一个SwiftUI错误。我有一个类似的问题,UI更新将使用单个ViewController重新加载PageViewController。
在“ Updating an @Environment to pass data to PageViewController in SwiftUI results in loss of swiping between ViewControllers”中描述的向PageViewController添加ID似乎可行。