- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我很难理解为什么在 .onAppear
期间 @Published EnvironmentObject 变量发生更改时 PageViewController 无法按预期工作在其父 View 中。
如果我注释掉 .onAppear
DetailView
中的修饰符,然后一切正常 - 幻灯片按 PageViewController 的预期滑动。但是一旦该修饰符重新进入,页面就不会正确滑动。
由于状态变化,这与重新渲染有关,但我无法弄清楚。我知道updateUIViewController
在状态变化时被调用,这似乎改变了 viewControllers 的数组。
如果有人对如何解决这个问题有指导意见,我将非常感激听到它!
如果您正在运行以下代码,请确保更改您的 SceneDelegate:
let contentView = ContentView()
let contentView = ContentView().environmentObject(Global())
import SwiftUI
import Foundation
import UIKit
struct Item: Hashable {
var text: String
}
let testItems: [Item] = [
Item(text: "I am item 1"),
Item(text: "I am item 2"),
Item(text: "I am item 3")
]
final class Global : ObservableObject {
@Published var hideText: Bool = false
}
struct ContentView: View {
@EnvironmentObject var global: Global
var body: some View {
NavigationView {
VStack {
List(testItems, id: \.self) { item in
NavigationLink(destination: DetailView(item: item)) {
Text(item.text)
}
}
Text("I should vanish when detail view loads")
.opacity(self.global.hideText ? 0 : 1)
}
.navigationBarTitle("Test")
}
}
}
struct DetailView: View {
@EnvironmentObject var global: Global
var item: Item
var testViews: [Text] = [
Text("Slide 1").font(.title),
Text("Slide 2").font(.title),
Text("Slide 3").font(.title),
]
var body: some View {
// The .onAppear modifier breaks the PageViewController
// when it is commented out, the slides work as expected
PageView(testViews)
.onAppear {
self.global.hideText = true
}
}
}
struct PageView<Page: View>: View {
@State var currentPage = 0
var viewControllers: [UIHostingController<Page>]
init(_ views: [Page]) {
self.viewControllers = views.map{ UIHostingController(rootView: $0) }
}
var body: some View {
VStack(alignment: .center) {
PageViewController(
viewControllers: viewControllers,
currentPageIndex: $currentPage
)
}
}
}
struct PageViewController: UIViewControllerRepresentable {
var viewControllers: [UIViewController]
@Binding var currentPageIndex: Int
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIViewController(context: Context) -> UIPageViewController {
let pageViewController = UIPageViewController(
transitionStyle: .scroll,
navigationOrientation: .horizontal
)
pageViewController.view.backgroundColor = UIColor.clear
pageViewController.dataSource = context.coordinator
pageViewController.delegate = context.coordinator
return pageViewController
}
func updateUIViewController(_ pageViewController: UIPageViewController, context: Context) {
pageViewController.setViewControllers([viewControllers[currentPageIndex]], direction: .forward, animated: true)
}
class Coordinator: NSObject, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var parent: PageViewController
init(_ pageViewController: PageViewController) {
self.parent = pageViewController
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
// retrieves the index of the currently displayed view controller
guard let index = parent.viewControllers.firstIndex(of: viewController) else {
return nil
}
// shows the last view controller when the user swipes back from the first view controller
if index == 0 {
return parent.viewControllers.last
}
//show the view controller before the currently displayed view controller
return parent.viewControllers[index - 1]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
// retrieves the index of the currently displayed view controller
guard let index = parent.viewControllers.firstIndex(of: viewController) else {
print("View controller not found!!")
return nil
}
// shows the first view controller when the user swipes further from the last view controller
if index + 1 == parent.viewControllers.count {
return parent.viewControllers.first
}
// show the view controller after the currently displayed view controller
return parent.viewControllers[index + 1]
}
func pageViewController(_ pageViewController: UIPageViewController,
didFinishAnimating finished: Bool,
previousViewControllers: [UIViewController],
transitionCompleted completed: Bool
) {
if completed,
let visibleViewController = pageViewController.viewControllers?.first,
let index = parent.viewControllers.firstIndex(of: visibleViewController) {
parent.currentPageIndex = index
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(Global())
}
}
最佳答案
这建立在@Mac3n 的有用答案之上,他正确地指出,将 ViewControllers 传递给状态的 UIViewControllerRepresentable 部分可以解决问题。所缺少的只是如何通过 init
实际做到这一点。方法。
这是对 PageView
的完整更新
struct PageView<Page: View>: View {
@State var currentPage = 0
@State var viewControllers: [UIHostingController<Page>]
init(_ views: [Page]) {
_viewControllers = State(initialValue: views.map{ UIHostingController(rootView: $0) })
}
var body: some View {
VStack(alignment: .center) {
PageViewController(
viewControllers: viewControllers,
currentPageIndex: $currentPage
)
}
}
}
关于ios - 在 onAppear 中更改状态会破坏 PageViewController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60241723/
SO亲爱的 friend 们: 2014 年 3 月 18 日。我正在处理一种情况,在使用 ng-repeat 时,数组内的元素(我从 Json 字符串中获取)更改了原始顺序。 需要明确的是,数组中的
有很多问题询问如何在 JavaScript 单击处理程序中更改 div 的类,例如,此处:Change Div style onclick .我理解得很好(只需更改 .className),并且它有效
我从access导入了一个数据库到mysql,但其中一个表的列名“股数”带有空格,但我尝试更改、替换甚至删除列名,但失败了。任何人都可以帮助解决这一问题 String UpdateQuary = "U
我正在做一个随机的学校元素。 目前,我有一个包含两个 CSS 的页面。一种用于正常 View ,一种用于残障人士 View 。 此页面还包括两个按钮,它们将更改使用的样式表。 function c
我需要使用 javascript 更改 HTML 元素中的文本,但我不知道该怎么做。 ¿有什么帮助吗? 我把它定义成这样: Text I want to change. 我正在尝试这样做: docum
我在它自己的文件 nav_bar.shtml 中有一个主导航栏,每个其他页面都包含该导航栏。这个菜单栏是一个 jQuery 菜单栏(ApyCom 是销售这些导航栏的公司的名称)。导航栏上的元素如何确定
我正在摆弄我的代码,并开始想知道这个变化是否来自: if(array[index] == 0) 对此: if(!array[index] != 0) 可能会影响任何代码,或者它只是做同样的事情而我不需
我一直在想办法调整控制台窗口的大小。这是我正在使用的函数的代码: #include #include #define WIDTH 70 #define HEIGHT 35 HANDLE wHnd;
我有很多情况会导致相同的消息框警报。 有没有比做几个 if 语句更简单/更好的解决方案? PRODUCTS BOX1 BOX2 BOX3
我有一个包含这些元素的 XELEMENT B Bob Petier 19310227 1 我想像这样转换前缀。 B Bob Pet
我使用 MySQL 5.6 遇到了这种情况: 此查询有效并返回预期结果: select * from some_table where a = 'b' and metadata->>"$.countr
我想知道是否有人知道可以检测 R 中日期列格式的任何中断的包或函数,即检测日期向量格式更改的位置,例如: 11/2/90 12/2/90 . . . 15/Feb/1990 16/Feb/1990 .
我希望能够在小部件显示后更改 GtkButton 的标签 char *ButtonStance == "Connect"; GtkWidget *EntryButton = gtk_button_ne
我正在使用 Altera DE2 FPGA 开发板并尝试使用 SD 卡端口和音频线路输出。我正在使用 VHDL 和 C 进行编程,但由于缺乏经验/知识,我在 C 部分遇到了困难。 目前,我可以从 SD
注意到这个链接后: http://www.newscientist.com/blogs/nstv/2010/12/best-videos-of-2010-progress-bar-illusion.h
我想知道在某些情况下,即使剧本任务已成功执行并且 ok=2,ansible 也会显示“changed=0”。使用 Rest API 和 uri 模块时会发生这种情况。我试图找到解释但没有成功。谁能告诉
这个问题已经有答案了: 已关闭12 年前。 Possible Duplicate: add buttons to push notification alert 是否可以在远程通知显示的警报框中指定有
当您的 TabBarController 中有超过 5 个 View Controller 时,系统会自动为您设置一个“更多” View 。是否可以更改此 View 中导航栏的颜色以匹配我正在使用的颜
如何更改.AndroidStudioBeta文件夹的位置,默认情况下,该文件夹位于Windows中的\ .. \ User \ .AndroidStudioBeta,而不会破坏任何内容? /编辑: 找
我目前正在尝试将更具功能性的编程风格应用于涉及低级(基于 LWJGL)GUI 开发的项目。显然,在这种情况下,需要携带很多状态,这在当前版本中是可变的。我的目标是最终拥有一个完全不可变的状态,以避免状
我是一名优秀的程序员,十分优秀!