ScrollViewReader не работает, и построение происходит довольно медленно

#swiftui

Вопрос:

Я не мог понять, почему он не работает с моим считывателем прокрутки ниже моего кода. Пожалуйста, помогите мне разобраться в этом вопросе. Я хочу передать свой zolyric.number в scrollToIndex, и этот scrollToIndex установит число, которое я хочу прокрутить в моем HymnLyrics(). Кроме того, хотя я не смог найти ошибку, здание довольно медленное.

Здесь ZolaiTitles () — это тот же список, просто сортирующий названия песен алгебраически, а HymnLyrics () — это тот, который будет отображаться на холсте.

 struct ZolaiTitles: View {
    
    @AppStorage("scrollToIndex") var scrollToIndex: Int?
    
    
    @EnvironmentObject var tappingSwitches: TapToggle
    
    let zoLyrics: [Lyric] = LyricList.hymnLa.sorted { lhs, rhs in
        return lhs.zoTitle < rhs.zoTitle
    }
    
    var body: some View {
        
        ScrollView {
            ForEach(zoLyrics, id: .id) { zoLyric in
                VStack {
                    Button(action: {
                        
                        //if let lyricNum = String(zoLyric) {
                        scrollToIndex = zoLyric.number // zolyric.number is already an interger.
                        //}

                        self.tappingSwitches.isHymnTapped.toggle()
                        
                    }, label: {
                        HStack {
                            Text(zoLyric.zoTitle)
                                .foregroundColor(Color("bTextColor"))
                                .lineLimit(1)
                                .minimumScaleFactor(0.5)

                            Spacer()
                            Text("(zoLyric.number)")
                                .foregroundColor(Color("bTextColor"))
                        }
                    })
                }
                .frame(maxWidth: .infinity, alignment: .leading)
                .padding([.leading, .bottom, .trailing])
            }
        }
    }
}


struct HymnLyrics: View {
    
    @AppStorage("scrollToIndex") var scrollToIndex: Int = 1
    
    var lyrics: [Lyric] = LyricList.hymnLa
    @AppStorage("fontSizeIndex") var fontSizeIndex = Int("Medium") ?? 18
    @AppStorage("fontIndex") var fontIndex: String = ""
    @AppStorage("showHVNumbers") var showHVNumbers: Bool = true
    
    var body: some View {
        ScrollViewReader { proxy in
            List(lyrics, id: .id) { lyric in
                
                VStack(alignment: .center, spacing: 0) {
                    
                    Text("(lyric.number)")
                        .padding()
                        .multilineTextAlignment(/*@START_MENU_TOKEN@*/.leading/*@END_MENU_TOKEN@*/)
                        .id(lyric.number)
                        
                    
                    VStack {
                        VStack {
                            Text(lyric.zoTitle)
                                .font(.title2)
                                .fontWeight(.bold)
                                .foregroundColor(.primary)
                                .autocapitalization(.allCharacters)
                            
                            Text(lyric.engTitle)
                                .font(.title3)
                                .fontWeight(.medium)
                                .foregroundColor(.secondary)
                                .italic()
                                
                        }
                        // Don't use Padding here!
                        
                    }
                    .multilineTextAlignment(.center)
                    
                    HStack {
                        Text(lyric.key)
                            .italic()
                        
                        Spacer()
                        
                        Text(lyric.musicStyle)
                    }
                    .foregroundColor(.blue)
                    .padding(.vertical)
                }
                //.id(lyric.number)

            }
            .onChange(of: scrollToIndex, perform: { value in
                proxy.scrollTo(value, anchor: .top)
            })
        }
    }
}
 

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

1. Я почти уверен, что ScrollViewReader должен находиться непосредственно внутри ScrollView, а не где-то дальше по иерархии

2. Спасибо @aheze, это работает после реализации в режиме прокрутки и изменения моего списка в цикл foreach. Но строительство заняло довольно много времени. Что-то не так с моим кодом? Кроме того, вид не прилипает к странице. Страница всегда начинается с самого начала.

3. onChange будет вызван только при scrollToIndex изменении. Когда ваше приложение запускается, оно не вызывает его, используйте onApeear для прокрутки до значения, сохраненного с помощью AppStorage