SwiftUI 中 UIView readableContentGuide 等价物是什么

use*_*917 6 layout uikit ios swiftui

UIView 的readableContentGuide布局可以与屏幕大小相关,并确保内容始终可读。我在 SwiftUI 中找不到关于这些东西的任何信息。

SwiftUI 中可以使用的等价物是什么?如果没有,我们可以使用 SwiftUI 组件在 UIKit 中构建相同的效果吗?

谢谢。

Dan*_*sko 5

考虑到无限范围的设备宽度,此处建议的填充解决方案没有意义。我们需要一个能够满足所有类型设备尺寸的解决方案,并且可以保留内容的可读宽度。

最终结果可以由任何视图以 SwiftUI 友好的方式使用:

SomeReallyLongView()
    .readableGuidePadding()
Run Code Online (Sandbox Code Playgroud)

首先,我们需要一个ViewModifier可以将视图宽度固定为最大边距的控件。UIKit 实际上将可读内容宽度定义为 672,所以让我们使用它。

SomeReallyLongView()
    .readableGuidePadding()
Run Code Online (Sandbox Code Playgroud)

现在我们有了一个修改器,可以将内容剪辑为 672 点宽,并在需要时使用水平间隔符。请注意,我们使用 minLength 0,否则在较小的屏幕上总会有水平填充。我们不希望这样。

现在我们可以创建一个方便的视图扩展来使用我们的修饰符:

private struct ReadableGuidePadding: ViewModifier {
    func body(content: Content) -> some View {
        HStack(spacing: 0) {
            Spacer(minLength: 0)
            content.frame(maxWidth: 672)
            Spacer(minLength: 0)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

享受


hal*_*gen 5

其他解决方案对我不起作用,因为它们依赖于硬编码的填充量或下拉到 UIKit,这对于需要在所有不同尺寸的 iPhone、iPad、和苹果电脑。因此,由于仍然没有本地 SwiftUI 等效项(截至 iOS 15/macOS 12),我想我应该做一个替代方案。

我的替代方法是根据以下内容计算填充量:

  • 视图的当前宽度
  • 和一些理想的可读宽度
struct ReadabilityPadding: ViewModifier {
    let isEnabled: Bool
    @ScaledMetric private var unit: CGFloat = 20

    func body(content: Content) -> some View {
        // Use a GeometryReader here to get view width.
        GeometryReader { geometryProxy in
            content
                .padding(.horizontal, padding(for: geometryProxy.size.width))
        }
    }

    private func padding(for width: CGFloat) -> CGFloat {
        guard isEnabled else { return 0 }

        // The internet seems to think the optimal readable width is 50-75
        // characters wide; I chose 70 here. The `unit` variable is the 
        // approximate size of the system font and is wrapped in
        // @ScaledMetric to better support dynamic type. I assume that 
        // the average character width is half of the size of the font. 
        let idealWidth = 70 * unit / 2

        // If the width is already readable then don't apply any padding.
        guard width >= idealWidth else {
            return 0
        }

        // If the width is too large then calculate the padding required
        // on either side until the view's width is readable.
        let padding = round((width - idealWidth) / 2)
        return padding
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是它在不同设备上的外观(顶部是正常的,底部是应用了 ReadabilityPadding 视图修饰符的):

截图对比