SwiftUI:如何仅在设备处于横向模式时启用 ScrollView?
Posted
技术标签:
【中文标题】SwiftUI:如何仅在设备处于横向模式时启用 ScrollView?【英文标题】:SwiftUI: How to enable ScrollView only when device is in landscape mode? 【发布时间】:2021-04-24 16:05:41 【问题描述】:我正在尝试在应用程序未处于横向模式时禁用滚动视图,但我不知道如何在 SwiftUI 中执行此操作,是否有人对此有解决方案。当设备处于横向模式时,我尝试为轴属性添加空数组,但这不起作用:
ScrollView(axes, showsIndicators: false)
VStack(spacing: 10)
Text("Something 1")
Text("Something 2")
Text("Something 3")
Text("Something 4")
Text("Something 5")
.padding(.top, 10)
///...
private var axes: Axis.Set
return UIDevice.current.orientation.isLandscape ? [] : .vertical
【问题讨论】:
【参考方案1】:Hacking With Swift 中有一些有用的代码可以检测 SwiftUI 中的设备方向变化:https://www.hackingwithswift.com/quick-start/swiftui/how-to-detect-device-rotation
但是,我不得不稍微改变它以获得可靠的第一个值。这是我最终得到的视图修饰符:
struct DeviceRotationViewModifier: ViewModifier
let action: (UIDeviceOrientation) -> Void
func body(content: Content) -> some View
content
.onAppear
action(UIDevice.current.orientation)
.onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification).dropFirst()) _ in
action(UIDevice.current.orientation)
extension View
func onRotate(perform action: @escaping (UIDeviceOrientation) -> Void) -> some View
self.modifier(DeviceRotationViewModifier(action: action))
然后,在您的View
中,您可以有条件地显示ScrollView
或仅显示VStack
,具体取决于此方向:
struct ContentView : View
@State private var orientation = UIDeviceOrientation.unknown
@ViewBuilder var subView : some View
VStack(spacing: 10)
Text("Something 1")
Text("Something 2")
Text("Something 3")
Text("Something 4")
Text("Something 5")
var body: some View
Group
if orientation.isLandscape
VStack
subView
Spacer()
else
ScrollView(.vertical, showsIndicators: false)
subView
.padding(.top, 10)
.onRotate newOrientation in
orientation = newOrientation
【讨论】:
啊,是的,这是一个解决方案,我刚刚在 Hacking With Swift 上找到了这段代码,在我看到你回答之前一分钟,是的,这是一个解决方案,但我认为这有点 hacky,因为我将针对不同的方向显示完全不同的视图,如果有一种方法可以在横向方向禁用滚动视图会更好。但这完全可行,非常感谢您的帮助,我会尝试然后将其标记为一个好的解决方案。 我不会说这是一个完全不同的视图——这就是我将所有常见组件拆分为subView
的原因——它只是一个不同的容器。
在我重定向到选项卡栏中的某些不同视图后,当我在进入横向模式时使用此方法时遇到问题,一切都崩溃了,然后我让一切都像一个完全糟糕的视图一样向上移动,出于某种原因,我认为在重定向到其他视图时必须发送方向属性。当我回去使用 UIDevice.current.orientation.isLandscape 时,一切正常,...
由于某种原因,我发现当设备处于横向模式并且我只是午餐一个应用程序时,即使设备处于横向模式,方向属性也是错误的,我不知道这是为什么,你有什么线索吗?
我发现原始 Hacking with Swift 代码就是这种情况,但不是我的修改版本。【参考方案2】:
有一个禁用的选项,也许你可以使用:
struct ContentView : View
@State private var orientation = UIDeviceOrientation.unknown
var body: some View
ScrollView(.vertical, showsIndicators: false)
VStack(spacing: 10)
Text("Something 1")
Text("Something 2")
Text("Something 3")
Text("Something 4")
Text("Something 5")
.disabled(!orientation.isLandscape)
.padding(.top, 10)
.onRotate newOrientation in
orientation = newOrientation
【讨论】:
我认为这将禁用与滚动视图中的任何子元素的交互,对吧?对于 OP 来说,这可能是也可能不是问题 是的,这可能是个问题以上是关于SwiftUI:如何仅在设备处于横向模式时启用 ScrollView?的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI TabView 与 PageTabViewStyle 在设备上的横向与 safeArea 添加奇数前沿插图