При нажатии в любом месте строки списка запускается навигационная ссылка, есть ли способ изменить это поведение?

#ios #swift #swiftui #swiftui-list #swiftui-navigationlink

Вопрос:

Я создаю список с помощью Scrollview LazyVStack в iOS 14 и списка в iOS 13, но поведение нажатия отличается. Если я помещаю навигационную ссылку в LazyVStack, ссылка срабатывает только при нажатии, но в списке, если я нажимаю в любом месте строки, навигационная ссылка срабатывает.

Есть ли способ запустить какую-либо навигационную ссылку внутри списка только при нажатии на нее? Приведенный ниже код является примером, в реальном проекте много компонентов внутри компонентов, это не просто выводит навигационную ссылку за пределы списка.

Код:

Экран списка

 import SwiftUI

struct ContentView: View {
    
    @State var navigate = false
    
    var body: some View {
        NavigationView {
            VStack {
                VList {
                    ForEach(0..<3) { index in
                        VStack(alignment: .leading) {
                            HStack {
                                Text("Item title")
                                    .font(.system(size: 17))
                                    .fontWeight(.semibold)
                                    .frame(idealWidth: .infinity, maxWidth: .infinity, alignment: .leading)
                                    .padding(.all, 4)
                                
                                ZStack {
                                    Text("See more")
                                        .font(.system(size: 15))
                                        .underline()
                                        .padding(.all, 4)
                                        .onTapGesture {
                                            self.navigate = true
                                        }
                                    
                                    NavigationLink(
                                        destination: Text("Destination"),
                                        isActive: $navigate,
                                        label: {
                                            EmptyView()
                                        })
                                        .buttonStyle(PlainButtonStyle())
                                }
                            }
                            
                            Text("Description of item")
                        }
                    }
                }
            }
            .navigationBarHidden(true)
            .navigationBarTitle("")
        }
    }
}
 

Компонент VList

 import SwiftUI

struct VList<Content:View>: View {
    
    var content: () -> Content
    
    var body: some View {
        if #available(iOS 14.0, *) {
            ScrollView {
                LazyVStack(spacing: 0) {
                    content()
                }
            }
        } else {
            List {
                content()
                    .padding(.horizontal, -20)
            }
            .onAppear {
                UITableView.appearance().separatorStyle = .none
                UITableViewCell.appearance().selectionStyle = .none
            }
        }
    }
}
 

Ответ №1:

Вы должны предоставить фон для VStack, а также использовать onTapGesture . Поэтому я не знаю, какой цвет вашего приложения или фона я дал невидимому цвету, вы можете заменить его своим цветом. Также обратите внимание, что вы должны сообщить SwiftUI, что используется фон, и это означает, что SwiftUI не применяет действия ко всем VStack.


 struct ContentView: View {
    
    @State var navigate = false
    
    var body: some View {
        NavigationView {
            VStack {
                List {
                    ForEach(0..<3) { index in
                        VStack(alignment: .leading) {
                            HStack {
                                Text("Item title")
                                    .font(.system(size: 17))
                                    .fontWeight(.semibold)
                                    .frame(idealWidth: .infinity, maxWidth: .infinity, alignment: .leading)
                                    .padding(.all, 4)
                                
                                ZStack {
                                    Text("See more")
                                        .font(.system(size: 15))
                                        .underline()
                                        .padding(.all, 4)
                                        .onTapGesture {
                                            self.navigate = true
                                        }
                                    
                                    NavigationLink(
                                        destination: Text("Destination"),
                                        isActive: $navigate,
                                        label: {
                                            EmptyView()
                                        })
                                        .buttonStyle(PlainButtonStyle())
                                }
                            }
                            
                            
                            Text("Description of item")
                        }
                        .background(Color.white.opacity(0.01).onTapGesture { })    // << : Here
                    }
                }
            }
            .navigationBarHidden(true)
            .navigationBarTitle("")
        }
    }
}
 

Комментарии:

1. Это отлично работает для нажатия за пределами текста, но когда я нажимаю в тексте(«Подробнее»), навигационная ссылка запускается 3 раза, и навигация возвращается на экран списка, а не на экран назначения.

2. извините, я сначала отправил неправильный код, я должен отправить .фон(цвет. белый.непрозрачность(0,01).onTapGesture { }) и отправил этот неправильный .фон(цвет.очистить.onTapGesture { }) повторите попытку! попробуйте использовать белый.непрозрачность(0,01)

3. Проблема с краном устранена с помощью вашего предложения, ошибка навигация не работает должным образом видео ошибки

4. Так что это еще вопрос, а нужно новый вопрос, Могу я вам помочь, как хорошо, но это вопрос, не связанный с этим вопрос, Вы можете запустить мой приведенный код в моем ответе, я имею в виду именно странице просмотр содержимого и он будет работать отлично без проблем, вопрос вы ставите видео Еще одна проблема в другой части вашего кода, а не на странице просмотр содержимого , поэтому я думаю, что вы можете принять моего ответа здесь и мы работаем по этому вопросу вместе на новый вопрос.

5. Проблема возникает и в contentView , но только в iOS 13, в iOS 14 этот код работает идеально. Из-за этого я спрашиваю в комментариях, но если вы предпочитаете, я могу создать другой вопрос.