EasyFocus

================

一种通用的方式,用于在可识别数据模型上实现焦点,并简化对数组中记录的焦点获取和设置,这对于列表尤其有用。

为什么会有这个软件包?

在数据数组上使用开箱即用的 @FocusState 属性包装器意味着使用带有关联值的枚举,正如我们将在下面的两个简单示例中看到的那样,代码会变得有些复杂。

@FocusState 示例

为了从 yourDataArray 中的记录打印文本值,您需要类似下面的代码。

	public enum FocusID : Hashable {
   	case focusID(id: String)
	}
	...
	@FocusState private var focusedID: FocusID?
	...
	case .focusID(let id) = focusedID
	if let id = id,
		let index = yourDataArray.firstIndexOf( where { $0.id = id }) {
  		print(yourDataArray[index].text)
    } else {
    	print("no text")
    }  

相反,要将焦点设置到 YourDataRow 行,您必须使用类似的语法:

	focusedID = .focusID(id: YourDataRow.id)

这还行,还可以接受。 但确实有点乏味和不直观。 应该更容易!

解决方案

这个软件包旨在简化焦点的设置以及从当前聚焦的记录中获取数据。 使用与上面相同的示例,该软件包消除了定义枚举的需要,并将您的数据模型用作 @Focus 属性包装器的目标:

@Focus 示例

	@Focus private var focusedRow: YourDataModel?
	...
	print(focusedRow?.text ?? "no text")

以及将焦点设置到数据记录:

	focusedRow = YourDataRow

现在代码少了很多!(为了简洁起见,我省略了一些代码,但省略不多,也不比开箱即用的 SwiftUI 解决方案所需的更多。) 有关完整的示例,请参见 example.swift 文件,该示例将其列表中的焦点行与视图模型同步。

用法

首先,import EasyFocus

其次,定义您的数据模型,并使其符合 FocusableListRow。 为此,只需添加一个 id 字段,并确保该结构是可哈希的。 例如:

	struct myDataModel : FocusableListRow {
		id: Int
		text: String
	}

然后,定义您的变量来保持焦点:

	@Focus private var focusedRow: YourDataModel?

在您想要设置焦点的数据项上,添加对 .enableFocus 的调用。 例如:

	.enableFocus(on: myDataItem, with: _focusedRow)

您现在可以使用变量 focusedRow 来设置和获取焦点。

结束。