gpt4 book ai didi

SwiftUI:强制更新

转载 作者:可可西里 更新时间:2023-11-01 00:54:05 26 4
gpt4 key购买 nike

通常情况下,我们不能讨论 Apple 预发布的东西,但我已经看到很多关于 SwiftUI 的讨论,所以我怀疑这没问题;就这一次。

我正在学习其中一个教程(我这样做)。

我在“与 UIKit 交互”教程中的可滑动屏幕下方添加了一对按钮:https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit

这些是“下一个”和“上一个”按钮。在一端或另一端时,相应的按钮会隐藏。我有那个工作正常。

我遇到的问题是访问由 PageViewController 表示的 UIPageViewController 实例。

我更改了 currentPage 属性(通过使 PageViewController 成为 UIPageViewController 的委托(delegate)),但我需要强制 UIPageViewController 以编程方式更改。

我知道我可以通过重绘 PageView 主体来“强制”显示,反射(reflect)一个新的 currentPage,但我不确定该怎么做。

struct PageView<Page: View>: View {
var viewControllers: [UIHostingController<Page>]
@State var currentPage = 0

init(_ views: [Page]) {
self.viewControllers = views.map { UIHostingController(rootView: $0) }
}

var body: some View {
VStack {
PageViewController(controllers: viewControllers, currentPage: $currentPage)

HStack(alignment: .center) {
Spacer()

if 0 < currentPage {
Button(action: {
self.prevPage()
}) {
Text("Prev")
}

Spacer()
}

Text(verbatim: "Page \(currentPage)")

if currentPage < viewControllers.count - 1 {
Spacer()

Button(action: {
self.nextPage()
}) {
Text("Next")
}
}

Spacer()
}
}
}

func nextPage() {
if currentPage < viewControllers.count - 1 {
currentPage += 1
}
}

func prevPage() {
if 0 < currentPage {
currentPage -= 1
}
}
}

我知道答案应该很明显,但我很难弄清楚如何以编程方式刷新 VStack 或主体。

最佳答案

2021 SWIFT 1 和 2:

重要的事情!如果你搜索这个 hack,可能你做错了什么!请在阅读 hack 解决方案之前阅读此 block !!!!!!!!!!!!

Your UI wasn't updated automatically because of you miss somethingimportant.

  • Your ViewModel must be a class wrapped into ObservableObject/ObservedObject
  • Any field in ViewModel must be a STRUCT. NOT A CLASS!!!! Swift UI does not work with classes!
  • Must be used modifiers correctly (state, observable/observedObject, published, binding, etc)
  • If you need a class property in your View Model (for some reason) - you need to mark it as ObservableObject/Observed object and assign them into View's object !!!!!!!! inside init() of View. !!!!!!!
  • Sometimes is needed to use hacks. But this is really-really-really exclusive situation! In most cases this wrong way! One more time: Please, use structs instead of classes!

Your UI will be refreshed automatically if all of written above was used correctly.

正确用法示例:

struct SomeView : View {
@ObservedObject var model : SomeViewModel
@ObservedObject var someClassValue: MyClass

init(model: SomeViewModel) {
self.model = model

//as this is class we must do it observable and assign into view manually
self.someClassValue = model.someClassValue
}

var body: some View {
//here we can use model.someStructValue directly

// or we can use local someClassValue taken from VIEW, BUT NOT value from model

}

}

class SomeViewModel : ObservableObject {
@Published var someStructValue: Bool = false
var someClassValue: MyClass = MyClass() //myClass : ObservableObject

}

以及主题问题的答案。

(黑客解决方案 - 最好不要使用它)

方式一:在 View 内部声明:

@State var updater: Bool = false

所有你需要更新的是 toogle() 它:updater.toogle()


方式二:从ViewModel刷新

Works on SwiftUI 2

public class ViewModelSample : ObservableObject
func updateView(){
self.objectWillChange.send()
}
}

方式三:从ViewModel刷新:

works on SwiftUI 1

import Combine
import SwiftUI

class ViewModelSample: ObservableObject {
private let objectWillChange = ObservableObjectPublisher()

func updateView(){
objectWillChange.send()
}
}

关于SwiftUI:强制更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56561630/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com