iOS SwiftUI 框架集成 1.1
第三节 在SwiftUI
视图的状态下跟踪页面
如果要添加一个自定义的UIPageControl
控件,就需要一种方式能够在PageView
中跟踪当前展示的页面。这就需要在PageView
中声明一个@State
属性,并传递一个针对该属性的绑定关系给PageViewController
视图,在PageViewController
中通过绑定关系更新状态属性,来反映当前展示的页面。
步骤1 在PageViewController
中添加一个绑定属性currentPage
。除了使用关键字@Binding
声明属性为绑定属性外,还需要更新一下函数setViewControllers(_:direction:animated:)
,给它传入currentPage
绑定属性
做到这一步还不能正常运行,继续进行下一步。
步骤2 在PageView
中声明@State
变量,并在创建PageViewController
时把绑定属性传入。注意使用$
语法创建一个针对状态变量的绑定关系。
步骤3 通过改变PageView
视图中的currentPage
初始值来测试绑定关系是否正常生效。也可以做一个测试按钮,点击按钮时让第二个页面展示出来
步骤4 添加一个TextView
控件来展示状态变量currentPage
的值,拖动页面切换时观察TextView
上的值,目前不会发生变化。因为PageViewController
内部没有在切换页面的过程中更新currentPage
的值。
步骤5 在PageViewController.swift
中让coordinator
作为UIPageViewController
的代理,并添加pageViewController(_:didFinishAnimating:previousViewControllers:transitionCompleted completed: Bool)
方法。因为SwiftUI
在页面切换动画完成时会调用这个方法,这样就可以这个方法内部获取当前正在展示的页面的下标,并同时更新绑定属性currentPage
的值。
步骤6 coordinator
除了是UIPageViewController
数据源外,再把它赋值为UIPageViewController
的代理。由于绑定关系是双向的,所以当页面切换时,PageView
视图上的Text
就会实时展示当前的页码。
第四节 添加一个自定义PageControl
我们已经为包裹在UIViewRepresentable
视图中的子视图上添加了一个自定义UIPageControl
步骤1 创建一个新的SwiftUI
视图,命名为PageControl.swift
,并使用PageControl
类型遵循UIViewRepresentable
协议。UIViewRepresentable
和UIViewControllerRepresentable
类型有相同的生命周期,在UIKit类型中都有对应的生命周期方法。
步骤2 在PageView
中用PageControl
替换Text
,并把VStack
换成ZStack
。因为总页数和当前页面都已经传入PageControl
,所以PageControl
已经可以正确的显示。
下一步要处理PageControl
与用户的交互,让它可以被用户点击任意一边进行页面间的切换。
步骤3 在PageControl
中创建一个嵌套类型Coordiantor
,添加一个makeCoordinator()
方法创建并返回一个coordinator
实例。因为UIControl
子类(包括UIPageControl
)使用Target-Action
模式,Coordinator
实现一个@objc
方法来更新currentPage
绑定属性的值。
步骤4 把coordinator
作为PageControl
值改变事件的目标处理器,并指定updateCurrentPage(sender:)
方法为处理函数
步骤5 现在就可以尝试PageControl
的各种交互来切换页面,PageView
展示了SwiftUI
和UIKit
视图如何混合使用。
检查是否理解
问题1 下面哪个协议可以用来把UIKit
中的视图控件器桥接进SwiftUI
?
- UIViewRepresentable
- UIHostingController
- UIViewControllerRepresentable
问题2 对于UIViewControllerRepresentable
类型,下面哪个方法可以为它创建一个代理或数据源?
- 在
makeUIViewController(context:)
方法中创建UIViewController
实例的地方 - 在
UIViewControllerRepresentable
类型的初始化器中 - 在
makeCoordinator()
方法中