![](/img/trans.png)
[英]SwiftUI NavigationLink highlight staying highlighted after returning to previous view
[英]SwiftUI - NavigationLink cell in a Form stays highlighted after detail pop
在 iOS 14 中,看起來NavigationLink
在返回Form
上下文后不會被取消選擇。 這也適用於Form
Picker
和其他任何導致從列表中顯示另一個View
的東西(為呈現單元格提供突出顯示的上下文)。
我沒有注意到 iOS 13 中的這種行為。
一旦另一個視圖被關閉,有沒有辦法“取消選擇”突出顯示的行?
示例代碼:
struct ContentView: View {
var body: some View {
Form {
NavigationLink(destination: Text("Detail")) {
Text("Link")
}
}
}
}
(不同)視覺示例:
在我的情況下,這種行為出現在我的NavigationView
和List/Form
之間使用任何 Viewcontent(例如 Text()、Image()、...)時。
var body: some View {
NavigationView {
VStack {
Text("This text DOES make problems.")
List {
NavigationLink(destination: Text("Doesn't work correct")) {
Text("Doesn't work correct")
}
}
}
}
}
將 Text()放在List之下不會產生任何問題:
var body: some View {
NavigationView {
VStack {
List {
NavigationLink(destination: Text("Does work correct")) {
Text("Does work correct")
}
}
Text("This text doesn't make problems.")
}
}
}
這絕對是一個 XCode 12 錯誤。 隨着越來越多的人報告這個問題,它會越早得到解決。
我也遇到了這個問題,並相信我找到了我的案例的根本原因。
在我的情況下,我有一個如下結構:
struct Page1View: View {
var body: some View {
NavigationView {
List {
NavigationLink("Page 2", destination: Page2View())
}
.listStyle(GroupedListStyle())
.navigationBarTitle("Page 1")
}
}
}
struct Page2View: View {
var body: some View {
List {
NavigationLink("Page 3", destination: Text("Page 3"))
}
.listStyle(GroupedListStyle())
.navigationBarTitle("Page 2")
}
}
此問題會發生在 NavigationLink 到頁面 3 上。在控制台輸出中,使用該鏈接時會顯示此錯誤:
2021-02-13 16:41:00.599844+0000 App[59157:254215] [Assert] displayModeButtonItem is internally managed and not exposed for DoubleColumn style. Returning an empty, disconnected UIBarButtonItem to fulfill the non-null contract.
我發現我需要將.navigationViewStyle(StackNavigationViewStyle())
應用於 NavigationView,這解決了問題。
IE
struct Page1View: View {
var body: some View {
NavigationView {
List {
NavigationLink("Page 2", destination: Page2View())
}
.listStyle(GroupedListStyle())
.navigationBarTitle("Page 1")
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
今天一直在與這個問題作斗爭半天,來到這篇文章,幫助我理解如果Text
、 Button
或其他東西放在NavigationView
和我的案例List
之間會出現這個問題。 我找到了對我有用的解決方案。 只需為該項目添加.zIndex()
。 .zIndex()
必須高於List
Tried with Xcode 12.5
。
var body: some View {
NavigationView {
VStack {
Text("This text DOES make problems.")
.zIndex(1.0)
List {
NavigationLink(destination: Text("Doesn't work correct")) {
Text("Doesn't work correct")
}
}
}
}
}
我做了一些修補,結果證明這是由於UIHostingController
嵌套在UINavigationController
並使用該導航控制器造成的。 更改導航堆棧以使用 SwiftUI NavigationView
解決了此問題。
與@pawello2222 在問題評論中所說的類似,我認為根本原因與 SwiftUI 在使用外部UINavigationController
時不理解正確的導航層次結構有關。
這只是修復了此問題的一個實例,根據我的視圖結構,我仍在各種其他上下文中遇到此問題。
我已經向 Apple 提交了一份問題報告FB8705430 ,所以希望這個問題很快得到解決。
之前(損壞):
struct ContentView: View {
var body: some View {
Form {
NavigationLink(destination: Text("test")) {
Text("test")
}
}
}
}
// (UIKit presentation context)
let view = ContentView()
let host = UIHostingController(rootView: view)
let nav = UINavigationController(rootViewController: host)
present(nav, animated: true, completion: nil)
之后(工作):
struct ContentView: View {
var body: some View {
NavigationView {
Form {
NavigationLink(destination: Text("test")) {
Text("test")
}
}
}
}
}
// (UIKit presentation context)
let view = ContentView()
let host = UIHostingController(rootView: view)
present(host, animated: true, completion: nil)
這絕對是List
一個錯誤,目前,我的解決方法是通過更改 id 來刷新List
,如下所示:
struct YourView: View {
@State private var selectedItem: String?
@State private var listViewId = UUID()
var body: some View {
List(items, id: \.id) {
NavigationLink(destination: Text($0.id),
tag: $0.id,
selection: $selectedItem) {
Text("Row \($0.id)")
}
}
.id(listViewId)
.onAppear {
if selectedItem != nil {
selectedItem = nil
listViewId = UUID()
}
}
}
}
我基於此制作了一個修飾符,您可以使用:
struct RefreshOnAppearModifier<Tag: Hashable>: ViewModifier {
@State private var viewId = UUID()
@Binding var selection: Tag?
func body(content: Content) -> some View {
content
.id(viewId)
.onAppear {
if selection != nil {
viewId = UUID()
selection = nil
}
}
}
}
extension View {
func refreshOnAppear<Tag: Hashable>(selection: Binding<Tag?>? = nil) -> some View {
modifier(RefreshOnAppearModifier(selection: selection ?? .constant(nil)))
}
}
像這樣使用它:
List { ... }
.refreshOnAppear(selection: $selectedItem)
我設法通過向列表的不同組件添加 id,使用綁定並重置 .onDisappear 上的綁定來解決它
struct ContentView: View {
@State var selection: String? = nil
var body: some View {
NavigationView {
VStack {
Text("Hello, world!")
.padding()
List {
Section {
NavigationLink( destination: Text("Subscreen1"), tag: "link1", selection: $selection ) {
Text("Subscreen1")
}.onDisappear {
self.selection = nil
}
NavigationLink( destination: Text("Subscreen2"), tag: "link2", selection: $selection ) {
Text("Subscreen2")
}.onDisappear {
self.selection = nil
}
}.id("idSection1")
}
.id("idList")
}
}
}
}
這是我一直在使用的解決方法,直到此 List 問題得到修復。 使用Introspect庫,我保存 List 的 UITableView.reloadData 方法並在它再次出現時調用它。
import SwiftUI
import Introspect
struct MyView: View {
@State var reload: (() -> Void)? = nil
var body: some View {
NavigationView {
List {
NavigationLink("Next", destination: Text("Hello"))
}.introspectTableView { tv in
self.reload = tv.reloadData
}.onAppear {
self.reload?()
}
}
}
}
將.navigationViewStyle(StackNavigationViewStyle())
添加到NavigationView
為我修復了它。
在此線程中建議: https : //developer.apple.com/forums/thread/660468
這是我對這個問題的解決方案。
// This in a stack in front of list, disables large navigation title from collapsing by disallowing list from scrolling on top of navigation title
public struct PreventCollapseView: View {
@State public var viewColor: Color?
public init(color: Color? = nil) {
self.viewColor = color
}
public var body: some View {
Rectangle()
.fill(viewColor ?? Color(UIColor(white: 0.0, alpha: 0.0005)))
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 1)
}
}
// handy modifier..
extension List {
public func uncollapsing(_ viewUpdater: Bool) -> some View {
VStack(spacing: 0.0) {
Group {
PreventCollapseView()
self
}.id(viewUpdater)
}
}
}
struct TestView: View {
@State var updater: Bool = false
var body: some View {
List {
Text("Item one")
Text("Item two")
Text("Manually refresh")
.onTapGesture { DispatchQueue.main.async { updater.toggle() } }
.onAppear { print("List was refreshed") }
}
.uncollapsing(updater)
.clipped()
.onAppear { DispatchQueue.main.async { updater.toggle() }} // Manually refreshes list always when re-appearing/appearing
}
}
添加 NavigationView,為 largeTitle 配置,並嵌入 TestView,一切就緒。 切換更新程序以刷新。
有同樣的問題。 奇怪的是,完全相同的代碼在 iOS13 中工作。 我在一個簡單的列表中遇到了這個問題:
struct TestList: View {
let someArray = ["one", "two", "three", "four", "five"]
var body: some View {
List(someArray, id: \.self) { item in
NavigationLink(
destination: Text(item)) {
Text(item)
}.buttonStyle(PlainButtonStyle())
}.navigationBarTitle("testlist")
}
}
這嵌入在:
struct ListControllerView: View {
@State private var listPicker = 0
var body: some View {
NavigationView{
Group{
VStack{
Picker(selection: $listPicker, label: Text("Detailoverview")) {
Text("foo").tag(0)
Text("bar").tag(1)
Text("TestList").tag(2)
}
這是在 Tabbar 內。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.