Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swiftui 根据@State变量的值更改重新加载视图_Swiftui - Fatal编程技术网

Swiftui 根据@State变量的值更改重新加载视图

Swiftui 根据@State变量的值更改重新加载视图,swiftui,Swiftui,我的视图顶部有一个选项卡。选项卡是动态的,下面显示的ListView()取决于选项卡索引。对于选项卡0索引,ListView()是固定的,但从索引1开始,ListView()将根据所选选项卡索引重新加载。因此,我当前选择的选项卡如下所示: @State private var selectedTabIndex = 0 我现在静态地重新加载视图,如下所示: if self.selectedTabIndex == 0 { ListView(id: selectedTabIndex) }

我的视图顶部有一个选项卡。选项卡是动态的,下面显示的ListView()取决于选项卡索引。对于选项卡0索引,ListView()是固定的,但从索引1开始,ListView()将根据所选选项卡索引重新加载。因此,我当前选择的选项卡如下所示:

@State private var selectedTabIndex = 0
我现在静态地重新加载视图,如下所示:

if self.selectedTabIndex == 0 {
     ListView(id: selectedTabIndex)
} else if self.selectedTabIndex == 1 {
     ListView(id: selectedTabIndex)          
} else if self.selectedTabIndex == 2 {
     ListView(id: selectedTabIndex)       
} else if self.selectedTabIndex == 3 {
     ListView(id: selectedTabIndex)
} else if self.selectedTabIndex == 4 {
     ListView(id: selectedTabIndex)
} else if self.selectedTabIndex == 5 {
     ListView(id: selectedTabIndex)
}
这很好,也可以重新加载ListView(),但这不是正确的方法,因为选项卡索引或多或少会动态变化。因此,当我单击选项卡时,我的selectedTabIndex值正在更改,我尝试了类似的方法:

if self.selectedTabIndex == 0 {
     ListView(id: selectedTabIndex)
} else {
     ListView(id: selectedTabIndex)
}
但它只会重新加载第一次单击的选项卡,而不会加载其他选项卡。请问我该怎么修?因为我对SwiftUI还不熟悉,所以有时会觉得很难。请帮忙

更多详情:

import SwiftUI

struct WorkView: View {
@EnvironmentObject var navBarPreference: NavBarPreferences

@State private var selectedTabIndex = 0
@State private var isEmpty: Bool = true //
@State private var showWorkDetailView:Bool = false
@State var isCategoryAvailable:Bool = false

@ObservedObject var WorkVM = WorkViewModel() //
@State var workCategoryName: [String] = [" "]
@State var workCategoryID: [Int] = [0]
@State var selectedID: Int = 0
@State var workContentModel = [WorkContentModel]() //

var body: some View {
    VStack(spacing: 0) {
        HeaderView(title: "ワーク")
        VStack {
            
            if self.workCategoryName.isEmpty == false {
                SlidingTab(selection: $selectedTabIndex, tabs: self.workCategoryName).padding(.top, 10)
            }
            
        }
        
        Spacer().frame(maxHeight: 24)
        
        //(selectedTabIndex == 0 ? SelectedFirstTab() : Text("Second View")).padding()
        
        if self.selectedTabIndex == 0 {
            SelectedFirstTab(selectedTabIndex: self.selectedTabIndex, isCategoryAvailable: self.$isCategoryAvailable, workCategoryName: self.$workCategoryName, workCategoryID: self.$workCategoryID, selectedID: self.$selectedID)
        } else if self.selectedTabIndex == 1 {
            SelectedFirstTab(selectedTabIndex: self.selectedTabIndex, isCategoryAvailable: self.$isCategoryAvailable, workCategoryName: self.$workCategoryName, workCategoryID: self.$workCategoryID, selectedID: self.$workCategoryID[self.selectedTabIndex])

        } else if self.selectedTabIndex == 2 {
            SelectedFirstTab(selectedTabIndex: self.selectedTabIndex, isCategoryAvailable: self.$isCategoryAvailable, workCategoryName: self.$workCategoryName, workCategoryID: self.$workCategoryID, selectedID: self.$workCategoryID[self.selectedTabIndex])

        } else if self.selectedTabIndex == 3 {
            SelectedFirstTab(selectedTabIndex: self.selectedTabIndex, isCategoryAvailable: self.$isCategoryAvailable, workCategoryName: self.$workCategoryName, workCategoryID: self.$workCategoryID, selectedID: self.$workCategoryID[self.selectedTabIndex])

        } else if self.selectedTabIndex == 4 {
            SelectedFirstTab(selectedTabIndex: self.selectedTabIndex, isCategoryAvailable: self.$isCategoryAvailable, workCategoryName: self.$workCategoryName, workCategoryID: self.$workCategoryID, selectedID: self.$workCategoryID[self.selectedTabIndex])

        } else if self.selectedTabIndex == 5 {
            SelectedFirstTab(selectedTabIndex: self.selectedTabIndex, isCategoryAvailable: self.$isCategoryAvailable, workCategoryName: self.$workCategoryName, workCategoryID: self.$workCategoryID, selectedID: self.$workCategoryID[self.selectedTabIndex])
        }
        
        //Spacer()
    }.frame(minWidth: SCREEN_WIDTH)
        
        //.position(x: SCREEN_WIDTH/2, y: SCREEN_HEIGHT/2)
        //            .background(
        //                Image("PPImage")
        //                    .resizable()
        //                    .frame(minWidth: 375, minHeight: 945)
        //                //.aspectRatio(contentMode: .fit)
        //        )
        .edgesIgnoringSafeArea(.top)
        .navigationBarTitle("", displayMode: .inline)
        .navigationBarHidden(self.navBarPreference.navBarIsHidden)
        .navigationBarBackButtonHidden(self.navBarPreference.navigationBarBackButtonHidden)
        .onAppear{ self.navBarPreference.navBarIsHidden = true
            self.navBarPreference.navigationBarBackButtonHidden = true }
}

}

