我将如何将类的每个实例设置为tabview的特定页面
我试图在应用程序视图中分配一个页面中的每个天气位置一个页面,但不确定如何实现这一目标。
我的位置视图中有一个CurrentPage变量,每次在屏幕上显示天气位置时应该添加1个,但是它只是在我拥有的整个foreach循环中添加一个,因此实际上并未将页码分配给天气视图。
我想知道是否有人知道如何在每个循环中迭代时将页码分配给每个位置。
我的位置视图如下所示。我尝试过的代码位于IF语句中的onAppear修饰符中的底部,但它不如上面说,我不确定这是否是执行此类操作的正确方法。任何帮助都很棒!
struct LocationView: View {
@ObservedObject var weatherVM: WeatherViewViewModel
@ObservedObject var multiLocationVM: MultiLocationViewModel
@State private var pageSelection = 1
@State var currentPage: Int = 0
var body: some View {
ZStack {
LinearGradient(colors: [Color("BackgroundColorSun"), Color("BackgroundColorSky")], startPoint: .topLeading, endPoint: UnitPoint(x: 0.5, y: 0.5)).ignoresSafeArea()
if multiLocationVM.weatherVM.count == 0 {
BlankLocationView(multiLocationVM: multiLocationVM)
} else {
TabView(selection: $pageSelection) {
ForEach(multiLocationVM.weatherVM, id: \.self.city) { location in
VStack(spacing: 0) {
VStack(spacing: -10) {
ZStack(alignment: .center) {
Text("\(location.getWeatherIconFor(icon: location.weatherIcon))")
//.innerShadow(Color(.red))
.font(.custom("SF Pro Text", size: 64))
.innerShadow()
//.foregroundColor(.gray)
.offset(x: -70, y: -35)
Text("\(location.getTempFor(temp: location.weather.current.temp))°")
.font(.system(size: 96, weight: .semibold, design: .rounded))
.tracking(-0.41)
.shadow(color: .black.opacity(0.25), radius: 4, x: 0, y: 4)
}
.offset(x: 15)
Text(location.conditions)
.font(.custom("SF Pro Display", size: 24))
}
.padding(EdgeInsets(top: -8, leading: 0, bottom: -8, trailing: 0))
VStack(spacing: -20) {
HourlyWeatherView(weatherVM: location)
DailyWeatherView(weatherVM: location)
}
Spacer()
}
.onAppear() {
if location.city != weatherVM.city {
weatherVM.city = location.city
currentPage += multiLocationVM.weatherVM.firstIndex(of: location)!
location.page = currentPage
print("current \(currentPage)")
print("Location \(location.page)")
} else {
return
}
}
.tag(currentPage)
}
}
.tabViewStyle(.page(indexDisplayMode: .automatic))
.indexViewStyle(.page(backgroundDisplayMode: .interactive))
}
}
.padding(.bottom, 70)
.ignoresSafeArea()
}
}
struct LocationView_Previews: PreviewProvider {
static var previews: some View {
LocationView(weatherVM: WeatherViewViewModel(city: "Phoenix"), multiLocationVM: MultiLocationViewModel())
}
}
I am trying to assign each weather location in my app a page in a tab view but am unsure on how to achieve this.
I have a currentPage variable in my location view which should add 1 every time a weather location is shown on screen but instead it just keeps adding one throughout the entire foreach loop I have, so a page number isn't actually assigned to a weather view.
I was wondering if anyone knew how I could assign a page number to each location when iterating through my for each loop.
My location view is shown below. The code I tried is at the bottom in the onAppear modifier in the if statement but it doesn't work like I said above and I am not sure if this is even the right approach for doing something like this. Any help would be great!
struct LocationView: View {
@ObservedObject var weatherVM: WeatherViewViewModel
@ObservedObject var multiLocationVM: MultiLocationViewModel
@State private var pageSelection = 1
@State var currentPage: Int = 0
var body: some View {
ZStack {
LinearGradient(colors: [Color("BackgroundColorSun"), Color("BackgroundColorSky")], startPoint: .topLeading, endPoint: UnitPoint(x: 0.5, y: 0.5)).ignoresSafeArea()
if multiLocationVM.weatherVM.count == 0 {
BlankLocationView(multiLocationVM: multiLocationVM)
} else {
TabView(selection: $pageSelection) {
ForEach(multiLocationVM.weatherVM, id: \.self.city) { location in
VStack(spacing: 0) {
VStack(spacing: -10) {
ZStack(alignment: .center) {
Text("\(location.getWeatherIconFor(icon: location.weatherIcon))")
//.innerShadow(Color(.red))
.font(.custom("SF Pro Text", size: 64))
.innerShadow()
//.foregroundColor(.gray)
.offset(x: -70, y: -35)
Text("\(location.getTempFor(temp: location.weather.current.temp))°")
.font(.system(size: 96, weight: .semibold, design: .rounded))
.tracking(-0.41)
.shadow(color: .black.opacity(0.25), radius: 4, x: 0, y: 4)
}
.offset(x: 15)
Text(location.conditions)
.font(.custom("SF Pro Display", size: 24))
}
.padding(EdgeInsets(top: -8, leading: 0, bottom: -8, trailing: 0))
VStack(spacing: -20) {
HourlyWeatherView(weatherVM: location)
DailyWeatherView(weatherVM: location)
}
Spacer()
}
.onAppear() {
if location.city != weatherVM.city {
weatherVM.city = location.city
currentPage += multiLocationVM.weatherVM.firstIndex(of: location)!
location.page = currentPage
print("current \(currentPage)")
print("Location \(location.page)")
} else {
return
}
}
.tag(currentPage)
}
}
.tabViewStyle(.page(indexDisplayMode: .automatic))
.indexViewStyle(.page(backgroundDisplayMode: .interactive))
}
}
.padding(.bottom, 70)
.ignoresSafeArea()
}
}
struct LocationView_Previews: PreviewProvider {
static var previews: some View {
LocationView(weatherVM: WeatherViewViewModel(city: "Phoenix"), multiLocationVM: MultiLocationViewModel())
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
恕我直言,您不需要CurrentPage Counter作为
tabview(selection:)
为您处理。选择,在您的情况下,pageSelection
将在用户刷新时进行更新,或者您可以通过编程方式设置它。您只需要提供拟合.tag
:IMHO you don't need the currentPage counter as
TabView(selection: )
is handling that for you. The selection, in your casepageSelection
will update when the user swipes, or you can set it programmatically. You just have to provide a fitting.tag
: