- 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/
默认的 interactivePopGestureRecognizer 仅当您在屏幕的左边缘从左向右滑动时才有效。我希望能够通过在屏幕上的任意位置滑动来执行此手势。 Reddit、Slack 和 Tw
在我的应用程序中,我有不同的 Controller 。当我将 controller1 推到导航 Controller 并向后滑动时,一切正常。但是,如果我将导航 controller1 插入 cont
我有一个嵌套在 UINavigationController 中的 View Controller . 我已经实现了 iOS 7 interactivePopGestureRecognizer 以使用
我想知道如何使用可见键盘滑动 ViewController? 在 iOS 7 中,我可以左右滑动 ViewController,但键盘保持不动。 简而言之,我想进入以下状态: 谢谢! 最佳答案 更新:
我的应用左下角有这个自定义后退按钮。当导航堆栈上没有更多的 View Controller 然后只有 Root View Controller 时,按钮向下过渡。现在我介绍了 iOS7 标准的“滑动弹
我的应用程序支持英语和阿拉伯语。 interactivePopGestureRecognizer 在使用英语时可以正常工作,即从左向右滑动时,它会弹出 viewController。但是当我使用阿拉伯
我已经实现了interactivePopGestureRecognizer。它过渡到上一页。但问题是,当转换发生时,如果当前 View Controller 中有一个 UIScrollView,它就会
我有一个 UIScrollView,其框架与包含的 View Controller 相同。 当 ScrollView 的缩放比例大于 1 时,从屏幕左侧 50% 开始从左向右滑动会导致 interac
我在同一个 UINavigationController 上有两个不同的 UIViewControllers。两者都包含一个 tableview。如果第一个 View Controller 上的一个单
在我的 UINavigationController 中,我检查它是否具有属性 interactivePopGestureRecognizer,然后再这样设置: class UINavigationC
我有一个自定义控件,包含一行按钮,模仿标签栏。此控件在 UINavigationController 离开 Root View Controller 时滑出 View ,并在导航到 Root View
我有一个被推送到导航堆栈的 UIViewController。我想扩展标准的 iOS7 交互式平移手势以将此 View Controller 弹出到默认 UIRectEdgeLeft 边界之外,以便用
我有像这张照片这样的屏幕。 HomeViewController 将推送到 maintabbar,一个 tabbar item 将推送到 detailScreen。为什么向后滑动不起作用。我认为这是I
我有一个应用程序,我需要在其中禁用 interactivePopGestureRecognizer,这样我的自定义幻灯片菜单就不会显示。我想我可能已经尝试了 SO 中提到的所有内容,但没有运气。我的
我需要在我的应用程序中禁用 interactivePopGestureRecognizer,我做到了 - (void)viewDidAppear:(BOOL)animated { [super
我正在尝试实现自定义 id 将一个特定的 View Controller 推送到导航 Controller 的导航堆栈时的对象。 但是,我发现这样做会阻止 UINavigation Controlle
如何检测我的 interactivePopGestureRecognizer 是否已完成并将返回(弹出)到先前的 View Controller 或 shift 是否不够。然后当前 View Cont
是否有一个干净的解决方案可以让 View Controller 上的回调或事件被 interactivePopGestureRecognizer 关闭(弹出)? 为了清楚起见,在该手势识别器弹出 Co
我的第一个问题,请温柔... 如果我使用 UIPageViewControllerTransitionStylePageCurl,但不能使用 UIPageViewControllerTransitio
我使用 UINavigationController 的默认实现和从左到右弹出的默认手势 (interactivePopGestureRecognizer)。我怎样才能让 interactivePop
我是一名优秀的程序员,十分优秀!