SwiftUI:强制更新

时间:2019-06-12 11:53:05

标签: swift swiftui

通常,我们不能讨论Apple发行前的内容,但是我已经看过许多SwiftUI的讨论,因此我怀疑这是可以的。就这样一次。

我正在研究其中一个教程中的杂草(我这样做)。

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

这些是“下一步”和“上一步”按钮。在一端或另一端时,相应的按钮将隐藏。我的工作很好。

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

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

我知道我可以通过重画PageView主体以反映新的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或主体。

3 个答案:

答案 0 :(得分:7)

2020 SWIFT 1和2:

方法1:在视图内部声明:

@State updater: Bool

您需要更新的全部是toogle()它:updater.toogle()


方法2:从ViewModel刷新

在SwiftUI 2上工作

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

方法3:从ViewModel刷新:

在SwiftUI 1上运行

import Combine
import SwiftUI

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

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

答案 1 :(得分:2)

currentPage设置为@State,将重新加载整个正文。

答案 2 :(得分:1)

这是另一种使用id()标识符对我有用的解决方案。基本上,我们并没有真正令人耳目一新的观点。我们正在用新视图替换视图。

import SwiftUI

struct ManualUpdatedTextField: View {
    @State var name: String
    
    var body: some View {
        VStack {
            TextField("", text: $name)
            Text("Hello, \(name)!")
        }
    }
}

struct MainView: View {
    
    @State private var name: String = "Tim"
    @State private var theId = 0

    var body: some View {
        
        VStack {
            Button {
                name += " Cook"
                theId += 1
            } label: {
                Text("update Text")
                    .padding()
                    .background(Color.blue)
            }
            
            ManualUpdatedTextField(name: name)
                .id(theId)
        }
    }
}