Ações rápidas da tela inicial para iOS

As Ações Rápidas são uma ótima maneira de dar aos usuários acesso rápido aos recursos usados ​​com frequência do seu aplicativo na tela inicial. O iOS 13 introduziu o conceito de ações rápidas, onde os usuários podem tocar e segurar um ícone de aplicativo para revelar um conjunto de atalhos ou ações a serem executadas diretamente na tela inicial.

Por padrão, todos os aplicativos têm atalhos para editar a tela inicial ou excluir aplicativos:


O menu que aparece depois de pressionar o ícone do aplicativo "Note Buddy" na tela inicial contém opções para "editar" a tela inicial ou "excluir" o aplicativo.

Os desenvolvedores também podem fornecer suas próprias operações de atalho, fornecendo aos usuários atalhos poderosos para funções de aplicativos usadas com frequência. O aplicativo da câmera do iOS possui ações para tirar diferentes tipos de fotos ou gravar vídeos. Um aplicativo de compras pode permitir que você vá direto para seu pedido ou lista de desejos, enquanto um aplicativo de mensagens pode mostrar seus contatos favoritos para que você possa acessá-los facilmente.

Tenho certeza de que você pode encontrar maneiras de agir rápido para beneficiar seus usuários. Neste tutorial você vai aprender:

  • Ações rápidas estáticas , sempre disponíveis para seu aplicativo.
  • Ações rápidas dinâmicas que seu aplicativo pode definir em tempo de execução.
  • Como dar suporte a ambos os tipos de ações rápidas em um projeto de amostra, um aplicativo de anotações chamado Note Buddy .

começando

Note Buddy é um aplicativo de anotações com alguns recursos básicos:

  • Adicione, edite ou exclua notas com título e corpo.
  • Favoritar uma nota.
  • Armazene suas notas entre os lançamentos.
  • Classifique automaticamente as notas pela data da última modificação.

Abra o projeto, então compile e execute. Você verá esta página de anotação:


Captura de tela do item de inicialização "Note Buddy" após o primeiro lançamento mostrando a lista de notas padrão e a opção de criar uma nova nota.

Para aprimorar a funcionalidade do Note Buddy, você pode encontrar modelos e suas classes associadas no grupo Modelos . **NoteNoteStore

Indo para SwiftUI, no grupo Views você tem:

  • NoteList: Exibe uma lista de todas as notas classificadas pela data da última modificação.
  • NoteRow: Visualização da linha de notas na lista de notas. Mostra o título, o corpo da nota e se o usuário a marcou como favorita.
  • EditNote: Um editor para modificar o título, o corpo da nota ou alterar o status do favorito.
  • NavigationLink+Value: uma extensão auxiliar que torna a navegação programática um pouco mais fácil quando você tem um modelo de dados associado para enviar.

最后,AppMain通过引用NoteStore和主体来描述您的应用程序,该主体在 a 中设置NoteList视图WindowGroup并正确注入适当的环境值。

在开始编码之前,是时候仔细看看这两种类型的快速操作是什么,以及它们是如何工作的。

静态与动态快速操作

您可以使用两种类型的快速操作:静态和动态。

您将静态操作用于在您的应用程序中永远不会更改的操作,例如邮件应用程序的新消息操作。

如果您的操作可能在某些条件下发生变化或取决于特定数据或状态,请使用动态操作。例如,消息应用程序将为您所有固定的对话添加快速操作。

在这两种情况下,您都添加代码来处理触发的特定操作。由于添加静态快速操作更快,您将从这些开始。

创建静态快速操作

静态快速​​操作是让您的用户创建新笔记的好方法。

Um emoji de papel com uma carinha sorridente.

首先,添加模型代码以帮助您处理触发的操作。右键单击Models组,然后单击New File...  ▸ Swift File。将新文件命名为Action并单击Create

将文件内容替换为:

导入 UIKit

// 1
枚举动作类型:字符串 {
  case newNote = "NewNote"
}

// 2
枚举行动:平等{
  案例新注

  // 3
  init?(shortcutItem: UIApplicationShortcutItem) {
    // 4
    守卫让 type = ActionType(rawValue:shortcutItem.type) else {
      返回零
    }

    // 5
    开关类型{
    案例.new注意:
      自我 = .newNote
    }
  }
}

// 6
类 ActionService: ObservableObject {
  静态让共享 = ActionService()

  // 7
  @Published var 动作:动作?
}

