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

Posted 小陈乱敲代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在跨平台原生 Swift 应用程序中计算 SafeArea 常量相关的知识,希望对你有一定的参考价值。

介绍

今天的文章与之前的文章有些不同。我们将研究如何处理与 androidios 兼容的 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 编译器相关的文章。感谢您的阅读,我们下一篇文章再见!

以上是关于在跨平台原生 Swift 应用程序中计算 SafeArea 常量的主要内容,如果未能解决你的问题,请参考以下文章

Swift 数据类型

云原生在京东丨基于 Tekton 打造下一代云原生 CI 平台

云原生应用保护平台的发展演进脉络

iOS 11 Swift 4 iPhone X Safe Area 支持全屏ScrollView

今日风向标:Intel原生开发套件Clojure 1.7AWS Farm Device

网易伏羲云原生游戏中间件平台实践