Содержимое SwiftUI Scrollview находится за пределами области прокрутки

#view #swiftui #scrollview #frame

#Вид #swiftui #scrollview #рамка

Вопрос:

У меня возникли проблемы с сохранением содержимого ScrollView, содержащегося в scrollview: введите описание изображения здесь

Изначально я хочу отобразить буквы A и B в ScrollView и заставить пользователя прокручивать, чтобы увидеть дополнительные буквы. Однако, несмотря на то, что я ограничил родительский VStack рамкой высотой 120, вы также можете увидеть букву C, которая находится за пределами ScrollView (как указано синим фоном). Вот код:

 var body: some View {            
    VStack(alignment: .leading, spacing: 0) {
         HStack(alignment: .center , spacing: 5) {
             Text("Letter").font(.tableHeader).frame(width: 75, height: 30, alignment: .center)
         } // HStack
         .frame(width: 195, height: 50, alignment: .center)
         .background(Color.green)

         VStack(alignment: .leading, spacing: 0) {
             GeometryReader { outsideProxy in
                 ScrollView (.vertical, showsIndicators: false) {
                     ZStack(alignment: .top) {           
                         GeometryReader { insideProxy in
                             Color.clear
                             // get offset
                         } // GeometryReader inside
                         VStack(alignment: .leading, spacing: 10) {
                             HStack(alignment: .center, spacing: 5){
                                 Text("A").font(.tableData).frame(width: 75, height: 50, alignment: .center)
                             }
                             HStack(alignment: .center, spacing: 5){
                                 Text("B").font(.tableData).frame(width: 75, height: 50, alignment: .center)
                             }
                             HStack(alignment: .center, spacing: 5){
                                 Text("C").font(.tableData).frame(width: 75, height: 50, alignment: .center)
                             }
                             HStack(alignment: .center, spacing: 5){
                                 Text("D").font(.tableData).frame(width: 75, height: 50, alignment: .center)
                             }
                         } // VStack
                     } // ZStack
                 } // Scrollview
             } // GeometryReader outside
             .background(Color.blue)
         } // VStack
         .frame(width: 195, height: 120, alignment: .leading)
     } // VStack
 }
  

Полный код требует использования GeometryReader (и, следовательно, ZStack), поэтому я оставил эти элементы в примере выше.

Каков наилучший способ решения этой проблемы? Открыт для любых улучшений для кодирования вышеупомянутого макета. Имейте в виду, что в конечном итоге я хочу, чтобы пользователь мог щелкнуть по A, B, C или D, чтобы перейти к следующему представлению в стеке навигации.

Ответ №1:

Сделайте его обрезанным

  ScrollView (.vertical, showsIndicators: false) {
     ZStack(alignment: .top) {           
         GeometryReader { insideProxy in
             Color.clear
             // get offset
         } // GeometryReader inside
         VStack(alignment: .leading, spacing: 10) {
             HStack(alignment: .center, spacing: 5){
                 Text("A").font(.tableData).frame(width: 75, height: 50, alignment: .center)
             }
             HStack(alignment: .center, spacing: 5){
                 Text("B").font(.tableData).frame(width: 75, height: 50, alignment: .center)
             }
             HStack(alignment: .center, spacing: 5){
                 Text("C").font(.tableData).frame(width: 75, height: 50, alignment: .center)
             }
             HStack(alignment: .center, spacing: 5){
                 Text("D").font(.tableData).frame(width: 75, height: 50, alignment: .center)
             }
         } // VStack
     } // ZStack
 } // Scrollview
 .clipped()           // << here !!
  

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

1. Боже … жаль, что я не опубликовал этот вопрос 24 часа назад… потратил так много времени. Спасибо, @Asperi!

2. Ваше решение, @Asperi, устранило основную проблему в вопросе, но после добавления .clipped() я заметил, что в scrollview не отображается буква «D». После достижения дна scrollview слегка подпрыгнет и скроет «D». Как я могу заставить scrollview дойти до дна?

3. Очень странно… Я только что обновился до версии Xcode 12.0 (12A7209), и похоже, что исходный код работал нормально без использования .clipped(), и все параметры отображаются правильно. Просто делюсь с теми, кто столкнется с этим вопросом в будущем.