很多事情正在发生。这是您添加的内容:

  1. 您创建一个ActionTypeString. 稍后您将使用字符串值来帮助识别您的应用将执行的不同类型的操作。该newNote案例将确定创建新注释的操作。
  2. 您创建另一个名为的枚举Action,看起来相似,但只是Equatable. 这可能看起来有点重复,但是当您稍后添加其他操作时它会很有意义。
  3. 然后创建一个可失败的初始化程序,它接受UIApplicationShortcutItem. 系统使用这种类型来描述不同的快速动作。
  4. 在这里,您确保您正在创建Action一个已知的ActionType,否则您返回nil
  5. 打开ActionType您的应用程序已知的不同可能值。然后,您可以使用可用的信息来描述正确的Action.
  6. 定义一个ObservableObject类,您可以稍后将其传递到 SwiftUI 环境中,并为您以后使用 UIKit 代码提供一个单例访问器。
  7. 定义一个@Published可以表示您的应用应执行的操作的属性。

Action概念的目的是让您对应用支持的快速操作进行建模,并在UIApplicationShortcutItem.

现在,打开AppMain.swift。在上面noteStore,添加一个新属性ActionService

私有让 actionService = ActionService.shared

然后更新body实现以确保服务被注入到视图层次结构中并且NoteList可以访问它:

var body: 一些场景 {
  窗口组 {
    笔记列表()
      .environmentObject(actionService)
      .environmentObject(noteStore)
      .environment(.managedObjectContext, noteStore.container.viewContext)
  }
}

ActionService在 SwiftUI 环境中可用,是时候使用它了。在Views组中打开NoteList.swift并在下面添加以下属性:**noteStore

@EnvironmentObject var actionService: ActionService
@Environment(.scenePhase) var 场景相位

您不仅要访问ActionService该类,还需要访问ScenePhase,这是一个属性,当您的应用程序变为活动状态和进入后台时会通知您。

在视图的底部,添加以下方法:

func performActionIfNeeded() {
  // 1
  守卫让行动 = actionService.action else { return }

  // 2
  切换动作{
  案例.new注意:
    创建新笔记()
  }

  // 3
  actionService.action = nil
}

这个方法做了三件事:

  1. 检查ActionService.
  2. 打开动作类型并调用 的createNewNote()动作Action.newNote
  3. 从执行后删除操作ActionService

每当您的应用程序处于活动状态时,您都需要触发此代码。您将onChange(of:perform:)视图修饰符与scenePhase您之前添加的属性一起使用。

toolbar在修饰符的右大括号后添加以下代码:

// 1
.onChange(of: scenePhase) { newValue in
  // 2
  切换新值 {
  案例.活动:
    执行ActionIfNeeded()
  // 3
  默认:
    休息
  }
}

在这里,代码:

  1. 将修饰符添加到将在更改List时触发其关闭的修饰符。scenePhase
  2. 使用提供的参数,它会打开该值。如果是.active,它将调用您的新performActionIfNeeded()方法。
  3. 由于您不关心其他状态,例如.inactiveor .background,它不会做任何事情。

修改信息属性列表文件

您将逻辑添加到处理操作的代码中。但在运行应用程序之前,您仍然需要告诉系统您的静态操作。这很简单。

资源组中,打开Info.plist。右键单击顶部的信息属性列表,然后单击 添加行

Key列中,键入Home Screen Shortcut Items,然后按回车键完成编辑。Xcode 自动将Type设置为Array并为您添加一个项目。通过单击 V 形展开元素,您将看到两个嵌套键:


GUI do Info.plist do Xcode mostrando a propriedade Item de atalho da tela inicial e seu valor aninhado padrão

此数组中列出的每个项目代表您的应用支持的单个静态快速操作。使用以下值更新占位符项:

  • 快捷方式项目类型NewNote
  • 标题New Note

除了默认键之外,您还需要添加一个。将鼠标悬停在标题上,然后单击出现的 + 图标。键入UIApplicationShortcutItemIconSymbolName(暂时忽略弹出选项,您必须键入完整的字符串)KeyValuesquare.and.pencil**

以下是每个键的细分:

  • Shortcut Item Type:一个字符串标识符,代表一种独特的操作类型。您可能会注意到这与ActionType.newNote您之前添加的枚举案例的原始值相匹配。这很重要。
  • 标题:当用户点击并按住您的应用程序图标时显示的用户友好标题。
  • UIApplicationShortcutItemIconSymbolName:用于此操作的 SF 符号。您还可以使用UIApplicationShortcutItemIconFile
    捆绑包中可用的图标文件,或UIApplicationShortcutItemIconType一组可用于快速操作的预定义选项。编辑 Info.plist 条目时,可以从下拉列表中选择图标文件和图标类型,但符号选项不是。


GUI do Info.plist do Xcode mostrando a propriedade "Home Screen Shortcut Item" e o valor do atalho "New Note"

您可以在Apple 文档中阅读有关Info.plist中快捷方式项目的附加键。

构建和运行您的应用程序

