- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
交互式弹出手势识别器应允许用户在滑动超过一半屏幕(或这些线周围的某些内容)时返回导航堆栈中的上一个 View 。在 SwiftUI 中,当滑动距离不够远时,手势不会被取消。
SwiftUI: /image/shQl8.jpg
UIKit: /image/2EeIS.jpg
<小时/>问题:
使用 SwiftUI View 时是否可以获取 UIKit 行为?
<小时/>尝试
我尝试将 UIHostingController 嵌入 UINavigationController 中,但这提供了与 NavigationView 完全相同的行为。
struct ContentView: View {
var body: some View {
UIKitNavigationView {
VStack {
NavigationLink(destination: Text("Detail")) {
Text("SwiftUI")
}
}.navigationBarTitle("SwiftUI", displayMode: .inline)
}.edgesIgnoringSafeArea(.top)
}
}
struct UIKitNavigationView<Content: View>: UIViewControllerRepresentable {
var content: () -> Content
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
func makeUIViewController(context: Context) -> UINavigationController {
let host = UIHostingController(rootView: content())
let nvc = UINavigationController(rootViewController: host)
return nvc
}
func updateUIViewController(_ uiViewController: UINavigationController, context: Context) {}
}
最佳答案
我最终覆盖了默认的 NavigationView
和 NavigationLink
以获得所需的行为。这看起来很简单,我一定忽略了默认 SwiftUI View 所做的事情?
我将 UINavigationController
包装在一个 super 简单的 UIViewControllerRepresentable
中,它将 UINavigationController
作为环境对象提供给 SwiftUI 内容 View 。这意味着 NavigationLink
稍后可以获取它,只要它位于同一个导航 Controller 中(呈现的 View Controller 不接收环境对象),这正是我们想要的。
注意: NavigationView 需要 .edgesIgnoringSafeArea(.top)
并且我还不知道如何在结构本身中设置它。如果您的 NVC 在顶部切断,请参阅示例。
struct NavigationView<Content: View>: UIViewControllerRepresentable {
var content: () -> Content
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
func makeUIViewController(context: Context) -> UINavigationController {
let nvc = UINavigationController()
let host = UIHostingController(rootView: content().environmentObject(nvc))
nvc.viewControllers = [host]
return nvc
}
func updateUIViewController(_ uiViewController: UINavigationController, context: Context) {}
}
extension UINavigationController: ObservableObject {}
我创建了一个自定义的 NavigationLink,它访问环境 UINavigationController 以推送托管下一个 View 的 UIHostingController。
注意:我没有实现 SwiftUI.NavigationLink 的 selection
和 isActive
,因为我不完全理解它们的含义还没有做。如果您想提供帮助,请发表评论/编辑。
struct NavigationLink<Destination: View, Label:View>: View {
var destination: Destination
var label: () -> Label
public init(destination: Destination, @ViewBuilder label: @escaping () -> Label) {
self.destination = destination
self.label = label
}
/// If this crashes, make sure you wrapped the NavigationLink in a NavigationView
@EnvironmentObject var nvc: UINavigationController
var body: some View {
Button(action: {
let rootView = self.destination.environmentObject(self.nvc)
let hosted = UIHostingController(rootView: rootView)
self.nvc.pushViewController(hosted, animated: true)
}, label: label)
}
}
这解决了向后滑动在 SwiftUI 上无法正常工作的问题,并且因为我使用名称 NavigationView 和 NavigationLink,所以我的整个项目立即切换到这些名称。
在示例中,我也展示了模式表示。
struct ContentView: View {
@State var isPresented = false
var body: some View {
NavigationView {
VStack(alignment: .center, spacing: 30) {
NavigationLink(destination: Text("Detail"), label: {
Text("Show detail")
})
Button(action: {
self.isPresented.toggle()
}, label: {
Text("Show modal")
})
}
.navigationBarTitle("SwiftUI")
}
.edgesIgnoringSafeArea(.top)
.sheet(isPresented: $isPresented) {
Modal()
}
}
}
struct Modal: View {
@Environment(\.presentationMode) var presentationMode
var body: some View {
NavigationView {
VStack(alignment: .center, spacing: 30) {
NavigationLink(destination: Text("Detail"), label: {
Text("Show detail")
})
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}, label: {
Text("Dismiss modal")
})
}
.navigationBarTitle("Modal")
}
}
}
<小时/>
编辑:我一开始就说“这看起来很简单,我一定是忽略了一些东西”,我想我找到了它。这似乎没有将环境对象转移到下一个 View 。我不知道默认的 NavigationLink 是如何做到这一点的,所以现在我手动将对象发送到我需要它们的下一个 View 。
NavigationLink(destination: Text("Detail").environmentObject(objectToSendOnToTheNextView)) {
Text("Show detail")
}
编辑2:
这通过执行 @EnvironmentObject var nvc: UINavigationController
将导航 Controller 公开给 NavigationView
内的所有 View 。解决这个问题的方法是使我们用来管理导航的environmentObject成为一个文件私有(private)类。我在要点中修复了这个问题:https://gist.github.com/Amzd/67bfd4b8e41ec3f179486e13e9892eeb
关于ios - 如何在 SwiftUI 中恢复与 UIKit (interactivePopGestureRecognizer) 中相同的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58234142/
大家好,我正在尝试制作一个具有大量动画和效果的交互式 UI。 但我不知道是否: 核心图形可以支持用户交互(触摸、拖动等) 核心图形支持对象旋转 核心图形可以以任何方式与 UIKit 和核心动画交互 谢
我正在查看 Swift 中的一些 UIKit header ,特别是用于 UIViewController 的 header ,并且有几个函数返回隐式展开的可选值而不是普通的可选值。 例如: //旋转
我正在尝试运行此代码: GetRepsButton.Command = new Command(async () => { var url =
我正在尝试运行此代码: GetRepsButton.Command = new Command(async () => { var url =
从 SwiftUI View 推送到 UIKit 时,导航栏项目不存在或未添加。 我在 Storyboard中添加了一项,在代码中添加了一项,但都没有显示。 这可能是 SwiftUI 中的一个错误,但
嘿,你们这些聪明人; 一个艰难的crash bug 调试了很多天,还是没有找到根本原因,渴望得到您的提示和指导。 它是一个表格 View Controller ,但由于我们在其中添加了许多其他 UI
目前正在尝试打开一个在 Swift 3、Xcode 8.1 中创建的应用程序。我进行了大量研究,删除派生数据并一遍又一遍地清理整个项目。我已将 Xcode 及其语法更新为最新版本。 MapKit 可能
我有一个 View ,其边界设置为碰撞( setTranslatesReferenceBoundsIntoBoundaryWithInsets )和一个带有重力的 subview 设置,以便它可以与
我正在探索 tvOS,我发现 Apple 提供了一套不错的 templates使用TVML编写。我想知道使用 TVML 模板的 tvOS 应用是否也可以使用 UIKit。 我可以在一个应用程序中混合使
在导入我的框架后,需要将 UIKit 显式导入项目中的所有 UIKit 子类。 我决定从我的项目中导出所有 objective-c 类 并制作一个框架。我使用 Google map 框架 创建了该框架
我试图在 playground 中创建一个 UILabel 但失败了。 playground 目前只支持 OS X 开发吗? 最佳答案 是的,确实如此! 文件:新建 > 文件... > iOS > 源
由于 SwiftUI 文本中的一些限制。我必须使用 UIText 代替。 在 UIViewRepresentable 中, func makeUIView(context: Context)
我试图将SubView SwiftUI View 添加到UIView。 self.view.addSubview(contentView) Error: Cannot convert value of
好的,我知道如何使用 UIViewRepresentable 和 Coordinator 包装像 TextField 这样的 UIKit 组件,以便与 SwiftUI 一起使用。一切都运转良好。但是,
UIKit Dynamics 和 UIKit Animation 在动画层面最本质的区别是什么? 关于 UIKit Dynamic 的资料并不多。我对此了解不多。我只知道如何使用它。我认为这个问题与硬
我已经阅读了有关词法和预处理器问题的其他问题,并且我尝试使用有助于解决他们的问题的方法。不幸的是,这些解决方案都无法帮助解决问题。这个错误不知从何而来,我不确定除了阅读之外我还能做什么来解决这个问题。
例如我有以下界面。 #import @interface someClass : NSObject @property (nonatomic, copy) NSString *string; @pro
我多年来一直在与 tableView.performBatchUpdates 的 UIKit 问题作斗争。 我有一个简单的数据模型,其中包含由 tableView 和 tableViewCells 驱
我正在读这个post关于进口,我有一个问题。默认情况下,prefix.pch 文件中的#import 会减慢编译时间吗?我应该删除它并仅在必要时导入吗? #ifdef __OBJC__ #im
我一直在观看一个视频,该视频指出 UIAlertView 仅在导入 UIKit.h 时才有效。但是,如果我在头文件中注释掉 import 语句: //#import @interface ViewC
我是一名优秀的程序员,十分优秀!