常见交互

使用表达式和变量 4步完成搜索框

通过使用ProtoPie的"indexOf"和"lowerCase"函数,来制作一个功能齐全的搜索框。

Jeff Clarke, UX Designer & ProtoPie Educator

August 13, 2023

使用表达式和变量 4步完成搜索框

介绍

搜索功能是每一个数字体验中必不可少的交互体验,您可能也需要进行这类原型设计。然而,大多数原型设计工具无法实现真正的搜索功能,因此作为设计师,我们经常通过展示一些截图来模拟各种搜索结果。

💡 在 ProtoPie 中不存在这种限制!

ProtoPie领先的零代码概念模型,让做出一个功能性齐全的搜索交互变得快速简单。此外,虽然许多原型设计工具都具有创建组件以重复使用的功能,但ProtoPie更进一步,允许您重复使用交互和逻辑,这对本教程非常重要。
0

您将学到什么

通过这篇ProtoPie教程,您将学到:
  • 如何使用已内置的 indexOf()lowerCase() 函数。
  • 如何使组件之间以及组件与场景之间进行通信。
  • 如何在组件中构建可重复使用的逻辑。
  • 如何快速简单地创建一个有效的搜索体验。**我相信!**您会惊讶于这是多么容易做的事情!
完成时间:≤15分钟

开始之前

打开无交互的原型文件。这是一个音乐应用的交互原型,其中包含8首歌曲列表,列表的顶部是搜索框。列表中的每首歌曲都是一个名为”Song”组件的子版组件,由于每首歌曲的图层结构相同,因此使用了组件功能。这样就不需要分别制作8次,而只需制作一个组件,然后在场景中使用8个其子版组件,并分别设置了每个子版组件的封面、歌曲标题和艺术家。
我们将分别在场景及”Song”组件的子版组件中进行操作,使我们的搜索功能正常工作。

分步说明

第一步:设置搜索

首先在主场景中,为搜索框添加一些交互。
  • 添加一个「监听」触发,对象设置为搜索框的输入图层 Search field 并选择监听文本
1
  • 添加一个「发送」反应,设置渠道为”发送至当前场景(Send to Current Scene)”。在信息中填写SEARCH,并勾选”同时发送数据(Send Value Together)”,再填写表达式 `Search field`.text
2

💡 发生了什么?

每当搜索框里的文本属性发生变化时,就会触发「监听」。每次按键时,信息 SEARCH 与搜索框的内容将被一起发送到场景中。任何设置了监听此消息的内容都将接收到它,并可以对其做出反应。我们接下来将执行此操作!
将歌曲列表中的每个项目都制作为组件的好处是,可以将逻辑放在主控组件中,而这个设置将包含在所有子版组件中。通过这种方式,可以使每个组件独立负责确定是否与搜索匹配。
  • 进入组件 Song 的主控组件
3
现在我们正在编辑组件 Song 的主控组件,在这里进行的任何工作都将自动复制到主场景中的所有子版组件中。使组件对 SEARCH 消息做出反应。
  • 添加一个「接收」触发,设置渠道为”从当前场景接收(Receive from Current Scene)”。在信息中填写SEARCH,并勾选“赋值给变量(Assign to Variable)”。组件中目前不存在任何变量,因此需要创建一个变量。
4
💡 在设置「接收」触发时,接收的信息和渠道必须与相应的「发送」反应中使用的内容一致。
  • 在组建中创建一个变量命名为 searchKeyword,并设置类型为文本
5
  • 回到上一步创建的「接收」触发,在“选择一个变量(Assign to Variable)“菜单中选择刚才新创建的变量 searchKeyword
6
💡 每当Pie接收到一个带有值的消息时,需要先将该值分配给一个变量,然后才能对其进行操作。这就是选择“选择一个变量”操作的原因。

第二步:在搜索框中显示结果

我们已经设置了组件Song来接收来自场景的搜索关键字。现在我们要想确定关键字是否与歌曲标题的任何部分相匹配。
我们将在「条件」中使用ProtoPie内置的 indexOf() 函数。indexOf()函数用于查找文本中是否存在某些文本。它有两个参数:sourcesearchValue
  • source 是想要搜索的文本,例如本示例中的歌曲标题。
  • searchValue 是在 source 中要查找的关键字。这将是我们传递给变量 searchValue 的值。
当我们执行 indexOf() 时,它会返回一个数字,指示找到的文本的位置。如果没有找到匹配项,则返回 -1。有两种可能性:
  • 如果函数返回的值是 -1,这意味这首歌曲与我们的搜索不匹配,因此应从搜索结果中排除。
  • 如果函数返回除 -1 之外的任何值,则表示该歌曲与我们的搜索匹配,应包含在结果中。

一起看看 indexOf() 的作用!

  • 在组件Song的主控组件中,在**「接收**」触发下添加一个**「**条件」。
  • 在条件中检查第一种可能性 - 不匹配。
  • 在第一个下拉菜单中选择 “表达式"。
  • 表达式填写:indexOf('Title'.text, searchKeyword)
  • 选择 =(等号),并在底部框中输入数值 -1
