#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