I've got an HStack with a Menu and a Link buttons, which are part of a card that pops up when the user clicks on the card's title. Every time the card expands fully, the Menu button is higher than the Link button. Once clicked, the Menu button goes down to its proper position.
Any ideas what I'm doing wrong?
struct ItemButtonRow: View {
var item: ItemEntity
var bottomPadding: CGFloat = 10
@Binding var showShareSheet: Bool
var body: some View {
HStack(alignment: .center) {
Menu(
content: {
Button {
showShareSheet.toggle()
} label: {
Text("as image")
Image(systemName: "photo")
}
ShareLink(item: item.title, message: Text(item.summary)) {
Text("as text")
Image(systemName: "text.justify.left")
}
},
label: {
HStack {
Image(systemName: "square.and.arrow.up")
Text("Share")
}
.padding(10)
.background(RoundedRectangle(cornerRadius: 10).fill(Color("whitesand")))
.tint(Color(.secondaryLabel))
}
)
Spacer()
Link(destination: URL(string: "\(item.link)?utm_source=items&utm_medium=ios_app")!) {
Image(systemName: "book")
Text("Read more")
}
.padding(10)
.background(RoundedRectangle(cornerRadius: 10).fill(Color("vpurple")))
.tint(Color(.white))
}
.frame(height: 60)
.padding(.bottom, bottomPadding)
}
}
struct DailyItemView: View {
@Environment(\.scenePhase) private var scenePhase
@EnvironmentObject var am: ItemModel
@EnvironmentObject var um: UnsplashModel
@State private var cardPosition: BottomSheetPosition = .dynamicBottom
@State private var showAboutScreen = false
@State private var showShareSheet = false
@State private var refreshImage = false
private let haptics = UINotificationFeedbackGenerator()
private let iPad = UIDevice.current.userInterfaceIdiom == .pad
// MARK: - BODY
var body: some View {
let topCardPosition: BottomSheetPosition = iPad ? .relative(0.6) : .relative(0.8)
ZStack {
GeometryReader { proxy in
DailyItemCoverImage(imageUrl: am.dailyItemCoverImageUrl, blurHash: am.dailyItemImageBlurHash)
}
.ignoresSafeArea()
.bottomSheet(
bottomSheetPosition: $cardPosition,
switchablePositions: [.dynamicBottom, topCardPosition],
headerContent: {
ItemTitle(item: am.dailyItem, showDate: false, alignment: .center)
.padding(.top, 20)
.padding(.horizontal, 25)
.padding(.horizontal, iPad ? 200 : 0)
.onTapGesture {
self.haptics.notificationOccurred(.success)
if cardPosition == .dynamicBottom {
cardPosition = topCardPosition
} else {
cardPosition = .dynamicBottom
}
}
},
mainContent: {
VStack {
ItemContentBox(item: am.dailyItem, scroll: true)
ItemButtonRow(item: am.dailyItem, bottomPadding: 10, showShareSheet: $showShareSheet)
}
.padding(.top, 10)
.padding(.horizontal, 25)
.padding(.horizontal, iPad ? 200 : 0)
}
)
.enableBackgroundBlur(cardPosition == topCardPosition ? true : false)
.backgroundBlurMaterial(.dark(.thick))
.showDragIndicator(true)
.enableFlickThrough(false)
.customBackground(
HStack {
Spacer(minLength: iPad ? 150 : 0)
Color("background")
.opacity(0.95)
.cornerRadius(30, corners: [.topLeft, .topRight])
.shadow(color: .black.opacity(0.1), radius: 10, x:0, y: -2)
Spacer(minLength: iPad ? 150 : 0)
}
)
.enableFloatingIPadSheet(false)
.sheetWidth(iPad ? BottomSheetWidth.relative(1) : BottomSheetWidth.platformDefault)
}
.overlay(Color.black.opacity(showShareSheet ? 0.8 : 0))
.animation(.easeInOut(duration: 0.2), value: showShareSheet)
.sheet(isPresented: $showShareSheet) {
ItemShare(item: am.dailyItem)
.presentationDetents([.height(650)])
}
.toastDimmedBackground(true)
// Refresh view when moving from a different screen
.onAppear {
print("DailyItemView: onAppear")
am.getDailyItem()
}
// Refresh view when restoring from background
.onChange(of: scenePhase) { newScene in
switch newScene {
case .active:
print("Active scene")
am.getDailyItem()
case .inactive:
print("Inactive scene")
am.getDailyItem()
case .background:
print("Background scene")
@unknown default:
print("Unknown scene")
}
}
}
}

