SwiftUI如何在横屏和竖屏中重新排序

3
我们使用自定义的 gridView 来以网格形式显示所有产品。问题在于,如果设备处于横向或纵向方向,我们需要重新排序。
我们该怎么做呢?
ModularGridStyle(columns: 2, rows: 3)

当设备处于横屏状态时,列和行需要不同。

这是视图:

var body: some View {
Grid(self.products) { product in
                    Text("\(product.name)")

                }
                .gridStyle(
                    ModularGridStyle(columns: 2, rows: 3)
                )
}

这个回答解决了你的问题吗?SwiftUI在设备旋转时重新绘制视图组件 - Chris
4个回答

3
我会使用verticalSizeClass
@Environment(\.verticalSizeClass) private var verticalSizeClass: UserInterfaceSizeClass?

var body: some View {
    Grid(self.products) { Text(verbatim: "\($0.name)") }
        .gridStyle(
            ModularGridStyle(
                columns: self.verticalSizeClass == .compact ? 3 : 2, 
                rows: self.verticalSizeClass == .compact ? 2 : 3
            )
        )
    }
}

2

我个人更喜欢使用GeometryReader来设置不同的视图,以适应纵向和横向。当然,这有点冗余,但通常你还有其他属性也会随之改变:

var body: some View {
    GeometryReader() { g in
        if g.size.width < g.size.height {
            // view in portrait mode
            Grid(self.products) { product in
                Text("\(product.name)")
            }
            .gridStyle(
                ModularGridStyle(columns: 2, rows: 3)
            )
        } else {
            // view in landscape mode
            Grid(self.products) { product in
                Text("\(product.name)")
            }
            .gridStyle(
                ModularGridStyle(columns: 3, rows: 2)
            )
        }
    }
}

0

我正在寻找一种更简单优雅的解决方案 -

并在hackingwithswift中找到了这段代码。

// Our custom view modifier to track rotation and
// call our action
struct DeviceRotationViewModifier: ViewModifier {
let action: (UIDeviceOrientation) -> Void

    func body(content: Content) -> some View {
      content
        .onAppear()
        .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
            action(UIDevice.current.orientation)
        }
    }
}



// A View wrapper to make the modifier easier to use
extension View {
    func onRotate(perform action: @escaping (UIDeviceOrientation) -> Void) -> some View {
        self.modifier(DeviceRotationViewModifier(action: action))
    }
}


// An example view to demonstrate the solution
struct ContentView: View {
@State private var orientation = UIDeviceOrientation.unknown

var body: some View {
    Group {
        if orientation.isPortrait {
            Text("Portrait")
        } else if orientation.isLandscape {
            Text("Landscape")
        } else if orientation.isFlat {
            Text("Flat")
        } else {
            Text("Unknown")
        }
    }
    .onRotate { newOrientation in
        orientation = newOrientation
    }
}
}

0
这里是可能的方法:
private var deviceOrientationPublisher = NotificationCenter.default.publisher(for:
    UIDevice.orientationDidChangeNotification)

@State var dimention: (Int, Int) = (2, 3)
var body: some View {
    Grid(self.products) { product in
        Text("\(product.name)")

    }
    .gridStyle(
        ModularGridStyle(columns: dimention.0, rows: dimention.1)
    )
    .onReceive(deviceOrientationPublisher) { _ in
        self.dimention = UIDevice.current.orientation.isLandscape ? (3, 2) : (2, 3)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接