SwiftUI: fullScreenCover with no animation?
A possible solution is to disable views animation completely (and then, if needed, enable again in .onAppear
of presenting content), like
Button(action: {
UIView.setAnimationsEnabled(false) // << here !!
showModal.toggle()
}) {
and then
}, content: {
VStack {
Text("Here I am")
TheFullCover()
}
.onAppear {
UIView.setAnimationsEnabled(true) // << here !!
}
})
Tested with Xcode 13 / iOS 15
SwiftUI: show fullScreenCover without animation
Based on your comment on the @AlexanderThoren answere. I added down animation and also simplify the code.
Add a transition animation.
Add this extension to hide - show view.
extension View {
func showLockView(isLocked: Binding<Bool>) -> some View {
ZStack {
self
if isLocked.wrappedValue {
LockScreen(isLocked: isLocked).animation(.default).transition(AnyTransition.move(edge: .bottom))
}
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
}
}
And use it with your content view
struct ContentView: View {
@State var isLocked = true
var body: some View {
VStack {
Text("Unlocked view")
.padding()
}
.showLockView(isLocked: $isLocked) // << Here
}
}
Edit : As mentioned in the comment, here is the solution without View extension.
struct ContentView: View {
@State var isLocked = true
var body: some View {
ZStack {
VStack {
Text("Unlocked view")
.padding()
}
if isLocked {
LockScreen(isLocked: $isLocked)
.edgesIgnoringSafeArea(.all)
.animation(.default)
.transition(AnyTransition.move(edge: .bottom))
}
}
}
}
SwiftUI: How to present a FullScreenCover Sideways
Use overlay
with animation
Parent view
struct ContentView: View {
@State var isShowSheet: Bool = false
var body: some View {
VStack{
Button("Show Sheet") {
withAnimation {
isShowSheet.toggle()
}
}
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
.overlay(isShowSheet ? FullScreen(isShowSheet: $isShowSheet.animation()) : nil)
}
}
FullScreen view
struct FullScreen: View {
@Binding var isShowSheet: Bool
var body: some View {
Color.blue
.transition(.move(edge: .leading))
.onTapGesture {
isShowSheet = false
}
.edgesIgnoringSafeArea(.all)
}
}
The second option is to use UIViewController with custom animation.
I have use viewControllerHolder extesion from this link (// https://stackoverflow.com/a/58494173/14733292) and added CATransition()
struct ViewControllerHolder {
weak var value: UIViewController?
}
struct ViewControllerKey: EnvironmentKey {
static var defaultValue: ViewControllerHolder {
return ViewControllerHolder(value: UIApplication.shared.windows.first?.rootViewController)
}
}
extension EnvironmentValues {
var viewController: UIViewController? {
get { return self[ViewControllerKey.self].value }
set { self[ViewControllerKey.self].value = newValue }
}
}
extension UIViewController {
func present<Content: View>(style: UIModalPresentationStyle = .automatic, @ViewBuilder builder: () -> Content) {
let toPresent = UIHostingController(rootView: AnyView(EmptyView()))
toPresent.modalPresentationStyle = style
toPresent.rootView = AnyView(
builder()
.environment(\.viewController, toPresent)
)
self.presentController(toPresent)
}
func presentController(_ viewControllerToPresent: UIViewController) {
let transition = CATransition()
transition.duration = 0.25
transition.type = CATransitionType.push
transition.subtype = CATransitionSubtype.fromLeft
self.view.window?.layer.add(transition, forKey: kCATransition)
present(viewControllerToPresent, animated: false)
}
func dismissController() {
let transition = CATransition()
transition.duration = 0.25
transition.type = CATransitionType.push
transition.subtype = CATransitionSubtype.fromRight
self.view.window?.layer.add(transition, forKey: kCATransition)
dismiss(animated: false)
}
}
ContentView and FullScreen
struct ContentView: View {
@Environment(\.viewController) private var viewControllerHolder: UIViewController?
var body: some View {
VStack{
Button("Show Sheet") {
viewControllerHolder?.present(style: .overFullScreen, builder: {
FullScreen()
})
}
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
}
}
struct FullScreen: View {
@Environment(\.viewController) private var viewControllerHolder: UIViewController?
var body: some View {
Color.blue
.onTapGesture {
viewControllerHolder?.dismissController()
}
.edgesIgnoringSafeArea(.all)
}
}
How can I animate transition of a view insertion/removal? Insertion animation doesn't work
Well, ok, it is just observation from the SwiftUI Preview history and until now (can't say what will be in the next version), but - transitions do not work properly in Preview at all (static or Live - it looks like limitation, so just don't test them there.
Test transitions either on standalone Simulator or, what is preferable, on Real Device.
Related Topics
Swift Set UIbutton Setbordercolor in Storyboard
Argument of '#Selector' Does Not Refer to an '@Objc' Method (Swift 3)
How to Convert String to Date Without Time in Swift 3
Implementing Undo and Redo in a UItextview with Attributedtext
Scenekit Ar Game Fps Getting Low and The Device Getting Hot with Use
Shortest Code to Create an Array of Random Numbers in Swift
How to Upload Images from The Browser to Amazon S3 Using Vapor and Leaf
Using Auto Layout to Orientate Stack Views Vertically in Portrait and Horizontally in Landscape
How to Use This Fetchrequest() in Swift
Siblings Relationship Between Same Models in Vapor
How to Delay a Return-Statement in Swift
How to Synchronize Access to a Property That Has Didset
User Already Authenticated in App and Firebase Realtime Database Returns Failed: Permission_Denied
How to Fill Triangle in Swift Using Core Graphics
Passing Values Between Viewcontrollers Based on List Selection in Swift
Error: Variable with Getter/Setter Cannot Have an Initial Value