struct SelectedFirstTab: View {
@State private var isEmpty: Bool = true
@ObservedObject var WorkVM = WorkViewModel()
@State var workContentModel = [WorkContentModel]()

var selectedTabIndex: Int = 0
@Binding var isCategoryAvailable:Bool
@Binding var workCategoryName: [String]
@Binding var workCategoryID: [Int]
@Binding var selectedID: Int


var body: some View {
    VStack {
        if self.workContentModel.isEmpty {
            EmptyContent()
        } else {
            ScrollView(showsIndicators: false) {
                ForEach(self.workContentModel) { content in
                    NavigationLink(destination: WorkDetailView(data: content)) {
                        WorkViewRow(data: content)
                    }.frame(minWidth: SCREEN_WIDTH, minHeight: 118)
                        .padding(.top, 5)
                        .padding(.bottom, 5)
                }
            }.frame(maxHeight: 600)
        }
    }
    .onAppear {
        
        if self.isCategoryAvailable == false {
            self.WorkVM.getWorkList() { workCategory, content in
                for i in 0..<workCategory.count {
                    self.workCategoryName.append(workCategory[i].name ?? " ")
                    self.workCategoryID.append(workCategory[i].id ?? 0)
                }
                self.workCategoryName.removeFirst()
                
                self.workContentModel = content
                self.isCategoryAvailable = true
                self.isEmpty = false
                
                // print("myContent:\(content)")
                // print("workCategoryID:\(self.workCategoryID)")
                
                self.selectedID = self.workCategoryID[self.selectedTabIndex]
                print("selectedID:\(self.selectedID)")
                
            }
            
        } else if self.isCategoryAvailable == true {
            self.WorkVM.getCategory(id: self.selectedID) { content in
                self.workContentModel = content
                self.isEmpty = false
                self.selectedID = self.workCategoryID[self.selectedTabIndex]
                print("selectedID:\(self.selectedID)")
            }
        }
        
    }
}
}

