ForEach внутри ScrollView не занимает всю ширину - PullRequest
1 голос
/ 11 июня 2019

Я пытаюсь воссоздать пользовательский интерфейс моего текущего приложения, используя SwiftUI. И это намного сложнее, чем я изначально. Я хотел создать карточные клетки с фоном позади них. Я обнаружил, что List не поддерживает это, по крайней мере, пока. List настолько ограничен - он не позволяет удалить разделитель ячеек.

Итак, я перешел на ForEach внутри ScrollView. Я предполагаю, что это не то, что должно использоваться в производстве для длинных столов, но это должно работать на данный момент. У меня проблема в том, что ForeEach просмотр не занимает всю ширину, которую обеспечивает ScrollView. Я могу установить модификатор .frame(...), но это потребует ширины жесткого кода, что я определенно не хочу делать.

Есть идеи, как заставить VStack взять полную ширину ScrollView? Я пытался использовать ForeEach без VStack, и у него та же проблема. Кажется, что ScrollView (родительское представление) «сообщает» своему дочернему представлению (VStack), что его кадр меньше, чем фактический кадр ScrollView. И на основе этой информации дочерние представления строят свой макет и размеры.

Вот мой текущий результат:

image

А вот и код:

struct LandmarkList : View {
    var body: some View {
        NavigationView {
            ScrollView() {
                VStack {
                    Spacer().frame(height: 160)
                    ForEach(landmarkData) { landmark in
                        LandmarkRow(landmark: landmark).padding([.leading, .trailing], 16)
                    }
                }.scaledToFill()
                .background(Color.pink)
            }
            .background(Color.yellow)
            .edgesIgnoringSafeArea(.all)
            .navigationBarTitle(Text("Landmarks"))

        }
    }
}

struct LandmarkRow : View {
    var landmark: Landmark

    var body: some View {
        HStack {
            VStack(alignment: .leading) {
                Text(landmark.name).font(.title)
                Text("Subtitle")
                    .font(.callout)
                    .color(.gray)
            }
            Spacer()
            Text("5 mi")
                .font(.largeTitle)
            }.frame(height: 80)
            .padding()
            .background(Color.white)
            .cornerRadius(16)
            .clipped()
            .shadow(radius: 2)
    }
}

Ответы [ 2 ]

2 голосов
/ 11 июня 2019

У меня та же проблема, единственный способ, который я нашел до сих пор, это исправить ScrollView и представление контента ширина , чтобы каждое подпредставление, добавляемое вами в представлении контента, былопо центру.

Я создал простую оболочку, которая принимает ширину в качестве параметра init

struct CenteredList<Data: RandomAccessCollection, Content: View>: View where Data.Element: Identifiable {

    public private(set) var width: Length
    private var data: Data
    private var contentBuilder: (Data.Element.IdentifiedValue) -> Content

    init(
        width: Length = UIScreen.main.bounds.width,
        data: Data,
        @ViewBuilder content: @escaping (Data.Element.IdentifiedValue) -> Content)
    {
        self.width = width
        self.data = data
        self.contentBuilder = content
    }

    var body: some View {
        ScrollView {
            VStack {
                ForEach(data) { item in
                    return self.contentBuilder(item)
                }.frame(width: width)
            }
            .frame(width: width)
        }
        .frame(width: width)
    }
}

По умолчанию она принимает ширину экрана (UIScreen.main.bounds.width).

Работаетпросто как List вид:

var body: some View {
    TileList(data: 0...3) { index in
        HStack {
            Text("Hello world")
            Text("#\(index)")
         }
    }
}
1 голос
/ 17 июня 2019

Вполне возможно, что ответом на это может быть просто завершение вашего scrollView внутри GeometryReader

Как сделано в ответе здесь -> Как растянуть View на его родительский фрейм с помощьюSwiftUI

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...