Виджет пользовательского интерфейса Swift список элементов, которые занимают слишком много места

#swift #swiftui #widget #geometryreader

Вопрос:

введите описание изображения здесь

Как вы можете видеть на изображении, у меня есть виджет с рядом элементов, я должен поставить в конце ряда элементов слово Next update , которое должно быть найдено в конце виджета.

Проблема в том, что:

  • если элементов мало, Next update то это слишком высоко.
  • если элементов много Next update , сообщение не отображается.

Не могли бы вы мне помочь?

P. s.

Если вы считаете, что это должно быть написано по-другому, дайте мне знать, заранее спасибо.

 struct GitCommitWidgetEntryView : View {
    var entry: ProviderCommit.Entry
    @Environment(.colorScheme) var colorScheme
    let firstColor: UInt = getDate() ? 0x4688B4 : 0x030721
    
    var body: some View {
        GeometryReader { geometry in
            if(entry.loading){
                if(!entry.error){
                    VStack() {
                        if(entry.user != ""){
                            HStack {
                                Spacer()
                                Text("(entry.user) ((entry.commits.count))")
                                    .font(.caption)
                                    .foregroundColor(Color.black)
                                    .shadow(
                                        color: Color.black,
                                        radius: 1.0,
                                        x: CGFloat(1),
                                        y: CGFloat(1)
                                    )
                                Spacer()
                            }
                            .background(Color(hex: 0xff9800))
                        }
                        if(entry.commits.count > 0){
                            ForEach(entry.commits, id:.id){
                                item in
                                Text(item.commit.message)
                                    .shadow(
                                        color: Color.black,
                                        radius: 1.0,
                                        x: CGFloat(1),
                                        y: CGFloat(1)
                                    )
                                Text("(item.author.login) (convertDate(date: item.commit.author.date))")
                                    .shadow(
                                        color: Color.black,
                                        radius: 1.0,
                                        x: CGFloat(1),
                                        y: CGFloat(1)
                                    )
                                Divider()
                            }
                            .frame(alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
                        }else{
                            Text("There are no repositories.")
                                .font(.caption)
                                .foregroundColor(Color.black)
                                .padding(2)
                                .background(Color.white.opacity(0.4))
                                .cornerRadius(5)
                                .padding(.bottom, 3)
                                .padding(.horizontal, /*@START_MENU_TOKEN@*/10/*@END_MENU_TOKEN@*/)
                                .multilineTextAlignment(.center)
                                .frame(maxWidth: .infinity, maxHeight: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
                        }
                        HStack {
                            Spacer()
                            Text("Next update")
                                .font(.caption)
                                .foregroundColor(Color.black)
                                .multilineTextAlignment(.center)
                                .shadow(
                                    color: Color.black,
                                    radius: 1.0,
                                    x: CGFloat(1),
                                    y: CGFloat(1)
                                )
                            Spacer()
                        }
                        .background(Color(hex: 0xff9800))
                    }
                    .background(LinearGradient(
                                    gradient: Gradient(colors: [
                                        Color(hex: firstColor),
                                        Color(hex: 0xffffff)
                                    ]),
                                    startPoint: .top,
                                    endPoint: .bottom)
                    )
                }else{
                    VStack() {
                        Text("No user exist.")
                            .font(.caption)
                            .foregroundColor(Color.black)
                            .padding(2)
                            .background(Color.white.opacity(0.4))
                            .cornerRadius(5)
                            .padding(.bottom, 3)
                            .padding(.horizontal, /*@START_MENU_TOKEN@*/10/*@END_MENU_TOKEN@*/)
                            .multilineTextAlignment(.center)
                    }
                    .frame(maxWidth: .infinity, maxHeight: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
                    .background(Color.red)
                }
            }else{
                VStack() {
                    Text("No user selected.")
                        .font(.caption)
                        .foregroundColor(Color.black)
                        .padding(2)
                        .background(Color.white.opacity(0.4))
                        .cornerRadius(5)
                        .padding(.bottom, 3)
                        .padding(.horizontal, /*@START_MENU_TOKEN@*/10/*@END_MENU_TOKEN@*/)
                        .multilineTextAlignment(.center)
                }
                .frame(maxWidth: .infinity, maxHeight: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
                .background(Color.green)
            }
        }
    }
}
 

Ответ №1:

Подход, который вам нужен, состоит в том, чтобы разделить «метки, которые всегда должны быть на экране» и «растущий список», схематически это должно быть так

 VStack {
  Text("Header label")
  Spacer()
  Text("Footer label")
}
.background(
   VStack {
     Text("Header label").opacity(0)     // for content offset
                                    // or constant height spacer
     ForEach ... // list here
   }
}
 

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

1. Я сделал, как вы указали, но я не понимаю, что я делаю не так. Как вы можете видеть на изображении вверху, часть текста вырезана. user-images.githubusercontent.com/20476002/… Код: pastebin.com/Gaxmc3MF