7
💡 通过运算符可以指示ProtoPie如何进行比较。条件属性栏中展示的 > ≥ < ≤ = ≠ 是ProtoPie中可用的所有运算符。
  • 当没有匹配时,则隐藏歌曲。在**「条件」下添加一个「透明度**」反应并选择图层 Song - 即组件的顶级容器。将透明度设置为 0,持续时间设置为 0。将持续时间设置为 0可以确保透明度发生时不是动画效果,而是立即发生。
8
现在需要处理第二种可能性,即存在搜索匹配时。
  • 再添加一个「条件」,填写相同的公式:indexOf('Title'.text, searchKeyword)
  • 这次选择 (不等于)运算符,数值填写 -1
9
重新命名「条件」,以便使设置更清晰明了。
  • 双击第一个「条件」,并将其重命名为 NO MATCH 不匹配
  • 双击第二个「条件」,并将其重命名为 MATCH 匹配。
10
此时,应该就有一个可以工作的搜索功能了。让我们返回到主场景。
  • 打开预览原型。当您输入文本时,可以看到不符合搜索条件的歌曲消失,如果你删除文本,它们就会重新出现。
11
只需几个简单的步骤,就已经创建了一个可工作的搜索体验的基础!
它确实有效,但您可能已经注意到了一个问题。如果用大写字母“C”搜索,会显示三首歌曲。然而,如果使用小写“c”进行搜索,则找不到任何结果。
11
让我们来解决这个问题吧!

第三步:使搜索不区分大小写

在使用 indexOf() 函数时,大小写很重要。对于该函数而言,Cc 是不同的。然而,如果我们不对此进行修改的话,用户体验将会很差。
为了解决这个问题,需要从方程中去除大小写敏感性。我们的方法是在执行 indexOf() 函数之前,将搜索关键词歌曲标题都转换为小写。
我们可以使用ProtoPie已内置的函数 lowerCase()。顾名思义,它可以将文本转换为小写形式。例如,lowerCase("ProtoPie is the BEST!!") 将会得到 protopie is the best!!

一起看看 lowerCase() 的作用!

回到场景,修改「监听」触发下的**「发送**」反应。
  • 修改同时发送数据的表达式,使用 lowerCase() 函数,将表达式修改为:lowerCase('Search field'.text)。这样就可以确保所有组件都能接收到搜索框中输入的小写形式。
12
💡 请注意 lowerCase() 函数名称中的大写"C"。函数名称也是区分大小写的。如果不小心使用了小写"c"的名称 lowercase(),该表达式将无法正常工作。
在执行 indexOf() 之前,需要对歌曲标题执行相同的操作。
  • 再次编辑组件 Song 的主控组件。
  • 修改两个「条件」。点击第一个条件」,并将表达式修改为:indexOf(lowerCase('Title'.text), searchKeyword)
12
💡 发生了什么?
函数可以嵌套在另一个函数中,并可以作为另一个函数中的参数使用。
由于 indexOf()函数需要用文本作为第一个参数,因此我们可以使用任何输出文本的函数,而 lowerCase() 就是这样的一个函数!当函数像这样嵌套时,先执行嵌套在里面的函数,然后执行外面的函数。这样 indexOf() 则在歌曲标题转换为小写时进行匹配。
  • 对第二个「条件」的表达式进行相同的修改。
13
回到场景并再次预览原型。现在您的搜索应该不区分大小写的了。

第4步:折叠结果

搜索功能已经完全实现了,但是在不匹配搜索的歌曲位置上留下了空白区域。我们希望在显示结果时将其折叠起来。
就像能够从场景向组件发送消息一样,组件也可以相互发送消息。但在此之前,需要修改组件以便它们可以互相区分。
  • 编辑组件 Song 的主控组件。
  • 创建一个名为id的变量,类型为数字。勾选”该变量在子版组件中可被覆写”。
14
💡 通过勾选”该变量在子版组件中可被覆写”,场景中的每个子版组件都可以具有不同的 id 值。
  • 回到场景,每个 Song 子版组件的右侧属性面板中都可以设置"覆写内容(Overrides)",我们可以在这里对新创建的 id 变量进行编辑。
14
  • 为每个子版组件分配不同的 id 值,最好使用连续的数值。
    • 例如,将第一项 "The Celebrated Ways" 的值设置为 1
    • 将第二项 "Feel Again" 的值设置为 2
    • 将第三项 "Good Enemy" 的值设置为 3
    • 以此类推。
15

💡这种连续编号对于逻辑非常重要。

幸运的是,子版组件的图层名称对应 id 值。请再次确认 Song 1 对应 id:1Song 2 对应 id:2,以此类推,直到 Song 8

