diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..989af99 --- /dev/null +++ b/NOTICE @@ -0,0 +1,9 @@ +ZXKit-code/core + +Copyright 2021 ZXKit and contributors. +All rights reserved. + +This product includes software developed at +ZXKit (https://zxkit.com/). + +This distribution has a binary dependency on zxkit/core, which is available under the Apache-2.0 License. The source code of zxkit/core can be found at https://github.com/zxkit-code/core. \ No newline at end of file diff --git a/README.md b/README.md index e0a11d6..6be80c1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,61 @@ # ZXUserDefaultManager -UserDefault Manager + +[中文文档](./README_zh.md) + +iOS UserDefault data management, iOS UserDefault数据管理 + +This project is a built-in function plug-in of [ZXKitSwift](https://github.com/ZXKitCode/ZXKitSwift), and it can also be integrated separately and used as an independent function. + +**If you have integrated `ZXKitSwift`, the file browser will be automatically displayed in the plug-in list, so there is no need to repeat the integration.** + + +## Independent integration + +cocoapods + +```ruby +pod 'ZXUserDefaultManager' +``` + +### Use + +```swift +ZXUserDefaultManager.shared.start() +``` + +## Support `ZXKit` + +**If you have integrated `ZXKitSwift`, the file browser will be automatically displayed in the plug-in list, so there is no need to repeat the integration.** + +If you need to support `ZXKit`, you can use cocoapods to quickly integrate it + +```ruby +pod 'ZXUserDefaultManager/zxkit' +``` + +then register to `ZXKit` in `AppDelegate` + +```swift +func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + ZXKit.regist(plugin: ZXUserDefaultManager.shared) + + return true +} +``` + +## Preview + +|File List|File Type Icon| +|----|----| +|![](./preview/demo2.png)|![](./preview/demo1.png)| + +Function example + +![](./preview/preview.gif) + +## License + +![](https://camo.githubusercontent.com/eb9066a6d8e0950066f3757c420e3a607c0929583b48ebda6fd9a6f50ccfc8f1/68747470733a2f2f7777772e6170616368652e6f72672f696d672f41534632307468416e6e69766572736172792e6a7067) + +Base on Apache-2.0 License diff --git a/README_zh.md b/README_zh.md new file mode 100644 index 0000000..58140f0 --- /dev/null +++ b/README_zh.md @@ -0,0 +1,64 @@ +# ZXUserDefaultManager + +iOS UserDefault data management, iOS UserDefault数据管理 + +该项目是[ZXKitSwift](https://github.com/ZXKitCode/ZXKitSwift)的内置功能插件,也可以单独集成当做独立功能使用。 + +**如果您已经集成了`ZXKitSwift`,插件列表中会自动显示该数据管理浏览器,不需要再重复集成。** + + +## 独立集成 + +cocoapods快速集成 + +```ruby +pod 'ZXUserDefaultManager' +``` + +### 使用 + +```swift +//显示管理器 +ZXUserDefaultManager.shared.start() +``` + +## `ZXKit`个性化集成 + +**如果您已经集成了`ZXKitSwift`,插件列表中会自动显示该文件浏览器,不需要再重复集成。** + +如果需要支持`ZXKit`,可以使用cocoapods快速集成 + +```ruby +pod 'ZXUserDefaultManager/zxkit' +``` + +之后可在`AppDelegate`的启动函数中注册到`ZXKit`即可 + +```swift +func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + //ZXKit注册 + ZXKit.regist(plugin: ZXUserDefaultManager.shared) + + return true +} + +``` + +## 预览 + + +|文件列表|文件类型| +|----|----| +|![](./preview/demo2.png)|![](./preview/demo1.png)| + +功能示例 + +![](./preview/preview.gif) + + +## License + +![](https://camo.githubusercontent.com/eb9066a6d8e0950066f3757c420e3a607c0929583b48ebda6fd9a6f50ccfc8f1/68747470733a2f2f7777772e6170616368652e6f72672f696d672f41534632307468416e6e69766572736172792e6a7067) + +Base on Apache-2.0 License diff --git a/ZXUserDefaultManager.podspec b/ZXUserDefaultManager.podspec new file mode 100644 index 0000000..5f2cb20 --- /dev/null +++ b/ZXUserDefaultManager.podspec @@ -0,0 +1,27 @@ +Pod::Spec.new do |s| +s.name = 'ZXUserDefaultManager' +s.swift_version = '5.0' +s.version = '0.0.1' +s.license= { :type => "Apache-2.0", :file => "LICENSE" } +s.summary = 'iOS UserDefault data management, iOS UserDefault数据管理' +s.homepage = 'https://github.com/ZXKitCode/ZXUserDefaultManager' +s.authors = { 'ZXKitCode' => 'dong765@qq.com' } +s.source = { :git => "https://github.com/ZXKitCode/ZXUserDefaultManager.git", :tag => s.version} +s.requires_arc = true +s.ios.deployment_target = '11.0' +s.subspec 'core' do |cs| + cs.resource_bundles = { + 'ZXUserDefaultManager' => ['pod/assets/**/*'] + } + cs.source_files = "pod/*.swift", "pod/view/*.swift", "pod/vc/*.swift", "pod/model/*.swift" + cs.dependency 'ZXKitUtil' + cs.dependency 'SnapKit' +end +s.subspec 'zxkit' do |cs| + cs.dependency 'ZXUserDefaultManager/core' + cs.dependency 'ZXKitCore/core' + cs.source_files = "pod/zxkit/*.swift" +end +s.default_subspecs = "core" +s.documentation_url = 'https://blog.hudongdong.com/ios/1169.html' +end diff --git a/example/ZXUserDefaultManager.xcodeproj/project.pbxproj b/example/ZXUserDefaultManager.xcodeproj/project.pbxproj index 34ac374..a7a5cd8 100644 --- a/example/ZXUserDefaultManager.xcodeproj/project.pbxproj +++ b/example/ZXUserDefaultManager.xcodeproj/project.pbxproj @@ -20,6 +20,7 @@ E4292D5826A02F3A00D5F6E2 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E4292D5526A02F3A00D5F6E2 /* Localizable.strings */; }; E4292D5A26A030EE00D5F6E2 /* ZXUserDefaultManager.png in Resources */ = {isa = PBXBuildFile; fileRef = E4292D5926A030EE00D5F6E2 /* ZXUserDefaultManager.png */; }; E4292D5D26A0476700D5F6E2 /* ZXDataCellModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4292D5C26A0476700D5F6E2 /* ZXDataCellModel.swift */; }; + E4292D5F26A1392100D5F6E2 /* ZXUserDefaultEditVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4292D5E26A1392100D5F6E2 /* ZXUserDefaultEditVC.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -41,6 +42,7 @@ E4292D5726A02F3A00D5F6E2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; E4292D5926A030EE00D5F6E2 /* ZXUserDefaultManager.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ZXUserDefaultManager.png; sourceTree = ""; }; E4292D5C26A0476700D5F6E2 /* ZXDataCellModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZXDataCellModel.swift; sourceTree = ""; }; + E4292D5E26A1392100D5F6E2 /* ZXUserDefaultEditVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZXUserDefaultEditVC.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -122,6 +124,7 @@ isa = PBXGroup; children = ( E4292D4926A028C800D5F6E2 /* ZXUserDefaultVC.swift */, + E4292D5E26A1392100D5F6E2 /* ZXUserDefaultEditVC.swift */, ); path = vc; sourceTree = ""; @@ -285,6 +288,7 @@ buildActionMask = 2147483647; files = ( E4292D4A26A028C800D5F6E2 /* ZXUserDefaultVC.swift in Sources */, + E4292D5F26A1392100D5F6E2 /* ZXUserDefaultEditVC.swift in Sources */, E4292D3826A01D6900D5F6E2 /* ViewController.swift in Sources */, E4292D5D26A0476700D5F6E2 /* ZXDataCellModel.swift in Sources */, E4292D4C26A028DB00D5F6E2 /* ZXUserDefaultManager.swift in Sources */, diff --git a/example/ZXUserDefaultManager.xcworkspace/xcuserdata/damon.xcuserdatad/UserInterfaceState.xcuserstate b/example/ZXUserDefaultManager.xcworkspace/xcuserdata/damon.xcuserdatad/UserInterfaceState.xcuserstate index ba9bf1c..144d30b 100644 Binary files a/example/ZXUserDefaultManager.xcworkspace/xcuserdata/damon.xcuserdatad/UserInterfaceState.xcuserstate and b/example/ZXUserDefaultManager.xcworkspace/xcuserdata/damon.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/example/ZXUserDefaultManager.xcworkspace/xcuserdata/damon.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/example/ZXUserDefaultManager.xcworkspace/xcuserdata/damon.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..ce56f0d --- /dev/null +++ b/example/ZXUserDefaultManager.xcworkspace/xcuserdata/damon.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/pod/assets/localizable/en.lproj/Localizable.strings b/pod/assets/localizable/en.lproj/Localizable.strings index 6a5f123..4049b19 100644 --- a/pod/assets/localizable/en.lproj/Localizable.strings +++ b/pod/assets/localizable/en.lproj/Localizable.strings @@ -17,3 +17,4 @@ "move here" = "move here"; "UserDefaultManager" = "UserDefaultManager"; "Hash value of the file" = "Hash value of the file"; +"save" = "save"; diff --git a/pod/assets/localizable/zh-Hans.lproj/Localizable.strings b/pod/assets/localizable/zh-Hans.lproj/Localizable.strings index be45856..e1e9979 100644 --- a/pod/assets/localizable/zh-Hans.lproj/Localizable.strings +++ b/pod/assets/localizable/zh-Hans.lproj/Localizable.strings @@ -17,3 +17,4 @@ "move here" = "移动到此处"; "UserDefaultManager" = "UserDefault管理"; "Hash value of the file" = "文件的hash值"; +"save" = "保存"; diff --git a/pod/model/ZXDataCellModel.swift b/pod/model/ZXDataCellModel.swift index 2e474bc..ba1ef9c 100644 --- a/pod/model/ZXDataCellModel.swift +++ b/pod/model/ZXDataCellModel.swift @@ -8,5 +8,6 @@ import UIKit class ZXDataCellModel: NSObject { - + var key = "" + var value: Any = "" } diff --git a/pod/vc/ZXUserDefaultEditVC.swift b/pod/vc/ZXUserDefaultEditVC.swift new file mode 100644 index 0000000..1a09ccd --- /dev/null +++ b/pod/vc/ZXUserDefaultEditVC.swift @@ -0,0 +1,148 @@ +// +// ZXUserDefaultEditVC.swift +// ZXUserDefaultManager +// +// Created by Damon on 2021/7/16. +// + +import UIKit + +class ZXUserDefaultEditVC: UIViewController { + private var model: ZXDataCellModel + + init(model: ZXDataCellModel) { + self.model = model + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + + override func viewDidLoad() { + super.viewDidLoad() + let rightBarItem = UIBarButtonItem(title: "save".ZXLocaleString, style: .plain, target: self, action: #selector(_rightBarItemClick)) + self.navigationItem.rightBarButtonItem = rightBarItem + self._createUI() + self._loadData() + } + + //MARK: UI + lazy var mTitleLabel: UILabel = { + let tLabel = UILabel() + tLabel.textAlignment = .center + tLabel.numberOfLines = 2 + tLabel.font = .systemFont(ofSize: 16, weight: .medium) + tLabel.textColor = UIColor.zx.color(hexValue: 0x333333) + return tLabel + }() + + lazy var mSegment: UISegmentedControl = { + let segment = UISegmentedControl(items: ["Bool", "Number", "String", "Object"]) + segment.addTarget(self, action: #selector(_changeType), for: .valueChanged) + return segment + }() + lazy var mTextView: UITextView = { + let textView = UITextView() + textView.font = .systemFont(ofSize: 14) + textView.layer.cornerRadius = 10 + textView.layer.borderWidth = 1.0 + textView.layer.borderColor = UIColor.zx.color(hexValue: 0xeeeeee).cgColor + return textView + }() +} + +extension ZXUserDefaultEditVC { + + @objc func _rightBarItemClick() { + switch self.mSegment.selectedSegmentIndex { + case 0: + UserDefaults.standard.set(mTextView.text.boolValue, forKey: model.key) + case 1: + UserDefaults.standard.set(Double(String(mTextView.text)) ?? 0, forKey: model.key) + case 2: + UserDefaults.standard.set(mTextView.text, forKey: model.key) + default: + if let jsonData = mTextView.text.data(using: .utf8), let object = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers) { + UserDefaults.standard.set(object, forKey: model.key) + } else { + UserDefaults.standard.set(mTextView.text, forKey: model.key) + } + } + self.navigationController?.popViewController(animated: true) + } + + func _createUI() { + self.view.backgroundColor = UIColor.zx.color(hexValue: 0xffffff) + self.view.addSubview(mTitleLabel) + mTitleLabel.snp.makeConstraints { make in + make.left.equalToSuperview().offset(10) + make.right.equalToSuperview().offset(-10) + make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(20) + } + + self.view.addSubview(mSegment) + mSegment.snp.makeConstraints { make in + make.left.right.equalTo(self.mTitleLabel) + make.top.equalTo(mTitleLabel.snp.bottom).offset(30) + make.height.equalTo(34) + } + + self.view.addSubview(mTextView) + mTextView.snp.makeConstraints { make in + make.left.equalToSuperview().offset(10) + make.right.equalToSuperview().offset(-10) + make.top.equalTo(mSegment.snp.bottom).offset(10) + make.bottom.equalTo(self.view.safeAreaLayoutGuide.snp.bottom).offset(-20) + } + } + + func _loadData() { + mTitleLabel.text = model.key + if model.value is Bool { + mSegment.selectedSegmentIndex = 0 + } else if model.value is NSNumber { + mSegment.selectedSegmentIndex = 1 + } else if model.value is String { + mSegment.selectedSegmentIndex = 2 + } else if (model.value is NSArray || model.value is NSDictionary) { + mSegment.selectedSegmentIndex = 3 + } + if JSONSerialization.isValidJSONObject(model.value), let jsonData = try? JSONSerialization.data(withJSONObject: model.value, options: .prettyPrinted) { + mTextView.text = String(data: jsonData, encoding: .utf8) + } else { + mTextView.text = "\(model.value)" + } + } + + @objc func _changeType() { + switch self.mSegment.selectedSegmentIndex { + case 0: + mTextView.text = "\(model.value)".boolValue ? "true" : "false" + case 1: + if model.value is NSNumber { + mTextView.text = "\(model.value)" + } else { + mTextView.text = "\(Double("\(model.value)") ?? 0)" + } + default: + if JSONSerialization.isValidJSONObject(model.value), let jsonData = try? JSONSerialization.data(withJSONObject: model.value, options: .prettyPrinted) { + mTextView.text = String(data: jsonData, encoding: .utf8) + } else { + mTextView.text = "\(model.value)" + } + } + } +} + +extension String { + var boolValue: Bool { + switch self.lowercased() { + case "false", "no", "0": + return false + default: + return !self.isEmpty + } + } +} diff --git a/pod/vc/ZXUserDefaultVC.swift b/pod/vc/ZXUserDefaultVC.swift index 3d20323..9a4ea5f 100644 --- a/pod/vc/ZXUserDefaultVC.swift +++ b/pod/vc/ZXUserDefaultVC.swift @@ -24,13 +24,17 @@ extension String{ } class ZXUserDefaultVC: UIViewController { - + var mTableViewList = [ZXDataCellModel]() override func viewDidLoad() { super.viewDidLoad() let rightBarItem = UIBarButtonItem(title: "close".ZXLocaleString, style: .plain, target: self, action: #selector(_rightBarItemClick)) self.navigationItem.rightBarButtonItem = rightBarItem self._createUI() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) self._loadData() } @@ -67,7 +71,14 @@ extension ZXUserDefaultVC { } func _loadData() { - UserDefaults.standard.dictionaryRepresentation() + mTableViewList.removeAll() + for item in UserDefaults.standard.dictionaryRepresentation().keys.sorted() { + let model = ZXDataCellModel() + model.key = item + model.value = UserDefaults.standard.object(forKey: item)! + mTableViewList.append(model) + } + mTableView.reloadData() } } @@ -80,12 +91,7 @@ extension ZXUserDefaultVC: UITableViewDelegate, UITableViewDataSource { let model = self.mTableViewList[indexPath.row] let cell = tableView.dequeueReusableCell(withIdentifier: "ZXDataTableViewCell") as! ZXDataTableViewCell cell.selectionStyle = UITableViewCell.SelectionStyle.none - if model.fileType == .folder { - cell.accessoryType = UITableViewCell.AccessoryType.disclosureIndicator - } else { - cell.accessoryType = UITableViewCell.AccessoryType.none - } - + cell.accessoryType = UITableViewCell.AccessoryType.disclosureIndicator cell.updateUI(model: model) return cell } @@ -108,49 +114,27 @@ extension ZXUserDefaultVC: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let model = self.mTableViewList[indexPath.row] - if model.fileType == .folder { - extensionDirectoryPath = extensionDirectoryPath + "/" + model.name - self._loadData() - } else { - let rightBarItem = UIBarButtonItem(title: "close".ZXLocaleString, style: .plain, target: self, action: #selector(_rightBarItemClick)) - self.navigationItem.rightBarButtonItem = rightBarItem - self.operateFilePath = self.currentDirectoryPath.appendingPathComponent(model.name, isDirectory: false) - //preview - let previewVC = QLPreviewController() - previewVC.delegate = self - previewVC.dataSource = self - self.navigationController?.pushViewController(previewVC, animated: true) - } - } - - func tableView(_ tableView: UITableView, canPerformAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) -> Bool { - return false + let vc = ZXUserDefaultEditVC(model: model) + self.navigationController?.pushViewController(vc, animated: true) } - func tableView(_ tableView: UITableView, shouldShowMenuForRowAt indexPath: IndexPath) -> Bool { + func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let model = self.mTableViewList[indexPath.row] - if model.fileType == .folder { - self.operateFilePath = self.currentDirectoryPath.appendingPathComponent(model.name, isDirectory: true) - self._showMore(isDirectory: true) - } else { - self.operateFilePath = self.currentDirectoryPath.appendingPathComponent(model.name, isDirectory: false) - self._showMore(isDirectory: false) + let delete = UIContextualAction(style: .destructive, title: "删除") { _, _, complete in + UserDefaults.standard.removeObject(forKey: model.key) + UserDefaults.standard.synchronize() + complete(true) + self._loadData() } - return true - } - - func tableView(_ tableView: UITableView, performAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) { - - } -} + let edit = UIContextualAction(style: .normal, title: "编辑") { _, _, complete in + let vc = ZXUserDefaultEditVC(model: model) + self.navigationController?.pushViewController(vc, animated: true) + } + edit.backgroundColor = UIColor.zx.color(hexValue: 0x5dae8b) -extension ZXUserDefaultVC: QLPreviewControllerDelegate, QLPreviewControllerDataSource { - func numberOfPreviewItems(in controller: QLPreviewController) -> Int { - return 1 - } + let config = UISwipeActionsConfiguration(actions: [delete, edit]) + return config - func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem { - return self.operateFilePath! as QLPreviewItem } } diff --git a/pod/view/ZXDataTableViewCell.swift b/pod/view/ZXDataTableViewCell.swift index bd31b0f..67ff7a0 100644 --- a/pod/view/ZXDataTableViewCell.swift +++ b/pod/view/ZXDataTableViewCell.swift @@ -29,32 +29,75 @@ class ZXDataTableViewCell: UITableViewCell { lazy var mIconButton: UIButton = { let button = UIButton() + button.titleLabel?.font = .systemFont(ofSize: 12) + button.setTitleColor(UIColor.zx.color(hexValue: 0xffffff), for: .normal) + button.backgroundColor = UIColor.zx.color(hexValue: 0x93D9A3) + button.layer.masksToBounds = true + button.layer.cornerRadius = 5 return button }() lazy var mTitleLabel: UILabel = { let tLabel = UILabel() - tLabel.font = .systemFont(ofSize: 14) + tLabel.lineBreakMode = .byCharWrapping + tLabel.numberOfLines = 3 + tLabel.font = .systemFont(ofSize: 12) tLabel.textColor = UIColor.zx.color(hexValue: 0x333333) return tLabel }() } +extension ZXDataTableViewCell { + func updateUI(model: ZXDataCellModel) { + self._updateButton(model: model) + + let attributedString = NSMutableAttributedString(string: "Key: \(model.key)\n\n") + attributedString.setAttributes([NSAttributedString.Key.foregroundColor : UIColor.zx.color(hexValue: 0xFF616D), NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12, weight: .bold)], range: NSRange(location: 0, length: 4)) + + let valueAttributedString = NSMutableAttributedString(string: "Value: \(model.value)") + valueAttributedString.setAttributes([NSAttributedString.Key.foregroundColor : UIColor.zx.color(hexValue: 0x5D8233), NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12, weight: .bold)], range: NSRange(location: 0, length: 7)) + attributedString.append(valueAttributedString) + mTitleLabel.attributedText = attributedString + } +} + extension ZXDataTableViewCell { func _createUI() { self.contentView.addSubview(mIconButton) mIconButton.snp.makeConstraints { $0.left.equalToSuperview().offset(10) $0.centerY.equalToSuperview() - $0.width.equalTo(60) - $0.height.equalTo(30) + $0.width.equalTo(70) + $0.height.equalTo(20) } self.contentView.addSubview(mTitleLabel) mTitleLabel.snp.makeConstraints { $0.left.equalTo(mIconButton.snp.right).offset(10) $0.top.equalToSuperview().offset(5) + $0.bottom.equalToSuperview().offset(-5) $0.right.equalToSuperview().offset(-20) } } + + func _updateButton(model: ZXDataCellModel) { + if model.value is Bool { + mIconButton.backgroundColor = UIColor.zx.color(hexValue: 0xA03C78) + mIconButton.setTitle("Bool", for: .normal) + } else if model.value is NSNumber { + mIconButton.backgroundColor = UIColor.zx.color(hexValue: 0xED8E7C) + mIconButton.setTitle("Number", for: .normal) + } else if model.value is String { + mIconButton.backgroundColor = UIColor.zx.color(hexValue: 0x96BAFF) + mIconButton.setTitle("String", for: .normal) + } else if model.value is NSArray { + mIconButton.backgroundColor = UIColor.zx.color(hexValue: 0x7C83FD) + mIconButton.setTitle("Array", for: .normal) + } else if model.value is NSDictionary { + mIconButton.backgroundColor = UIColor.zx.color(hexValue: 0x88FFF7) + mIconButton.setTitle("Dictionary", for: .normal) + } else { + mIconButton.setTitle("\(type(of: model.value))", for: .normal) + } + } } diff --git a/preview/demo1.png b/preview/demo1.png new file mode 100644 index 0000000..fcb77f8 Binary files /dev/null and b/preview/demo1.png differ diff --git a/preview/demo2.png b/preview/demo2.png new file mode 100644 index 0000000..95c83fb Binary files /dev/null and b/preview/demo2.png differ diff --git a/preview/preview.gif b/preview/preview.gif new file mode 100644 index 0000000..acfb47d Binary files /dev/null and b/preview/preview.gif differ