使用 NavigationLink 时不重新加载 Tab 项的 SwiftUI 问题

问题描述

我在 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);
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...