在跨平台原生 Swift 应用程序中计算 SafeArea 常量

介绍

今天的文章与之前的文章有些不同。我们将研究如何处理与 Android 和 iOS 兼容的 UI 小部件,而不是制作应用程序。一个这样的例子是 SafeArea 常数的计算。

我敢肯定,您一定在移动应用程序开发中遇到过 SafeaArea 概念。使用足够的填充插入其子项以避免操作系统入侵的 UI 小部件称为 SafeArea。但是为什么我们现在要讨论 SafeArea 呢?SCADE 社区报告了一些与 SafeArea 相关的问题,其中 UI 视图超出了可见区域。

在本文中(专门针对 SCADE 爱好者),我们将详细讨论我们如何实现 SafeArea 常量以避免目标设备显示对 UI 视图的任何干扰。

所以让我们开始吧😎。

先决条件

如果您尚未安装 SCADE IDE,请下载SCADE IDE 并将其安装在您的 macOS 系统上。SCADE 的唯一先决条件是 Swift 语言(至少是基础)。此外,如果您想在 Android 设备上运行 SCADE 应用程序,请确保 Android 模拟器或物理设备正在运行。

入门

为简单起见,让我们通过创建一个新的 SCADE 项目来理解概念, 然后选择 SCADE 选项,输入项目名称并单击创建。File -> New -> New Project.

我们将添加 iOS 和 Android 特定的代码来确定安全区域的顶部和底部高度。现在,让我们添加一个标签来main.page显示顶部和底部高度的数值。

iOS 代码

为了计算iOS设备,我们可以使用完全相同的本地swift代码库来查找上下档常量。使用UIApplication的安全区域插入代码库属性。窗口参数,我们可以轻松找到给定iOS设备的顶部和底部填充。

import ScadeKit

let window = UIApplication.shared.windows.first
let topPadding = window?.safeAreaInsets.top ?? 0
let bottomPadding = window?.safeAreaInsets.bottom ?? 0


self.label.text = "iOS, top: \(topPadding) bottom: \(bottomPadding)"

您可以测试上面的代码片段。是的,它有效😀!您可以针对一系列 iOS 设备,并且可以轻松获取这些设备的 SafeArea 常量。

让我们计算一下Android

在开始使用 Android 屏幕的 SafeArea 常量之前,让我们简要讨论一下swift-android编译器。SCADE 开发人员在内部开发了适用于 Android SDK 的 swift 编译器(目前它支持 API 24)。该存储库现在是开源的,任何人都可以使用现有的 Swift 类来开发各种 Android 用例。

我们使用getDimensionPixelSize()方法并传递包含status_bar_height标识符的资源 ID。

int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
int topPadding = getResources().getDimensionPixelSize(resourceId);

类似地,要获得底部缺口值,我们将再次使用相同的方法,但传递包含navigation_bar_height标识符的资源 ID。

int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
int topPadding = getResources().getDimensionPixelSize(resourceId);

这就是我们需要为 Android 做的所有事情。但是等等,我们不能直接将 Java 代码写入我们的 SCADE 应用程序。我们现在需要使用 swift-android 编译器将给定的 Java 代码片段转换为等效的 swift 代码。

用于 Android 代码的 Swift 编译器
swift-android 存储库包含从 Android SDK 生成的 swift 类。我们会将所需的类注入我们的 SCADE 应用程序并相应地实现类似的功能。它大量使用 SPM 将必要的依赖项注入 SCADE 应用程序。

对于上面的 Android 代码片段,我们需要 applicationContext 和 resources 实例来调用必要的方法。我们将以下 Android 包添加到Package.swift.

// swift-tools-version:5.3
import PackageDescription
import Foundation

let SCADE_SDK = ProcessInfo.processInfo.environment["SCADE_SDK"] ?? ""

let package = Package(
    name: "StatusBarMarginCalc",
    platforms: [
        .macOS(.v10_14)
    ],
    products: [
        .library(
            name: "StatusBarMarginCalc",
            type: .static,
            targets: [
                "StatusBarMarginCalc"
            ]
        )
    ],
    dependencies: [
      .package(name: "Android", url: "https://github.com/scade-platform/swift-android.git", .branch("android/24"))        
    ],
    targets: [
        .target(
            name: "StatusBarMarginCalc",
            dependencies: [
                .product(name: "Android", package: "Android", condition: .when(platforms: [.android])),
                 .product(name: "AndroidOS", package: "Android", condition: .when(platforms: [.android])),
                  .product(name: "AndroidApp", package: "Android", condition: .when(platforms: [.android])),
                   .product(name: "AndroidContent", package: "Android", condition: .when(platforms: [.android])),             
            ],
            exclude: ["main.page"],
            swiftSettings: [
                .unsafeFlags(["-F", SCADE_SDK], .when(platforms: [.macOS, .iOS])),
                .unsafeFlags(["-I", "\(SCADE_SDK)/include"], .when(platforms: [.android])),
            ]
        )
    ]
)

下一步,我们现在将为 Android 导入这些包:

import ScadeKit

#if os(Android)
  import Android
  import AndroidApp
  import AndroidContent
#endif

我们现在准备好为上面给定的 java 方法调用各自的 swift 方法。

#if os(Android)

  var res: Resources? = Application.currentActivity?.getResources()

// calling top notch method 
  var resID: Int32 =
    res?.getIdentifier(name: "status_bar_height", defType: "dimen", defPackage: "android") ?? 0
  var topPadding:Int32 = res?.getDimensionPixelSize(id: resID) ?? 0

// calling bottom notch method
  var resBottomID: Int32 =
    res?.getIdentifier(name: "navigation_bar_height", defType: "dimen", defPackage: "android")
    ?? 0
  var bottomPadding: Int32 = res?.getDimensionPixelSize(id: resBottomID) ?? 0


  self.label.text = "Android, Top: \(topPadding) Bottom: \(bottomPadding)"

#endif

让我们了解上面的代码片段以及它的基本作用。为了访问应用程序的资源,我们使用currentActivity返回上下文的实例。使用这个上下文,我们调用 getResources 来全局访问资源。

资源实例将调用 getIdentifier 方法并将 ID 作为 _status_bar_height _ 传递给 top-notch 常量,并将 _navigation_bar height传递 给底部 notch 常量。

👉请注意,如果在意外情况下返回nil ,我们也可以设置默认值。

现在我们可以在 Android 设备上测试代码了。将目标设置为您喜欢的任何 Android 设备并测试它是否按预期工作。


瞧🎊!我们已成功地将 SafeArea 常量集成到我们的 SCADE 应用程序中。使用 swif-android 库将任何特定于 Android 的功能集成到 SCADE 应用程序中非常容易。您绝对应该尝试使用 swift-android 构建一些有用的组件来构建跨平台应用程序。

我们将发布一系列与 swift-android 编译器相关的文章。感谢您的阅读,我们下一篇文章再见!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值