Выравнивание по низу VStack в SwiftUI

В настоящее время создается приложение для чата, и мне нужно, чтобы новые сообщения появлялись внизу экрана. Мне также нужно выровнять сообщения по нижнему краю. Однако использование VStack внутри ScrollView по умолчанию обеспечивает выравнивание по верхнему краю.

занятый swiftui!

    ScrollView {
        VStack(alignment: .leading, spacing: 16) {
            Spacer()
            .frame(minWidth: 0, maxWidth: .infinity, minHeight:0, maxHeight: .infinity, alignment: Alignment.topLeading)
            ForEach(notList, id: \.self) { not in
                NotRow(not: not)

            }

        }
        .padding()
        .frame(minWidth: 0, maxWidth: .infinity, minHeight:0, alignment: Alignment.topLeading)

    }

Что мне делать, чтобы это исправить?

5 ответов

не предлагает одинаковую высоту своим детям ( VStackв данном случае) как было предложено ему. Он просто просит минимальный размер. Решение состоит в том, чтобы заставить его непосредственного потомка реагировать с минимальной высотой, которая была предложена для ScrollViewсам. Мы можем добиться этого, прочитав предложенную высоту через GeometryReaderи установив это как минимальную высоту ребенка.

      GeometryReader { reader in
    ScrollView {
        VStack {
            /// Spacer() or Color.red will now behave as expected
        }
        .frame(minHeight: reader.size.height)
    }
}

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

ScrollView {
  VStack(alignment: .leading, spacing: 16) {
      Spacer()
      .frame(minWidth: 0, maxWidth: .infinity, minHeight:0, maxHeight: .infinity, alignment: Alignment.topLeading)
      ForEach(notList, id: \.self) { not in
          NotRow(not: not)
      }

  }
  .padding()
  .rotationEffect(Angle(degrees: 180))
}
.rotationEffect(Angle(degrees: 180))

Я думаю, вам не хватает maxHeight в VStack

VStack(alignment: .leading) {
  Spacer().frame(maxWidth: .infinity)
  // content here
}
.frame(maxHeight: .infinity) // <- this

Если вы удалите Spacer() и поместите его после закрывающих фигурных скобок вашего ForEach, это исправит. Вот как будет выглядеть ваш обновленный код:

ScrollView {
        VStack(alignment: .leading, spacing: 16) {
            .frame(minWidth: 0, maxWidth: .infinity, minHeight:0, maxHeight: .infinity, alignment: Alignment.topLeading)
            ForEach(notList, id: \.self) { not in
                NotRow(not: not)

            }
            Spacer()
        }
        .padding()
        .frame(minWidth: 0, maxWidth: .infinity, minHeight:0, alignment: Alignment.topLeading)

    }

Попробуйте изменить все свои Alignment.topLeadingс к Alignment.bottomLeading

Другие вопросы по тегам