现在让我们创造奇迹吧!

  • 再次编辑Song主控组件。
  • “NO MATCH”条件」下添加一个「发送」反应,设置渠道为“发送至当前场景”,信息填写 REORDER。勾选“同时发送数据”,并在下方出现的输入栏中使用 id
16
  • 创建一个新的变量并命名为 hiding_id,设置为数字类型。
18
  • 在“NO MATCH”「条件」下添加一个「发送」反应,
  • 添加一个「接收」触发,设置渠道为”从当前场景接收(Receive from Current Scene)”。信息填写 REORDER,勾选“赋值给变量(Assign to Variable)”。
  • 选择赋值给新创建的变量 hiding_id
18

在继续之前,有必要指出接下来会发生什么。

我们在“NO MATCH”「条件」中使用了一个「发送」反应来传播消息 REORDER。如果组件之间能够交流,那么这个特定的Song子版组件将告诉所有其他子版组件:“我是id: x。我与搜索不匹配,所以我要隐藏起来。其他组件请按照顺序重新排列。”
在这一点上,Song组件的所有子版组件都将接收到该消息,包括发送消息的子版组件。我们还发送了最初发送消息的组件 id,并赋值给变量 hiding_id。在「接收」触发中,每个子版组件将比较自己的 idhiding_id 是否相同。

关键部分如下:

如果接收方的id大于发送方的id(即 id>hiding_id),那么我们将把接收方的位置向上移动一个槽。这就是为什么在给每首歌曲赋予 id值时,需要使用顺序编号的原因。

一起看看它的实际操作

  • 在「接收」触发下添加一个「条件」,在第一个下拉菜单中选择变量 id,点击 >(大于)运算符。在下拉菜单中选择变量 hiding_id
19
  • 在「条件」下添加一个「移动」反应,坐标为选择“每次移动(Move By)”,并在 Y 坐标中输入 -84。最后,将持续时间设置为 0,以确保移动时不会有动画效果。
20
这就是我们需要做的全部事情!回到场景并预览原型,您的搜索功能应该可以完全正常工作了!

为什么这样做?

如果您对设置方法还有一些困惑,让我们回顾一下逻辑。如果您已经完全理解了以上内容,可以直接跳过这部分。
隐藏、重置和重新排序发生在每次按键时发生
每次在搜索框中输入一个字母时,每个组件都会判断它是否与搜索匹配,并不记得以前是否匹配。如果匹配,组件会重置自身的位置和透明度,即使它已经可见并处于原始位置。如果不匹配,组件会隐藏自身,即使它已经隐藏了。任何隐藏其自身的组件都会发送消息 **REORDER** 及其 **id**,所有位于其下方的组件(即 id 大于隐藏组件的组件)会向上移动 84 像素。
看一个例子。只考虑前三首歌曲,忽略其他的。
  1. “The Celebrated Ways”
  2. “Feel Again”
  3. “Good Enemy”
假设用户在搜索框中输入字符 n。会发生以下情况:
  • 歌曲 1 不匹配并隐藏自身。
  • 歌曲 1 向所有组件发生消息 REORDER,并附带其 id 值。
  • 歌曲 2 匹配并重置自身。
  • 歌曲 2 接收到来自歌曲 1 的 REORDER,并向上移动到第一个位置。
  • 歌曲 3 匹配并重置自身。
  • 歌曲 3 接收到来自歌曲 1 的 REORDER,并向上移动到第二个位置。
现在假设用户继续在搜索框中输入,接下来输入的字符是 e,搜索词变为 ne。会发生以下情况:
  • 歌曲 1 不匹配并隐藏自身,即使它已经是隐藏状态。
  • 歌曲 1 向所有组件发送消息 REORDER
  • 歌曲 2 不匹配并隐藏自身。
  • 歌曲 2 向所有组件发送消息 REORDER
  • 歌曲 2 接收到来自歌曲 1 的 REORDER,并向上移动到第一个位置,但由于它是隐藏的,我们看不到它。
  • 歌曲 3 匹配并重置自身,将其移回原始位置 3。
  • 歌曲 3 接收到来自歌曲 1 的 REORDER,并向上移动到第二个位置。
  • 歌曲 3 还接收到来自歌曲 2 的 REORDER,并再次移动到第一个位置。

这就是全部内容!很简单!

在创建功能性的搜索体验中,您已经成功地使用了ProtoPie的许多强大功能:
  • 函数和表达式
    • 学会了如何使用 indexOf()lowerCase() 函数
    • 学会了如何将它们嵌套在一个公式中,以进行复杂的信息处理
  • 发送和接收
    • 使用发送和接收功使场景能够与所有组件进行通信,并使组件能够相互通信。
  • 功能组件
    • 组件不仅在视觉设计上可重复使用,而且在功能上也可以重复使用!实际上,歌曲组件几乎完成了原型交互体验的所有工作。
最重要的是,我们希望您意识到这样的工作是多么容易。只涉及了几个内置函数,最重要的是 — 无需写代码!
祝您愉快地进行原型设计!