构建并运行您的应用程序。返回主屏幕并长按 Note Buddy 应用程序图标以查看列表中现在可用的快速操作:


“Note Buddy”的快速操作菜单现在包括“New Note”静态操作

点击新笔记以查看会发生什么:


Note Buddy 中的笔记列表屏幕。

没有什么?!?

嗯,这很奇怪。您添加了一个模型来处理应用程序中的操作,并在Info.plist 中定义了一个静态操作。

那怎么了?

当用户与快速操作进行交互时,系统会告诉您的应用程序,但您尚未对该信息进行任何操作。是时候这样做了!

处理静态快速操作

SwiftUI 尚未提供任何原生机制来响应快速操作的启动事件。因此,这部分需要依赖 UIKit。

右键单击AppMain.swift并选择New File...  ▸ Swift File。将文件命名为AppDelegate并单击Create。将文件内容替换为:

// 1
导入 UIKit

// 2
类 AppDelegate: NSObject, UIApplicationDelegate {
  私有让 actionService = ActionService.shared

  // 3
  功能应用程序(
    _ 应用程序:UIApplication,
    configurationForConnectingconnectingSceneSession: UISceneSession,
    选项:UIScene.ConnectionOptions
  ) -> UISceneConfiguration {
    // 4
    如果让shortcutItem = options.shortcutItem {
      actionService.action = Action(shortcutItem:shortcutItem)
    }

    // 5
    让配置 = UISceneConfiguration(
      名称:connectingSceneSession.configuration.name,
      sessionRole:connectingSceneSession.role
    )
    configuration.delegateClass = SceneDelegate.self
    返回配置
  }
}

// 6
类 SceneDelegate: NSObject, UIWindowSceneDelegate {
  私有让 actionService = ActionService.shared

  // 7
  函数窗口场景(
    _windowScene:UIWindowScene,
    performActionForshortcutItem: UIApplicationShortcutItem,
    completionHandler: @escaping (Bool) -> Void
  ) {
    // 8
    actionService.action = Action(shortcutItem:shortcutItem)
    完成处理程序(真)
  }
}

如果你对 UIKit 不太熟悉,别担心!以下是上述代码的概述:

  1. 导入 UIKit 框架以访问此文件中所需的符号和类型。
  2. 创建一个AppDelegate继承自协议NSObject并符合UIApplicationDelegate协议的命名类。
  3. 实现application(_:configurationForConnecting:options:)挂钩到应用程序准备启动主 UI 时触发的事件。
  4. shortcutItem选项一起打开包装。如果存在,则表明用户正在通过快速操作启动您的应用程序。使用您之前添加的初始化程序将数据映射到 anAction并将其分配给ActionService.
  5. 通过创建适当的UISceneConfiguration对象并返回它来满足方法的要求。
  6. 与第二步类似,创建另一个符合UIWindowSceneDelegate协议的类。
  7. 实现windowScene(_:performActionFor:completionHandler:) 挂钩在您的应用程序启动后用户与快速操作交互时触发的事件,例如,当它在后台时。
  8. 与第四步类似,尝试转换UIApplicationShortcutItem为 anAction并将其传递给ActionService.

最后,您的 SwiftUI 应用需要使用新的AppDelegateSceneDelegate. 因此,在AppMain.swift的 下方actionService,添加以下属性AppMain

@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

是时候再次构建和运行您的应用程序了。返回主屏幕并再次尝试使用您的快速操作:


快速操作启动 Note Buddy 并创建新笔记的动画片段

极好的!您添加了您的第一个静态快速操作。虽然这为许多可能性打开了大门,但您无法使用运行时使用的信息对其进行自定义。这就是动态动作的用武之地。

创建动态快速操作

如果用户想要编辑他们最近的笔记,他们仍然需要打开应用程序,滚动列表以找到它,点击它然后进行编辑。

简化和加快流程会很棒!

Info.plist 中进行静态操作时,您可以在代码中添加所有动态操作。对于 Note Buddy,可能对于您的许多应用程序,这些动态操作将在您的场景阶段更改为background. 因此,在前往主屏幕之前,您可以设置一些操作以在最后修改日期之前编辑最新的笔记。

处理动态快速操作

要添加动态操作,首先向您的ActionTypeAction枚举添加一个新案例。

打开Action.swift并将以下内容添加到ActionType

case editNote = "EditNote"

将以下新案例添加到Action

案例编辑注(标识符:字符串)

这就是为什么ActionType并且Action需要是两个单独的枚举。whileActionType表示不同快速动作类型的标识符,Action表示动作本身。在某些情况下,例如 的情况.editNote,这可以包括其他关联值。

添加新的枚举用例后,您会注意到编译器友好地告诉您,switch 语句init?(shortcutItem:)不再是详尽无遗的。通过将以下情况添加到开关来解决此问题:

