BindKit

一个简单易用的 iOS UIKit 双向数据绑定框架。只需学习一个 API

支持 Objective-C、Swift 5.10、Xcode 15.4、iOS 13+。以静态 XCFramework 形式分发,您可以将其链接到您的应用程序中(由 Electric Bolt Limited KLCLPVKM8C 签名)。

目前支持的视图

BindKit 直接支持以下视图和属性

视图类 视图属性
UIBarButtonItem enabled (启用)
UIButton enabled (启用), hidden (隐藏)
UIDatePicker date (日期), enabled (启用), hidden (隐藏)
UIImageView image (图像), hidden (隐藏)
UILabel text (文本), attributedText (富文本), hidden (隐藏)
UIPageControl currentPage (当前页), numberOfPages (页面数量), enabled (启用), hidden (隐藏)
UISegmentedControl selectedSegmentIndex (选中分段索引), enabled (启用), hidden (隐藏)
UISlider value (值), enabled (启用), hidden (隐藏)
UIStepper value (值), enabled (启用), hidden (隐藏)
UISwitch on (开启状态), enabled (启用), hidden (隐藏)
UITextFieldText text (文本), attributedText (富文本), enabled (启用), hidden (隐藏)
UITextView text (文本), attributedText (富文本), editable (可编辑), hidden (隐藏)

没有找到您感兴趣的属性或类? 提交一个 pull request,包含您添加属性或类的更改,或者使用 Vendor API 在您自己的应用程序中添加自定义功能。有关使用 Vendor API 实现自定义功能的示例,请参阅 BindingExample 中的 MySearchBar.swift

绑定

数据绑定是双向的 - 对您的模型属性的任何更改都会自动应用于您的视图属性,反之亦然。

只需学习一个 API

Objective-C

[model bindObjectSel: @selector(addressStr) toView: addressTextField viewKey: UITextFieldText];

Swift

model.bindObjectKey(#keyPath(model.addressStr), toView: addressTextField, viewKey: UITextFieldText)

只需几个简单的规则

以下规则在使用 Swift 中的 BindKit 时适用

  1. 您的模型对象必须继承自 NSObject
  2. 您模型中参与绑定的属性需要标记为 @objc dynamic

有关实现细节,请参阅底层原理

示例

Swift

class LogonModel: NSObject {
	
	@objc dynamic var username: String!
	@objc dynamic var password: String!
	@objc dynamic var logonEnabled: Boolean
	
	override func boundPropertiesDidUpdate() {
		logonEnabled = validate()
	}

	func validate() -> Boolean
		guard username!.trimmingCharacters(in: CharacterSet.whitespaces).count > 0 else { return false }
		guard password!.trimmingCharacters(in: CharacterSet.whitespaces).count > 0 else { return false }
		return true
	}
}

class LogonController: UITableViewController {

	@IBOutlet weak var usernameTextField: UITextField!
	@IBOutlet weak var passwordTextField: UITextField!
	@IBOutlet weak var logonButton: UIButton!

	var model = LogonModel()

	override func viewDidLoad() {
		model.bindKey(#keyPath(model.username), view: usernameTextField, viewKey: UITextFieldText)
		model.bindKey(#keyPath(model.password), view: passwordTextField, viewKey: UITextFieldText)
		model.bindKey(#keyPath(model.logonEnabled), view: logonButton, viewKey: UIButtonEnabled)
	}

}

将 BindKit 添加到您的应用程序

手动集成

Swift Package Manager

PrivacyInfo.xcprivacy

iOS 的 BindKit.xcframework 包含一个嵌入的 PrivacyInfo.xcprivacy 文件。 该文件实际上是空的,因为根据 Apple 隐私清单文件 文档,BindKit 没有任何跟踪组件或使用任何 API。

当前 PrivacyInfo.xcprivacy 文件的内容

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSPrivacyTracking</key>
    <false/>
    <key>NSPrivacyTrackingDomains</key>
    <array/>
    <key>NSPrivacyCollectedDataTypes</key>
    <array/>
    <key>NSPrivacyAccessedAPITypes</key>
    <array/>
</dict>
</plist>

构建

尽管静态 XCFramework 已预先构建并包含在存储库中,但如果您需要重新构建,请按照以下步骤操作

重新构建的静态 XCFramework 将被放置到项目的根目录中。

构建脚本目前假定使用 iOS SDK 17.5。如果您使用不同的 Xcode 构建链,请根据需要调整构建脚本中的 IOSSDK_VER 变量。

底层原理

模型

使用键值观察 (KVO) 监视参与绑定的模型属性的更改。 因此,模型对象必须继承自 NSObject,如果使用 Swift,则属性必须标记为 @objc dynamic

视图

参与绑定的视图在运行时被动态子类化。 每个受支持的视图都实现了一个动态子类。 根据视图的不同,需要不同的方法来监视更改:target-action、委托或通知。

不支持的视图? 提交一个 pull request,包含您添加属性或类的更改,或者使用 Vendor API 在您自己的应用程序中添加自定义功能。