diff --git a/QuickDrop.xcodeproj/project.pbxproj b/QuickDrop.xcodeproj/project.pbxproj index 8a3b13a..a048f6b 100644 --- a/QuickDrop.xcodeproj/project.pbxproj +++ b/QuickDrop.xcodeproj/project.pbxproj @@ -1739,8 +1739,8 @@ MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; - SHARED_BUILD = 128; - SHARED_VERSION = 2.13.2; + SHARED_BUILD = 129; + SHARED_VERSION = 2.13.3; STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = YES; @@ -1802,8 +1802,8 @@ MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = macosx; - SHARED_BUILD = 128; - SHARED_VERSION = 2.13.2; + SHARED_BUILD = 129; + SHARED_VERSION = 2.13.3; STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_EMIT_LOC_STRINGS = YES; diff --git a/QuickDrop/View/Toast/QuickDropToastView.swift b/QuickDrop/View/Toast/QuickDropToastView.swift index 3849931..be3eb71 100644 --- a/QuickDrop/View/Toast/QuickDropToastView.swift +++ b/QuickDrop/View/Toast/QuickDropToastView.swift @@ -259,11 +259,13 @@ struct QuickDropToastHostView: View { @ObservedObject var receiveModel: ReceiveModel let onCancel: () -> Void + @State private var didRenderOnce = false + private let slideAnimation = Animation.smooth private let fadeAnimation = Animation.easeInOut var body: some View { - let isVisible = receiveModel.toastIsVisible + let isVisible = didRenderOnce && receiveModel.toastIsVisible let isSlide = receiveModel.toastDismissStyle == .slide let hiddenOffset: CGFloat = isSlide ? toastSlideDistance : 0 let hiddenOpacity: Double = isSlide ? 1 : 0 @@ -275,9 +277,20 @@ struct QuickDropToastHostView: View { .offset(x: isVisible ? 0 : hiddenOffset) .opacity(isVisible ? 1 : hiddenOpacity) .blur(radius: isVisible ? 0 : hiddenBlur) - .animation(animation, value: receiveModel.toastIsVisible) + .animation(animation, value: isVisible) .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .trailing) .padding(.trailing, toastTrailingPadding) + .onAppear { + // Defer the visibility gate one run-loop tick so initial state is + // always rendered hidden before we animate to visible. + guard !didRenderOnce else { return } + DispatchQueue.main.async { + didRenderOnce = true + } + } + .onDisappear { + didRenderOnce = false + } } }