案例.edit注意:
  if let identifier = shortcutItem.userInfo?["NoteID"] as? 细绳 {
    self = .editNote(标识符:标识符)
  } 别的 {
    返回零
  }

在这里,您将检查shortcutItem'userInfo字典以获取要编辑的注释的 ID。如果成功,您将.editNote使用关联值初始化操作。否则,初始化程序只是通过返回而失败nil

如果您现在尝试构建项目,您将在NoteList.swift中看到另一个编译失败。转到它,您会发现您还需要在内部实现新的操作处理performActionIfNeeded()

将以下代码添加到 switch 语句中:

case .editNote(let 标识符):
  selectedNote = noteStore.findNote(withIdentifier: 标识符)

构建并运行您的应用程序。然后前往主屏幕,长按 Note Buddy 图标并查看结果:


注意 Buddy 的快速操作菜单,其中只有一个“新笔记”选项。

再一次……什么都没有?

虽然您已经确保快速操作正确传递到您的应用程序,但您仍然没有告诉您的应用程序显示任何动态项目。接下来你会这样做。

添加您的动态快速操作

如前所述,添加动态操作的好地方是应用程序进入后台时。此时,您拥有运行代码所需的所有信息,该代码确定要添加哪些操作,然后添加它们。

由于您已经在观察ScenePhasein NoteList,因此这是更新操作的好地方。但在您这样做之前,您需要创建自己的实例UIApplicationShortcutItem来描述您的动态操作。

前往Note.swift并在文件顶部添加以下导入:

导入 UIKit

Note扩展中,添加以下属性:

// 1
var 快捷方式项:UIApplicationShortcutItem?{
  // 2
  守卫!wrappedTitle.isEmpty || !wrappedBody.isEmpty else { return nil }

  // 3
  返回 UIApplicationShortcutItem(
    类型:ActionType.editNote.rawValue,
    本地化标题:“编辑注释”,
    本地化字幕:wrappedTitle.isEmpty ?包裹体:包裹标题,
    图标:.init(systemImageName:isFavorite?“星”:“铅笔”),
    用户信息: [
      “NoteID”:标识符为 NSString
    ]
  )
}

下面是代码分解:

  1. Note您在called上定义了一个新的计算属性shortcutItem。该属性是可选的,因为您不需要将每个音符都表示为快速操作。

  2. 如果注释没有标题或正文,则返回nil以便不会显示该注释。

  3. 然后你初始化一个新的实例UIApplicationShortcutItem并返回它。

    • 使用 定义的类型,ActionType以便在您稍后读回时与预期值匹配。
    • 提供一个用户友好的标题,就像你在Info.plist 中所做的那样。
    • 要进一步个性化操作,您可以将注释的标题或正文作为快速操作的副标题。
    • 使用适当的 SF 符号来表示该项目是否是收藏夹。
    • 在 中包含唯一标识符,Note以便userInfo您在响应快速操作时知道要编辑哪个注释。

现在您创建了一个属性来为给定的 公开适当的快捷方式Note,导航回NoteList.swift。在下面添加以下方法performActionIfNeeded()

func updateShortcutItems() {
  UIApplication.shared.shortcutItems = notes.compactMap(.shortcutItem)
}

在这里,您压缩映射 notes 数组以生成仅包含非 nil 的数组UIApplicationShortcutItem。然后将此数组分配给UIApplication'sshortcutItems属性,该属性又与您在主屏幕菜单中的静态操作一起可用。

现在,您只需在应用程序进入后台时调用此方法。向上滚动到onChange(of: perform:)您之前添加的修饰符并在 switch 语句中添加以下内容:

案例背景:
  updateShortcutItems()

构建并运行。然后看看有哪些项目可用:


快速操作启动 Note Buddy 并创建新笔记的动画片段

耶!你完成了。

灰色笑脸图释。

对您的笔记进行一些编辑,收藏一些并重复该过程。显示的注释以及订单在您后台运行应用程序时保持完美同步:


演示如何更新快速操作以反映应用内更改的动画剪辑

您可能已经注意到,并非所有笔记都显示出来。iOS 将操作数量限制为仅显示适合屏幕的操作。但是,文档建议您不要专门限制动态操作的计数。相反,像 Note Buddy 那样做。

这样,iOS 将显示它可以适应的所有快速操作。如果未来的更新能够实现更多功能,那就太好了,因为您无需在后台应用程序之前推出应用程序更新来支持添加更多操作。

结论

有了它:您已准备好为您的应用程序和项目添加快速操作。

点击下载项目资料与查看原文

这里也推荐一些面试相关的内容!

Guess you like

Origin juejin.im/post/7120863720683208735