struct EmptyContent: View {
var body: some View {
    ZStack {
        Rectangle()
            .foregroundColor(.clear)
            .frame(maxHeight: 600)
        
        VStack {
            Image("EmptyBackgroundImage")
                .resizable()
                .frame(maxWidth: 150, maxHeight: 146)
            CustomizedText(text: "表示されるワークは \n ありません", tracking: 2.2, frameHeight: 72, fontFamily: "HiraginoSans-W6", fontFamilySize: 22, lineLimit: 2)
                .frame(maxWidth: 218, maxHeight: 72)
            CustomizedText(text: "ここではワーク情報をお届けします。\n 最新のワークを探していますのでお待ちください。", tracking: 1.2, frameHeight: 42, fontFamily: "HiraginoSans-W3", fontFamilySize: 12, lineLimit: 2).frame(maxWidth: 333, maxHeight: 42)
            Spacer().frame(maxHeight: 210)
            
        }
    }
}
}
导入快捷界面
结构工作视图:视图{
@EnvironmentObject变量navBarPreference:NavBarPreferences
@状态私有变量selectedTabIndex=0
@State-private变量为空:Bool=true//
@状态私有变量showWorkDetailView:Bool=false
@状态变量isCategoryAvailable:Bool=false
@ObservedObject var WorkVM=WorkViewModel()//
@状态变量workCategoryName:[字符串]=[“”]
@状态变量workCategoryID:[Int]=[0]
@状态变量selectedID:Int=0
@状态变量workContentModel=[workContentModel]()//
var body:一些观点{
VStack(间距:0){
HeaderView(标题:ワーク")
VStack{
如果self.workCategoryName.isEmpty==false{
滑动选项卡(选择:$selectedTabIndex,选项卡:self.workCategoryName)。填充(.top,10)
}
}
框架垫片()(最大高度:24)
//(selectedTabIndex==0?SelectedFirstTab():文本(“第二个视图”)。填充()
如果self.selectedTabIndex==0{
SelectedFirstTab(selectedTabIndex:self.selectedTabIndex,isCategoryAvailable:self.$isCategoryAvailable,workCategoryName:self.$workCategoryName,workCategoryID:self.$workCategoryID,selectedID:self.$selectedID)
}如果self.SelectedTabinex==1,则为else{
SelectedFirstTab(selectedTabIndex:self.selectedTabIndex,isCategoryAvailable:self.$isCategoryAvailable,workCategoryName:self.$workCategoryName,workCategoryID:self.$workCategoryID,selectedID:self.$workCategoryID[self.selectedTabIndex])
}如果self.SelectedTabinex==2,则为else{
SelectedFirstTab(selectedTabIndex:self.selectedTabIndex,isCategoryAvailable:self.$isCategoryAvailable,workCategoryName:self.$workCategoryName,workCategoryID:self.$workCategoryID,selectedID:self.$workCategoryID[self.selectedTabIndex])
}否则,如果self.selectedTabIndex==3{
SelectedFirstTab(selectedTabIndex:self.selectedTabIndex,isCategoryAvailable:self.$isCategoryAvailable,workCategoryName:self.$workCategoryName,workCategoryID:self.$workCategoryID,selectedID:self.$workCategoryID[self.selectedTabIndex])
}否则,如果self.selectedTabIndex==4{
SelectedFirstTab(selectedTabIndex:self.selectedTabIndex,isCategoryAvailable:self.$isCategoryAvailable,workCategoryName:self.$workCategoryName,workCategoryID:self.$workCategoryID,selectedID:self.$workCategoryID[self.selectedTabIndex])
}否则,如果self.selectedTabIndex==5{
SelectedFirstTab(selectedTabIndex:self.selectedTabIndex,isCategoryAvailable:self.$isCategoryAvailable,workCategoryName:self.$workCategoryName,workCategoryID:self.$workCategoryID,selectedID:self.$workCategoryID[self.selectedTabIndex])
}
//垫片()
}.帧(最小宽度:屏幕宽度)
//.位置(x:屏幕宽度/2,y:屏幕高度/2)
//.背景(
//图像(“PPImage”)
//.可调整大小()
//.框架(最小宽度:375,最小高度:945)
////.aspectRatio(contentMode:.fit)
//        )
.edgesIgnoringSafeArea(.top)
.navigationBarTitle(“,显示模式:。内联)
.navigationBarHidden(self.navBarPreference.navBarShidden)
.navigationBarBackButtonHidden(self.navBarPreference.navigationBarBackButtonHidden)
.onAppear{self.navBarPreference.navbarishdden=true
self.navBarPreference.navigationBarBackButtonHidden=true}
}
}
结构SelectedFirstTab:视图{
@State-private变量为空:Bool=true
@ObservedObject var WorkVM=WorkViewModel()
@状态变量workContentModel=[workContentModel]()
变量selectedTabIndex:Int=0
@绑定变量isCategoryAvailable:Bool
@绑定变量workCategoryName:[字符串]
@绑定var workCategoryID:[Int]
@绑定变量selectedID:Int
var body:一些观点{
VStack{
如果self.workContentModel.isEmpty{
EmptyContent()
}否则{
滚动视图(显示指示器:false){
ForEach(self.workContentModel){中的内容
导航链接(目的地:WorkDetailView(数据:内容)){
WorkViewRow(数据:内容)
}.帧(最小宽度:屏幕宽度,最小高度:118)
.padding(.top,5)
.padding(.bottom,5)
}
}.框架(最大高度:600)
}
}
奥纳佩尔先生{
如果self.isCategoryAvailable==false{
self.WorkVM.getWorkList(){workCategory,中的内容
对于0中的i..Void){
AF.request(Router.get(端点:“/mobile/works/top”))
.responseDecodable(of:WorkTabModel.self){response in
打印(“原始URL请求工作列表选项卡:\(字符串(描述:response.request)))
开关响应。结果{
成功案例(价值):
如果让workCategory=value.data.workCategories{
self.workCategory.append(contentsOf:workCategory)
}
//公关
 import SwiftUI

 struct SlidingTab: View {

// Internal state to keep track of the selection index
@State private var selectionState: Int = 0 {
    didSet {
        selection = selectionState
    }
}

// Binding the selection index which will  re-render the consuming view
 @Binding var selection: Int

// The title of the tabs
 private var tabs: [String]

init(selection: Binding<Int>, tabs: [String]) {
    self._selection = selection
    self.tabs = tabs
}

var body: some View {
    VStack {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: 24.scale()) {
                ForEach(self.tabs, id: \.self) { tab in
                    VStack {
                        Text(tab)
                                .frame(maxHeight: 55)
                                .font(.custom("HiraginoSans-W6", size: 15))
                            .foregroundColor(self.selection == self.tabs.firstIndex(of: tab) ? APP_TEXT_COLOR : APP_TEXT_COLOR.opacity(0.5))
                        
                        Rectangle()
                            .frame(maxHeight: 3)
                            .foregroundColor(self.selection == self.tabs.firstIndex(of: tab) ? APP_COLOR : Color.clear)
                            .animation(.linear(duration: 0.25))
                        
                    }.fixedSize()
                        .onTapGesture {
                             withAnimation {
                            let selection = self.tabs.firstIndex(of: tab) ?? 0
                            self.selectionState = selection
                            }
                    }
                }
            }.padding(.horizontal, 20.scale())
        }
    }
    
}
}
import Foundation
import Combine
import Alamofire
import SwiftyJSON

class WorkViewModel: ObservableObject {
var updateValue =  PassthroughSubject<WorkViewModel, Never>()

@Published var workCategory = [WorkCategoryModel]() {
    willSet {
        updateValue.send(self)
    }
}

@Published var workContent = [WorkContentModel]() {
    willSet {
        updateValue.send(self)
    }
}

func getWorkList(completionHandler: @escaping ([WorkCategoryModel], [WorkContentModel]) -> Void) {
    AF.request(Router.get(endpoint: "/mobile/works/top"))
        .responseDecodable(of: WorkTabModel.self) { response in
            
            print("Original URL request WorkList Tab:\(String(describing: response.request))")
            
            switch response.result {
            case let .success(value):
                if let workCategory = value.data.workCategories {
                    self.workCategory.append(contentsOf: workCategory)
                }
               // print("workCategory**:\(self.workCategory)")
                
                if let workContent = value.data.work?.content {
                    self.workContent.append(contentsOf: workContent)
                }
                print("workContent**:\(self.workContent)")

                completionHandler(self.workCategory, self.workContent)

            case let .failure(error):
                print("WorkModel Error**:\(error)")
            }
    }
    
}

func getCategory(id: Int, completionHandler: @escaping ([WorkContentModel]) -> Void) {
    let urlString = "\(baseUrl)/mobile/works/top?work_category_id=\(id)"
    let userToken = UserDefaults.standard.value(forKey: "access_token") ?? ""
    let token = "Bearer \(userToken)"

    let headers: HTTPHeaders = [
        "Content-Type": "application/json",
        "Accept": "application/json",
        "Authorization": token
    ]

    AF.request(urlString, headers: headers)
        .responseJSON { response in
        print("Original URL request WorkList Category:\(String(describing: response.request))")
        print("Category JSON response:\(response)")
    }
    .responseDecodable(of: WorkTabModel.self) { response in
               
               print("Original URL request WorkList Tab:\(String(describing: response.request))")
               
               switch response.result {
               case let .success(value):
                   if let workContent = value.data.work?.content {
                       self.workContent.append(contentsOf: workContent)
                   }
                   print("workContent**:\(self.workContent)")

                   completionHandler(self.workContent)

               case let .failure(error):
                   print("WorkModel Error**:\(error)")
               }
       }
    
}
}
struct WorkView: View {
@EnvironmentObject var navBarPreference: NavBarPreferences

@State private var selectedTabIndex = 0
@State private var showWorkDetailView:Bool = false
@State var isCategoryAvailable:Bool = false

@ObservedObject var WorkVM = WorkViewModel() //
@State var workCategoryName: [String] = [" "]
@State var workCategoryID: [Int] = [0]
@State var workContentModel = [WorkContentModel]()
@State var hasShown: Bool = false

var body: some View {
    VStack(spacing: 0) {
        HeaderView(title: "ワーク")
        VStack {
            if self.workCategoryName.isEmpty == false {
                SlidingTab(selection: $selectedTabIndex, tabs: self.workCategoryName).padding(.top, 10)
                    .onTapGesture {
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                            if self.isCategoryAvailable == true {
                                self.hasShown = true
                                //self.workContentModel.removeAll()
                                print("myWorkCategoryIDs:\(self.workCategoryID)")
                                print("mySelectedIndex:\(self.selectedTabIndex)")
                                let mySelectedID = self.workCategoryID[self.selectedTabIndex]
                                self.WorkVM.workContent.removeAll()
                                self.workContentModel.removeAll()
                                self.getContent(id: mySelectedID)
                            }
                        }
                    }
            }
        }
        
        Spacer().frame(maxHeight: 24)
        
        //(selectedTabIndex == 0 ? SelectedFirstTab() : Text("Second View")).padding()
        VStack {
            if self.workContentModel.isEmpty {
                EmptyContent()
            } else {
                ScrollView(showsIndicators: false) {
                    ForEach(self.workContentModel) { content in
                        //Text("hihihihihihihihihi").frame(minWidth: 100, minHeight: 118)
                        NavigationLink(destination: WorkDetailView(data: content)) {
                            WorkViewRow(data: content)
                        }.frame(minWidth: SCREEN_WIDTH, minHeight: 118)
                            .padding(.top, 5)
                            .padding(.bottom, 5)
                    }
                }.frame(maxHeight: 600)
            }
        }
        
        //Spacer()
    }.frame(minWidth: SCREEN_WIDTH)
        .edgesIgnoringSafeArea(.top)
        .navigationBarTitle("", displayMode: .inline)
        .navigationBarHidden(self.navBarPreference.navBarIsHidden)
        .navigationBarBackButtonHidden(self.navBarPreference.navigationBarBackButtonHidden)
        .onAppear{ self.navBarPreference.navBarIsHidden = true
            self.navBarPreference.navigationBarBackButtonHidden = true
            
            if (self.hasShown == false && self.isCategoryAvailable == false) {
                self.WorkVM.workContent.removeAll()
                self.workContentModel.removeAll()
                self.getCategoryWithContent()
            }
    }
    
    
}

func getCategoryWithContent() {
    self.WorkVM.getWorkList() { workCategory, content in
        for i in 0..<workCategory.count {
            self.workCategoryName.append(workCategory[i].name ?? " ")
            self.workCategoryID.append(workCategory[i].id ?? 0)
        }
        self.workCategoryName.removeFirst()
        
        self.workContentModel = content
        self.isCategoryAvailable = true
        
        print("selectedTabIndex:\(self.selectedTabIndex)")
        print("getCategoryWithContent called")
        
    }
}

func getContent(id: Int) {
    self.WorkVM.getCategory(id: id) { content in
        self.workContentModel = content
        print("selectedTabIndex:\(self.selectedTabIndex)")
        print("getContent called")
    }
}
}


struct EmptyContent: View {
var body: some View {
    ZStack {
        Rectangle()
            .foregroundColor(.clear)
            .frame(maxHeight: 600)
        
        VStack {
            Image("EmptyBackgroundImage")
                .resizable()
                .frame(maxWidth: 150, maxHeight: 146)
            CustomizedText(text: "表示されるワークは \n ありません", tracking: 2.2, frameHeight: 72, fontFamily: "HiraginoSans-W6", fontFamilySize: 22, lineLimit: 2)
                .frame(maxWidth: 218, maxHeight: 72)
            CustomizedText(text: "ここではワーク情報をお届けします。\n 最新のワークを探していますのでお待ちください。", tracking: 1.2, frameHeight: 42, fontFamily: "HiraginoSans-W3", fontFamilySize: 12, lineLimit: 2).frame(maxWidth: 333, maxHeight: 42)
            Spacer().frame(maxHeight: 210)
            
        }
    }
}
}