【问题标题】:How to make a Dynamic PageViewController in SwiftUI?如何在 SwiftUI 中制作动态 PageViewController?
【发布时间】:2020-09-23 17:10:56
【问题描述】:

有人知道如何在 SwiftUI、iOS 14 中制作动态 pageView 控制器吗?显示与日期相关的页面的东西,以便人们可以向左或向右滚动以查看过去、现在和未来的数据。

struct DatePg: View
{
    let date: Date
    
    var body: some View {
        Text(date.description)
    }
}

有一个新的 API 允许使用 TabView 和 viewModifier 创建一个 PageViewController。但我见过的唯一例子是静态的。这是一个静态 PageView 的示例。

import SwiftUI

struct SwiftUIPageView: View
{
    @State private var selection = 0
    
    var body: some View {
        TabView(selection: $selection) {
            Text("Hello")
                .frame(maxWidth: .infinity, maxHeight: .infinity)
                .background(Color.blue)
                .tag(0)
            Text("World")
                .frame(maxWidth: .infinity, maxHeight: .infinity)
                .background(Color.red)
                .tag(1)
        }.tabViewStyle(PageTabViewStyle())
        .indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
    }
}

已经有一些使用 UIHostingController 工作的东西,但是通过 UIKit 对象传递 NSManageObjectContext 正在引起问题。

这是我目前所处的位置。还是不行。

import SwiftUI

@main struct PagerApp: App
{
    var body: some Scene {
        WindowGroup { DatePageView() }
    }
}

struct DatePageView: View
{
    @StateObject var dateData = DateData(present: Date())
    @State var index: Int = 1

    var body: some View {
        TabView(selection: $index) {
            ForEach(dateData.dates, id: \.self) { date in
                Text(date.description)
                    .onAppear { dateData.current(date: date) }
                    .tag(dateData.tag(date: date))
            }
        }
        .tabViewStyle(PageTabViewStyle())
        .indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
    }
}

class DateData: ObservableObject
{
    @Published var dates: [Date]
    
    init(present: Date) {
        let past = present.previousDay()
        let future = present.nextDay()
        self.dates = [past, present, future]
    }
    
    func current(date: Date) {
        //center around
        guard let i = dates.firstIndex(of: date) else { fatalError() }
        self.dates = [ dates[i].previousDay(), dates[i], dates[i].nextDay() ]
        print("make item at \(i) present")
    }
    
    func tag(date: Date) -> Int {
        guard let i = dates.firstIndex(of: date) else { fatalError() }
        return i
    }
}

【问题讨论】:

  • 您找到解决方案了吗?我试图实现相同的功能

标签: swiftui


【解决方案1】:

您可以使用数组和ForEach 动态创建视图。

这是一个使用字符串数组的示例:

// See edited section

您可以在视图初始化程序中传递您想要的项目

编辑:
这是每次到达最后一个页面时添加新页面的示例:

struct SwiftUIPageView: View
{
    @State private var selection = "0"
    
    @State var items: [String] = ["0", "1", "2", "3"]
    
    var body: some View {
        TabView(selection: $selection) {
            ForEach(items, id: \.self) { item in
                Text(item)
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .background(Color.red)
                    .tag(item)
            }
        }.tabViewStyle(PageTabViewStyle())
        .indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
        .onChange(of: selection, perform: { value in
            if Int(value) == (self.items.count - 1) {
                self.items.append("\(self.items.count)")
            }
        })
        .id(items)
    }
}

最后一个id(items) 很重要,因为它会在数组更改时强制视图重新加载。

【讨论】:

  • 这很酷,但这仍然是静态的。有没有办法使数据源动态化并使用 ForEach?这个想法是你向左滑动,过去一天,向右滑动,未来一天。
  • 我设法在每次到达最后一个时动态添加一个View,但是当它添加时,由于渲染了整个View,所以没有动画,请检查编辑
猜你喜欢
  • 1970-01-01
  • 2021-09-25
  • 1970-01-01
  • 2020-09-12
  • 1970-01-01
  • 2017-08-29
  • 1970-01-01
  • 2021-10-27
  • 1970-01-01
相关资源
最近更新 更多