问题描述
我在 TabView 中使用导航视图,问题是如果我在 Tab A 和 NavigationView 上打开其他视图,当从选项卡 A 更改为 B 时,我又回到选项卡 AI 不从头开始重新加载选项卡 A,但它显示使用 NavitagionLink 打开的最后一个视图。问题是在每个视图中我都从数据库获取数据,因此如果显示一个空视图。
我的 ContentView 如下所示:
import SwiftUI
struct ContentView: View {
@Observedobject var appState = AppState()
@State var currentTab : Tab
var body: some View {
TabView(selection: $appState.currentTab) {
NavigationView {
HomeView(appState: appState)
}
.tabItem {
if appState.currentTab == .home {
Image(systemName: "house.fill")
} else {
Image(systemName: "house")
}
Text(LocalizedStringKey("HoMetabMenu"))
}.tag(Tab.home)
NavigationView {
SearchView()
}
.tabItem {
if appState.currentTab == .search {
Image(systemName: "magnifyingglass.circle.fill")
} else {
Image(systemName: "magnifyingglass")
}
Text(LocalizedStringKey("SearchTabMenu"))
}.tag(Tab.search)
NavigationView {
AddItemView(appState: appState)
}
.tabItem {
if appState.currentTab == .add {
Image(systemName: "plus.circle.fill")
} else {
Image(systemName: "plus.circle")
}
Text(LocalizedStringKey("SellTabMenu"))
}.tag(Tab.add)
NavigationView {
ShoppingCartFavoritesView()
}
.tabItem {
if appState.currentTab == .favorites {
Image(systemName: "cart.fill")
} else {
Image(systemName: "cart")
}
Text(LocalizedStringKey("CartTabMenu"))
}.tag(Tab.favorites)
NavigationView {
ProfileView(appState: appState)
}
.tabItem {
if appState.currentTab == .profile {
Image(systemName: "person.fill")
} else {
Image(systemName: "person")
}
Text(LocalizedStringKey("ProfileTabMenu"))
}.tag(Tab.profile)
}//End TabView
.accentColor(Color("ColorMainDark"))
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(currentTab: Tab.home)
}
}
class AppState: ObservableObject {
@Published var currentTab : Tab = .home
}
enum Tab {
case home,search,add,favorites,profile
}
如果我打开 SearchView()
struct SearchView: View {
var body: some View {
NavigationLink(destination: View_2(id: "ABC")){
Text("ABC")
}
}
}
struct View_2: View {
@Observedobject var performSearchProducts = PerformSearchInProducts()
var id : String
var body: some View {
ScollView{
ForEach(performSearchProducts.products) { product in
Text(product.name)
}
}.onAppear(perform: {
self.performSearchProducts.searchSubCategory(id: id)
})
}
}
如果在 SearchView 中,我在 View_2() 上打开另一个标签,当我回到标签 SearchView 时,它不会显示 SearchView(),但它仍然在 View_2() 上,导航中的后退按钮吧。
如何显示 SearchView() 而不保持 NavigationLink 的状态?
解决方法
这是默认行为。将 id 附加到 TabView。
/**
* NodeJs Server-Side Example for Fine Uploader (traditional endpoints).
* Maintained by Widen Enterprises.
*
* This example:
* - handles non-CORS environments
* - handles delete file requests assuming the method is DELETE
* - Ensures the file size does not exceed the max
* - Handles chunked upload requests
*
* Requirements:
* - express (for handling requests)
* - rimraf (for "rm -rf" support)
* - multiparty (for parsing request payloads)
* - mkdirp (for "mkdir -p" support)
*/
// Dependencies
var express = require("express"),fs = require("fs"),rimraf = require("rimraf"),mkdirp = require("mkdirp"),multiparty = require('multiparty'),app = express(),cors = require('cors'),// paths/constants
fileInputName = process.env.FILE_INPUT_NAME || "qqfile",publicDir = process.env.PUBLIC_DIR || __dirname + "/",nodeModulesDir = process.env.NODE_MODULES_DIR || "node_modules/",uploadedFilesPath = process.env.UPLOADED_FILES_DIR || "uploads/",chunkDirName = "chunks",port = process.env.SERVER_PORT || 3031,maxFileSize = process.env.MAX_FILE_SIZE || 0; // in bytes,0 for unlimited
app.listen(port);
// enable CORs
app.use(cors());
// routes
app.use(express.static(publicDir));
app.use("/node_modules",express.static(nodeModulesDir));
app.post("/uploads",onUpload);
app.delete("/uploads/:uuid",onDeleteFile);
function onUpload(req,res) {
var form = new multiparty.Form();
form.parse(req,function(err,fields,files) {
var partIndex = fields.qqpartindex;
// text/plain is required to ensure support for IE9 and older
res.set("Content-Type","text/plain");
if (partIndex == null) {
onSimpleUpload(fields,files[fileInputName][0],res);
}
else {
onChunkedUpload(fields,res);
}
});
}
function onSimpleUpload(fields,file,res) {
var uuid = fields.test,responseData = {
success: false
};
file.name = fields.qqfilename;
if (isValid(file.size)) {
moveUploadedFile(file,uuid,function() {
responseData.success = true;
res.send(responseData);
},function() {
responseData.error = "Problem copying the file!";
res.send(responseData);
});
}
else {
failWithTooBigFile(responseData,res);
}
}
function onChunkedUpload(fields,res) {
var size = parseInt(fields.qqtotalfilesize),uuid = fields.qquuid,index = fields.qqpartindex,totalParts = parseInt(fields.qqtotalparts),responseData = {
success: false
};
file.name = fields.qqfilename;
if (isValid(size)) {
storeChunk(file,index,totalParts,function() {
if (index < totalParts - 1) {
responseData.success = true;
res.send(responseData);
}
else {
combineChunks(file,function() {
responseData.success = true;
res.send(responseData);
},function() {
responseData.error = "Problem conbining the chunks!";
res.send(responseData);
});
}
},function(reset) {
responseData.error = "Problem storing the chunk!";
res.send(responseData);
});
}
else {
failWithTooBigFile(responseData,res);
}
}
function failWithTooBigFile(responseData,res) {
responseData.error = "Too big!";
responseData.preventRetry = true;
res.send(responseData);
}
function onDeleteFile(req,res) {
var uuid = req.params.uuid,dirToDelete = uploadedFilesPath + uuid;
rimraf(dirToDelete,function(error) {
if (error) {
console.error("Problem deleting file! " + error);
res.status(500);
}
res.send();
});
}
function isValid(size) {
return maxFileSize === 0 || size < maxFileSize;
}
function moveFile(destinationDir,sourceFile,destinationFile,success,failure) {
mkdirp(destinationDir,function(error) {
var sourceStream,destStream;
if (error) {
console.error("Problem creating directory " + destinationDir + ": " + error);
failure();
}
else {
sourceStream = fs.createReadStream(sourceFile);
destStream = fs.createWriteStream(destinationFile);
sourceStream
.on("error",function(error) {
console.error("Problem copying file: " + error.stack);
destStream.end();
failure();
})
.on("end",function(){
destStream.end();
success();
})
.pipe(destStream);
}
});
}
function moveUploadedFile(file,failure) {
var destinationDir = uploadedFilesPath + uuid + "/",fileDestination = destinationDir + file.name;
moveFile(destinationDir,file.path,fileDestination,failure);
}
function storeChunk(file,numChunks,failure) {
var destinationDir = uploadedFilesPath + uuid + "/" + chunkDirName + "/",chunkFilename = getChunkFilename(index,numChunks),fileDestination = destinationDir + chunkFilename;
moveFile(destinationDir,failure);
}
function combineChunks(file,failure) {
var chunksDir = uploadedFilesPath + uuid + "/" + chunkDirName + "/",destinationDir = uploadedFilesPath + uuid + "/",fileDestination = destinationDir + file.name;
fs.readdir(chunksDir,fileNames) {
var destFileStream;
if (err) {
console.error("Problem listing chunks! " + err);
failure();
}
else {
fileNames.sort();
destFileStream = fs.createWriteStream(fileDestination,{flags: "a"});
appendToStream(destFileStream,chunksDir,fileNames,function() {
rimraf(chunksDir,function(rimrafError) {
if (rimrafError) {
console.log("Problem deleting chunks dir! " + rimrafError);
}
});
success();
},failure);
}
});
}
function appendToStream(destStream,srcDir,srcFilesnames,failure) {
if (index < srcFilesnames.length) {
fs.createReadStream(srcDir + srcFilesnames[index])
.on("end",function() {
appendToStream(destStream,index + 1,failure);
})
.on("error",function(error) {
console.error("Problem appending chunk! " + error);
destStream.end();
failure();
})
.pipe(destStream,{end: false});
}
else {
destStream.end();
success();
}
}
function getChunkFilename(index,count) {
var digits = new String(count).length,zeros = new Array(digits + 1).join("0");
return (zeros + index).slice(-digits);
}