SwiftUI:没有动画的全屏覆盖?

zum*_*zum 18 swiftui

我有这样的看法:

struct TheFullCover: View {
    
    @State var showModal = false
    
    var body: some View {
        
        
        Button(action: {
            showModal.toggle()
        }) {
            Text("Show Modal")
                .padding()
                .foregroundColor(.blue)
            
        }
        .background(Color(.white))
        .overlay(
            RoundedRectangle(cornerRadius: 10)
                .stroke(.red, lineWidth:1)
        )
        .fullScreenCover(isPresented: $showModal, onDismiss: {
            
        }, content: {
            VStack {
                Text("Here I am")
                TheFullCover()
            }
        })
        
    }
    
    
}
Run Code Online (Sandbox Code Playgroud)

每次我按下按钮时,模式屏幕都会全屏显示。一切都很好。

问题:

如何禁用向上滑动动画?我希望视图立即全屏呈现,而不需要动画。

有没有办法做到这一点?

asa*_*nko 29

据我所知,截至今天,正确的做法是使用transaction https://developer.apple.com/documentation/swiftui/transaction

var transaction = Transaction()
transaction.disablesAnimations = true
withTransaction(transaction) {
   showModal.toggle()
}
Run Code Online (Sandbox Code Playgroud)

我还为此创建了一个方便的扩展:

extension View {
    func withoutAnimation(action: @escaping () -> Void) {
        var transaction = Transaction()
        transaction.disablesAnimations = true
        withTransaction(transaction) {
            action()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

可以这样使用:

withoutAnimation {
    // do your thing
}
Run Code Online (Sandbox Code Playgroud)


Asp*_*eri 22

一种可能的解决方案是完全禁用视图动画(然后,如果需要,再次启用.onAppear呈现内容),例如

    Button(action: {
        UIView.setAnimationsEnabled(false)    // << here !!
        showModal.toggle()
    }) {
Run Code Online (Sandbox Code Playgroud)

进而

    }, content: {
        VStack {
            Text("Here I am")
            TheFullCover()
        }
        .onAppear {
            UIView.setAnimationsEnabled(true)    // << here !!
        }
    })
Run Code Online (Sandbox Code Playgroud)

使用 Xcode 13 / iOS 15 进行测试


小智 14

.fullScreenCover(isPresented: isPresented) {
    content()
        .background(TransparentBackground())
}
.transaction({ transaction in
    transaction.disablesAnimations = true
})
Run Code Online (Sandbox Code Playgroud)

根据@asamoylenko 的回答,这应该有效

  • 这也会禁用导航链接的推送动画 (5认同)

con*_*gnd 6

目前,我发现在 SwiftUI 中使用 UIKit 进行演示更容易。

someView
  .onChange(of: isPresented) { _ in
    if isPresented {
      let vc = UIHostingController(rootView: MyView())
      vc.modalPresentationStyle = .overFullScreen
      UIApplication.shared.rootVC?.present(vc, animated: false)
    } else {
      UIApplication.shared.rootVC?.dismiss(animated: false)
    }
  }
Run Code Online (Sandbox Code Playgroud)