I got this inside LazyVstack:
ForEach(memes, id: \.memeid){
meme in
if(!user.hiddenUsersString.contains(String(meme.userid) ",")){
GeometryReader{ proxy in
MemeView(memeid: meme.memeid,
picUrl: Functions.getMediaUrl(media: meme.pic, serverScaling: serverScaling,
whichMedia: "memes"),
profilImgUrl: finalImgUrl(theUrl: Functions.getProfileImg(userid: meme.userid, serverScaling: serverScaling, imgTag: user.userid == meme.userid ? user.profilePicTag : nil), memeOwner: meme.userid),
memeWidth: memeWidth,
memeHeight: Functions.getMemeHeight(memeWidth: memeWidth, fileName: meme.pic, memeSize: meme.size),
position: proxy.frame(in: .global).origin.y,
meme: meme,
memes: self.$memes)
}
}
}
In the body of MemeView I got:
VStack{
HStack{
AsyncImage(url: URL(string: profilImgUrl)) { phase in
switch phase {
case .empty:
ProgressView()
.scaleEffect(x: 1.5, y: 1.5, anchor: .center)
.aspectRatio(contentMode: .fit)
.frame(maxWidth: 34)
case .success(let image):
image.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxWidth: 34)
.cornerRadius(50)
case .failure:
Image(systemName: "person.circle.fill")
.resizable()
.aspectRatio(contentMode: .fit).frame(height: 34)
.cornerRadius(50)
.foregroundColor(Color.gray)
@unknown default:
Image(systemName: "person.circle.fill")
.resizable()
.aspectRatio(contentMode: .fit).frame(height: 34)
.cornerRadius(50)
.foregroundColor(Color.gray)
}
}
Text(meme.nickname)
}
.frame(height: 30)
ZStack{
if(meme.pic.contains(".mp4")){
VideoPlayer(player: player)
.frame(width: memeWidth,
height: memeHeight,
alignment: .center)
}else{
AsyncImage(url: URL(string: picUrl)) { phase in
switch phase {
case .empty:
ProgressView()
.scaleEffect(x: 1.5, y: 1.5, anchor: .center)
.aspectRatio(contentMode: .fit)
.frame(width: 34)
case .success(let image):
image.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: memeWidth, height: memeHeight)
.cornerRadius(50)
case .failure:
Image(systemName: "person.circle.fill")
.resizable()
.aspectRatio(contentMode: .fit).frame(height: 34)
.cornerRadius(50)
.foregroundColor(Color.gray)
@unknown default:
Image(systemName: "person.circle.fill")
.resizable()
.aspectRatio(contentMode: .fit).frame(height: 34)
.cornerRadius(50)
.foregroundColor(Color.gray)
}
}
}
}
.frame(width: memeWidth, height: 500)
}
.task {
if(meme.pic.contains(".mp4")){
player = AVPlayer(url: URL(string: picUrl)!)
}
}
Everything is squeezed together! VStack completely ignores the height of the children views.
Why is that and how to fix this?
I'm new to iOS / SwiftUI and must say that I absolutely loathe it. I'm shocked that apple think it's ok to release such a bugged and limited pile garbage into the world!
CodePudding user response:
First thing you should do is remove the VStack
located in your MemeView
, when you consider your overall structure you have something like this, which is not what I believe you're expecting.
LazyVStack {
VStack {
//Your MemeViewContent
}
}
As you can see, you have a LazyVStack
and then another VStack
inside of it, when your outer LazyVStack
manages your expected view just fine.
The next step is to refactor out the GeometryReader
OR, moving it higher in the view stack. Currently you have it ForEach
individual view, so it's going to cause the views contained inside of it, to be resized unexpectedly. Effectively, you've got a bunch of really small Frames
inside of your ForEach
loop, which then you're attempting to use as if it was taking up the entire screen, effectively chopping it into very small parts, eg squished views. A better solution would be to make use of the .onAppear{}
or .onDisappear{}
modifiers, or get the view's properties and calculate it that way. Ultimately, I would always recommend avoiding GemometryReader
except in special circumstances. If you're hard-stuck needing to have to use the GeometryReader
have a look here for a usage of it, where you'd bring it down to a more child view position and make use of the proxy. https://stackoverflow.com/a/73038067/12417531
onAppear/onDisappear Resources: How to check if a view is displayed on the screen? (Swift 5 and SwiftUI)
Geometry Reader Resources: https://swiftwithmajid.com/2020/11/04/how-to-use-geometryreader-without-breaking-swiftui-layout/