大家好,我是 K 哥。一名独立开发者,同时也是 Swift 开发框架【Aquarius】的作者,悦记和爱寻车 app 的开发者。
Aquarius 开发框架旨在帮助独立开发者和中小型团队,完成 iOS App 的快速实现与迭代。使用框架开发将给你带来简单、高效、易维护的编程体验。
介绍
大家好,我是 K 哥,一名 10 多年的 iOS 老鸟。Swift 开发框架 - Aquarius 作者,悦记和爱寻车两款 app 的开发者。
今天和大家推荐一下我开源的 Swift 开发框架 - Aquarius
Aquarius 旨在帮助独立开发者和中小型团队,完成 iOS App 的快速实现与迭代。使用框架开发将给你带来简单、高效、易维护的编程体验。
希望这款开发框架能够帮助到大家。
框架地址:
https://github.com/JZXStudio/Aquarius
描述
Aquarius 是以帮助独立开发者规范化开发流程,提高开发效率为目的而设计的 Swift 开发框架。
框架提供高效率、低侵入式的 framework,既支持新的项目工程,也支持加入到老的工程中
框架本身不依赖任何三方类库,不会增大项目体积
框架以 MVVM 设计模式为核心,通过一系列定义的方法,提供新的开发方式
框架建议通过方法设置 UI 组件的属性,基于此原则,重新封装了大部分 UI 组件的属性
框架提供数据绑定功能,既支持变量间的动态数据更新,也支持变量与 UI 组件属性的动态数据更新
要求
新增功能
液态玻璃效果
新增按钮的液态玻璃效果。
液态玻璃效果包括:
Glass
ClearGlass
ProminentGlass
ProminentClearGlass
针对以上四种按钮液态玻璃效果,框架新增 2 个枚举类型,包括:
LiquidGlassType
glass
clearGlass
prominentGlass
prominentClearGlass
LiquidGlassConfig
title
attributedTitle
subtitle
attributedSubtitle
titlePadding
titleAlignment
image
imagePadding
baseForegroundColor
baseBackgroundColor
新增的方法包括:
public func liquid(_ config: UIButton.Configuration)public func liquid( type: LiquidGlassType, title: String?=nil, attributedTitle: AttributedString?=nil, subtitle: String?=nil, attributedSubtitle: AttributedString?=nil, titlePadding: CGFloat?=nil, titleAlignment:UIButton.Configuration.TitleAlignment?=nil, image: UIImage?=nil, imagePadding: CGFloat?=nil, baseForegroundColor: UIColor?=nil, baseBackgroundColor: UIColor?=nil)public func liquid(type: LiquidGlassType, config: [LiquidGlassConfig : Any]?=nil)
复制代码
public func liquid_Glass( title: String?=nil, attributedTitle: AttributedString?=nil, subtitle: String?=nil, attributedSubtitle: AttributedString?=nil, titlePadding: CGFloat?=nil, titleAlignment:UIButton.Configuration.TitleAlignment?=nil, image: UIImage?=nil, imagePadding: CGFloat?=nil, baseForegroundColor: UIColor?=nil, baseBackgroundColor: UIColor?=nil)public func liquid_Glass(_ config: [LiquidGlassConfig : Any]?=nil)
复制代码
public func liquid_ClearGlass( title: String?=nil, attributedTitle: AttributedString?=nil, subtitle: String?=nil, attributedSubtitle: AttributedString?=nil, titlePadding: CGFloat?=nil, titleAlignment:UIButton.Configuration.TitleAlignment?=nil, image: UIImage?=nil, imagePadding: CGFloat?=nil, baseForegroundColor: UIColor?=nil, baseBackgroundColor: UIColor?=nil)public func liquid_ClearGlass(_ config: [LiquidGlassConfig : Any]?=nil)
复制代码
public func liquid_ProminentGlass( title: String?=nil, attributedTitle: AttributedString?=nil, subtitle: String?=nil, attributedSubtitle: AttributedString?=nil, titlePadding: CGFloat?=nil, titleAlignment:UIButton.Configuration.TitleAlignment?=nil, image: UIImage?=nil, imagePadding: CGFloat?=nil, baseForegroundColor: UIColor?=nil, baseBackgroundColor: UIColor?=nil)public func liquid_ProminentGlass(_ config: [LiquidGlassConfig : Any]?=nil)
复制代码
public func liquid_ProminentClearGlass( title: String?=nil, attributedTitle: AttributedString?=nil, subtitle: String?=nil, attributedSubtitle: AttributedString?=nil, titlePadding: CGFloat?=nil, titleAlignment:UIButton.Configuration.TitleAlignment?=nil, image: UIImage?=nil, imagePadding: CGFloat?=nil, baseForegroundColor: UIColor?=nil, baseBackgroundColor: UIColor?=nil)public func liquid_ProminentClearGlass(_ config: [LiquidGlassConfig : Any]?=nil)
复制代码
liquid
单独设置 UIButton.Configuration
示例:
let button: UIButton = A.ui.buttonvar config: UIButton.Configuration = UIButton.Configuration.glass()config.title = "test"button.liquid(config)
复制代码
设置液态玻璃类型,并做相关配置
示例:
let button: UIButton = A.ui.buttonbutton.liguid(type: .glass, title: "test"...)
复制代码
设置液态玻璃类型,并通过字典做相关配置
示例:
let type: LiquidGlassType = .glasslet config: [LiquidGlassConfig: Any] = [ title : "test"]let button: UIButton = A.ui.buttonbutton.liquid(type, config)
复制代码
liquid_Glass
设置 Glass 液态玻璃类型,并做相关配置
示例:
let button: UIButton = A.ui.buttonbutton.liguid_Glass(title: "test")
复制代码
设置 Glass 液态玻璃类型,并通过字典做相关配置
let config: [LiquidGlassConfig : Any] = [ .title : "test"]let button: UIButton = A.ui.buttonbutton.liquid_Glass(config)
复制代码
liquid_ClearGlass
设置 ClearGlass 液态玻璃类型,并做相关配置
示例:
let button: UIButton = A.ui.buttonbutton.liguid_ClearGlass(title: "test")
复制代码
设置 ClearGlass 液态玻璃类型,并通过字典做相关配置
let config: [LiquidGlassConfig : Any] = [ .title : "test"]let button: UIButton = A.ui.buttonbutton.liquid_ClearGlass(config)
复制代码
liquid_prominentGlass
设置 prominentGlass 液态玻璃类型,并做相关配置
示例:
let button: UIButton = A.ui.buttonbutton.liguid_prominentGlass(title: "test")
复制代码
设置 prominentGlass 液态玻璃类型,并通过字典做相关配置
let config: [LiquidGlassConfig : Any] = [ .title : "test"]let button: UIButton = A.ui.buttonbutton.liquid_prominentGlass(config)
复制代码
liquid_prominentClearGlass
设置 prominentClearGlass 液态玻璃类型,并做相关配置
示例:
let button: UIButton = A.ui.buttonbutton.liguid_prominentClearGlass(title: "test")
复制代码
设置 prominentClearGlass 液态玻璃类型,并通过字典做相关配置
let config: [LiquidGlassConfig : Any] = [ .title : "test"]let button: UIButton = A.ui.buttonbutton.liquid_prominentClearGlass(config)
复制代码
核心功能
框架提供:
MVVM 设计模式
开发方法
数据绑定
处理 UI 的新方法
深色模式切换
格式转换
依赖注入
自动管理
工具
通知
userDefaults
内购
日历/提醒
位置
日志
Timer
格式化属性
MVVM 设计模式
框架提供AView、AViewController、AViewModel,开发中,需基于此三个基类开始开发。
AView
主要功能包括:
键盘管理
分层管理
事件管理
Delegate 管理
通知管理
数据绑定管理
日志管理
热更新管理
示例代码:
import Aquarius
class TestView: AView {
}
复制代码
AViewController
主要功能包括:
埋点
导航条管理
分层管理
主题管理
日志管理
热更新管理
示例代码:
import Aquarius
class TestViewController: AViewController {
}
复制代码
AViewModel
主要功能包括:
分层管理
Delegate 管理
通知管理
数据绑定管理
日志管理
热更新管理
示例代码:
import Aquarius
class TestVM: AViewModel {
}
复制代码
框架提供了代码的低侵入性,可以在老的工程中引入Aquarius。引入后,新开发的功能继承AView、AViewController、AViewModel,老功能不受影响。
开发方法
洋葱开发法是作者为开发方法起的名字,方法主要将开发工作进行细分。
设计了多个方法,开发时只需要覆盖这些方法体,它们会自动执行。
AViewController
初始化中执行的方法包括:
a_Preview:开始前执行
a_Begin:开始执行时调用
a_Navigation:定制化导航条
a_Delegate:设置 delegate
updateThemeStyle:深色模式切换时调用
a_Notification:设置通知
a_Bind:设置数据绑定
a_Observe:设置 Observe
a_Event:设置事件
viewDidLoad 方法中执行的方法主要包括:
a_UI:设置 UI 组件
a_UIConfig:设置 UI 组件参数
a_Layout:设置 UI 组件的布局
a_Other:设置其它内容
a_End:代码末尾执行
a_Test:测试的代码函数,此函数值在 debug 模式下执行,发布后不执行
deinit 方法中执行的方法包括:
a_Clear:销毁时执行
AView
初始化中执行的方法包括:
a_Preview:开始前执行
a_Begin:开始执行时调用
a_UI:设置 UI 组件
a_UIConfig:设置 UI 组件参数
a_Layout:设置 UI 组件的布局
a_Notification:设置通知
a_Delegate:设置 delegate
updateThemeStyle:深色模式切换时调用
a_Bind:设置数据绑定
a_Event:设置事件
a_Other:设置其它内容
a_End:代码末尾执行
a_Test:测试的代码函数,此函数值在 debug 模式下执行,发布后不执行
deinit 方法中执行的方法包括:
a_Clear:销毁时执行
AViewModel
初始化中执行的方法包括:
a_Preview:开始前执行
a_Begin:开始执行时调用
a_Notification:设置通知
a_Delegate:设置 delegate
a_Observe:设置 Observe
a_Other:设置其它内容
a_End:代码末尾执行
a_Test:测试的代码函数,此函数值在 debug 模式下执行,发布后不执行
deinit 方法中执行的方法包括:
a_Clear:销毁时执行
ATableViewCell
初始化中执行的方法包括:
a_Preview:开始前执行
a_Begin:开始执行时调用
a_UI:设置 UI 组件
a_UIConfig:设置 UI 组件参数
a_Layout:设置 UI 组件的布局
updateThemeStyle:深色模式切换时调用
a_Notification:设置通知
a_Delegate:设置 delegate
a_Observe:设置 Observe
a_Bind:设置数据绑定
a_Event:设置事件
a_Other:设置其它内容
a_End:代码末尾执行
configWithCell(cellData: Any):cell 接收数据时调用
deinit 方法中执行的方法包括:
a_Clear:销毁时执行
数据绑定
框架中AView、AViewModel,提供了数据绑定功能,帮助实现完全解耦的数据更新。
数据绑定主要提供如下方法:
bindableFrom(_ dict: Dictionary<String, String>)bindablesFrom(_ o: Array<Dictionary<String, String>>)bindableTo(_ dict: Dictionary<String, String>)bindablesTo(_ o: Array<Dictionary<String, String>>)
复制代码
方法需要联动使用。
bindableFrom、、bindablesFrom,负责更新数据。
bindableTo、bindalbesTo,负责接收更新数据。
TestView
示例代码:
import UIKitimport Foundation
import Aquarius
class TestView: AView { private let testButton: UIButton = A.ui.button
@objc dynamic private var testString: String = ""
override func a_UI() { super.a_UI()
addSubviews(views: [ testButton ]) }
override func a_UIConfig() { super.a_UIConfig()
testButton.prototypeDesign(.hollow) testButton.setTitle("测试数据绑定", for: .normal) }
override func a_Layout() { super.a_Layout()
testButton.size(sizes: [100, 150]) testButton.point(points: [200, 400]) }
override func a_Bind() { super.a_Bind()
bindableFrom([ "bindKey" : #keyPath(testString) ]) }
override func a_Event() { super.a_Event()
testButton.addTouchUpInsideBlock { [weak self] result in self?.testString = String.random(length: 16) } }}
复制代码
TestVM
示例代码:
import Foundation
import Aquarius
class TestVM: AViewModel { @objc dynamic private var updateBindString: String = "" { willSet { A.log.info(newValue) } }
override func a_Bind() { super.a_Bind()
bindableTo([ "bindKey" : #keyPath(updateBindString) ]) }}
复制代码
处理 UI 的新方法
框架提供了一系列创建及处理 UI 组件的方法。方便开发者提高处理 UI 的效率。
快速初始化 UI 控件
A.ui.view//=UIView(frame: .zero)A.ui.imageView//=UIImageView(frame: .zero)A.ui.button//=UIButton(frame: .zero)A.ui.label//=UILabel(frame: .zero)A.ui.collectionView//=UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())A.ui.collectionViewCell//=UICollectionViewCell(frame: .zero)A.ui.datePicker//=UIDatePicker(frame: .zero)A.ui.navigationController//=UINavigationController()A.ui.navigationItem//=UINavigationItem()A.ui.pickerView//=UIPickerView(frame: .zero)A.ui.scrollView//=UIScrollView(frame: .zero)A.ui._switch//=UISwitch(frame: .zero)A.ui.tabBarController//=UITabBarController()A.ui.tabBarItem//=UITabBarItem()A.ui.tableView//=UITableView(frame: .zero)A.ui.tableViewCell//=UITableViewCell(frame: .zero)A.ui.textField//=UITextField(frame: .zero)A.ui.viewController//=UIViewController()A.ui.searchBar//=UISearchBar(frame: .zero)A.ui.textView//=UITextView(frame: .zero)A.ui.refreshControl//=UIRefreshControl()A.ui.activityIndicatorView//=UIActivityIndicatorView()A.ui.webView//=WKWebView()A.ui.progressView//=UIProgressView()A.ui.alert//=UIAlertController(title: "", message: "", preferredStyle: .alert)A.ui.mapView//=MKMapView()
复制代码
属性主要用于在 UIView 中快速的初始化 UI 控件。
示例代码:
import UIKitimport Foundation
import Aquarius
class TestView: AView { private let testButton: UIButton = A.ui.button private let testLabel: UILabel = A.ui.label private let testTableView: UITableView = A.ui.tableView ...}
复制代码
UI 布局
基础布局
UI 控件提供如下基础布局属性和方法:
//获取UI控件顶端y值func y() -> CGFloatfunc top() -> CGFloat//获取UI控件底端y值func bottom() -> CGFloat//获取UI控件左侧x值func x() -> CGFloatfunc left() -> CGFloat//获取UI控件右侧y值func right() -> CGFloat//获取UI控件宽度func width() -> CGFloat//获取UI控件高度func height() -> CGFloat//获取UI控件的sizefunc size() -> CGSize//获取UI控件的framefunc frame() -> CGRect//获取UI控件中间点x坐标func centerX() -> CGFloat//获取UI控件中间点y坐标func centerY() -> CGFloat//获取屏幕的Sizefunc screenSize() -> CGSize//获取屏幕的宽度func screenWidth() -> CGFloat//获取屏幕的高度func screenHeight() -> CGFloat//获取屏幕(去掉状态栏)的高度func screenHeightNoStatus() -> CGFloat//获取屏幕(去掉导航条)的高度func screenHeightNoNavigation() -> CGFloat//获取屏幕(去掉状态栏和导航条)的高度func screenHeightNoStatusNoNavigation() -> CGFloat//获取屏幕(去掉底部安全区域)的高度func screenHeightNoSafeAreaFooter() -> CGFloat//获取屏幕(去掉底部tabBar)的高度func screenHeightNoTabBar() -> CGFloat//获取屏幕(去掉底部安全区域和tabBar)的高度func screenHeightNoStatusNoSafeAreaFooter() -> CGFloat//获取屏幕(去掉状态栏和tabBar)的高度func screenHeightNoStatusNoTabBar() -> CGFloat//获取屏幕(去掉状态栏、底部安全区域和tabBar)的高度func screenHeightNoStatusNoSafeAreaFooterNoTabBar() -> CGFloat//获取屏幕(去掉导航条和底部安全区域)的高度func screenHeightNoNavigationNoSafeAreaFooter() -> CGFloat//获取屏幕(去掉导航条和tabBar)的高度func screenHeightNoNavigationNoTabBar() -> CGFloat//获取屏幕(去掉导航条、底部安全区域和tabBar)的高度func screenHeightNoNavigationNoSafeAreaFooterNoTabBar() -> CGFloat//获取屏幕(去掉状态栏、导航条和底部安全区域)的高度func screenHeightNoStatusNoNavigationNoSafeAreaFooter() -> CGFloat//获取屏幕(去掉状态栏、导航条和tabBar)的高度func screenHeightNoStatusNoNavigationNoTabBar() -> CGFloat//获取屏幕(去掉状态栏、导航条、底部安全区域和tabBar)的高度func screenHeightNoStatusNoNavigationNoSafeAreaFooterNoTabBar() -> CGFloat//获取顶部安全区域高度func safeAreaHeaderHeight() -> CGFloat//获取底部安全区域高度func safeAreaFooterHeight() -> CGFloat//获取状态栏高度func statusBarHeight() -> CGFloat//获取导航条高度func navigationBarHeight() -> CGFloat//获取tabBar高度func tabBarHeight() -> CGFloat
复制代码
UI 控件设置布局
UI 控件提供如下设置布局的方法:
//设置UI控件的y位置或顶部位置(支持动画)func y(y: CGFloat, animate: Bool = false, duration: TimeInterval = UIView.a_duration)func top(top: CGFloat, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//设置UI控件的底部位置(支持动画)func bottom(bottom: CGFloat, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//设置UI控件的x位置或左侧位置(支持动画)func x(x: CGFloat, animate: Bool = false, duration: TimeInterval = UIView.a_duration)func left(left: CGFloat, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//设置UI控件的右侧位置(支持动画)func right(right: CGFloat, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//设置UI控件的宽度(支持动画)func width(width: CGFloat, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//设置UI控件的高度(支持动画)func height(height: CGFloat, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//设置UI控件的size(设置宽和高)(支持动画)func size(width: CGFloat, height: CGFloat, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//设置UI控件的size(数组形式设置,0为宽度,1为高度)(支持动画)func size(sizes: Array<CGFloat>, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//设置UI控件的size(直接设置size)(支持动画)func size(size: CGSize, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//设置UI控件的size(宽和高相同)(支持动画)func size(widthHeight: CGFloat, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//设置UI控件的frame (支持动画)func frame(frame: CGRect, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//设置UI控件的frame(数组形式设置,0为x,1为y,2为width,3为height) (支持动画)func frame(frames: Array<CGFloat>, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//设置UI控件的frame(x和y相同,width和height相同时) (支持动画)func frame(xy: CGFloat, widthHeight: CGFloat, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//设置UI控件的frame (支持动画)func frame(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat, animate: Bool = false, duration: TimeInterval = UIView.a_duration)
复制代码
控件间布局方法
UI 控件提供如下控件间布局的方法:
//UI控件顶部在view的底部,offset为间距(支持动画)func alignTop(view: UIView, offset: CGFloat = 0, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//UI控件底部在view的顶部,offset为间距(支持动画)func alignBottom(view: UIView, offset: CGFloat = 0, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//UI控件左侧在view的右侧,offset为间距(支持动画)func alignLeft(view: UIView, offset: CGFloat = 0, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//UI控件右侧在view的左侧,offset为间距(支持动画)func alignRight(view: UIView, offset: CGFloat = 0, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//UI控件顶部等于target顶部,offset为间距(支持动画)func equalTop(target: UIView, offset: CGFloat = 0, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//UI控件底部等于target底部,offset为间距(支持动画)func equalBottom(target: UIView, offset: CGFloat = 0, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//UI控件左侧等于target左侧,offset为间距(支持动画)func equalLeft(target: UIView, offset: CGFloat = 0, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//UI控件右侧等于target右侧,offset为间距(支持动画)func equalRight(target: UIView, offset: CGFloat = 0, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//UI控件size等于target的size(支持动画)func equalSize(target: UIView, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//UI控件point等于target的point(支持动画)func equalPoint(target: UIView, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//UI控件宽度等于target的宽度(支持动画)func equalWidth(target: UIView, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//UI控件高度等于target的高度(支持动画)func equalHeight(target: UIView, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//UI控件rect等于target的rect(支持动画)func equalRect(target: UIView, animate: Bool = false, duration: TimeInterval = UIView.a_duration)//UI控件左侧位置为0func equalZeroLeft()//UI控件顶部位置为0func equalZeroTop()//UI控件左侧和顶部均为0func equalZeroTopAndLeft()//UI控件size等于屏幕的sizefunc equalScreenSize()//UI控件宽度等于屏幕宽度(offset为内间距)func equalScreenWidth(_ offset: CGFloat=0.0)//UI控件高度等于屏幕高度(offset为内间距)func equalScreenHeight(_ offset: CGFloat=0.0)
复制代码
批量布局
当两个控件间有多个属性相同,可以采用批量布局的方法
示例代码:
private let testLabel: UILabel = A.ui.lableprivate let testButton: UIButton = A.ui.button
override func a_Layout() { super.a_layout()
testLabel.size(widthHeight: 100.0) testLabel.top(top: 50.0) testLabel.left(left: 100.0) testLabel.target(testButton) testLabel.a_equals([ .width, .height, .top, .left ]) ...}
复制代码
支持批量设置的属性包括:
width、height、left、top、right、bottom、point、size、rect、backgroundColor、isHidden、alpha
layer 相关属性的快速设置
func layerCornerRadius(_ cornerRadius: CGFloat)func layerCornerCurve(_ cornerCurve: CALayerCornerCurve)func layerMasksToBounds(_ masksToBounds: Bool=true)func layerBorderWidth(_ borderWidth: CGFloat)func layerBorderColor(_ borderColor: UIColor)
复制代码
背景颜色的快速设置
func clearBackgroundColor()func whiteBackgroundColor()func blackBackgroundColor()func darkGrayBackgroundColor()func lightGrayBackgroundColor()func grayBackgroundColor()func redBackgroundColor()func greenBackgroundColor()func blueBackgroundColor()func cyanBackgroundColor()func yellowBackgroundColor()func magentaBackgroundColor()func orangeBackgroundColor()func purpleBackgroundColor()func brownBackgroundColor()//设置随机背景色func testBackgroundColor()
复制代码
批量设置 UI 控件
当多个 UI 控件具有相同的属性,可以将多个 UI 控件放入一个数组中,并直接处理数组。
示例代码:
override func a_UIConfig() { super.a_UIConfig()
let uiArray: [UIView] = [testButton, testLabel] uiArray.layerCornerRadius(8.0) uiArray.backgroundColor(0xFFFFFF.toColor) ...}
复制代码
支持批量设置的方法参见:Array++
UI 控件的添加和删除
框架支持单独添加 UI 控件和批量添加 UI 控件。在实际开发中,建议使用批量添加 UI 控件的方法。
示例代码:
private let testLabel: UILabel = A.ui.lableprivate let testButton: UIButton = A.ui.button
override func a_UI() { super.a_UI()
addSubViews(views:[ testLabel, testButton ])}
复制代码
UITableViewCell 也支持单独添加 UI 控件和批量添加 UI 控件。在实际开发中,建议使用批量添加 UI 控件的方法。
示例代码:
private let testLabel: UILabel = A.ui.lableprivate let testButton: UIButton = A.ui.button
override func a_UI() { super.a_UI()
addSubviewInContentView(views:[ testLabel, testButton ])}
复制代码
导航条的相关设置
继承于AViewController的UIViewController可以快速的设置导航条
框架提供的方法包括:
public var navigation_Title: Stringpublic var navigation_TitleView: UIView?public var navigation_LeftBarButton: UIButton?public var navigation_LeftBarButtonText: String?public var navigation_LeftBarButtonImage: UIImage?public var navigation_LeftBarButtonTintColor: UIColor?public var navigation_LeftBarButtonAction: Selector?public func navigation_LeftBarButtonSelector(executeBlock: (() -> Void)?)public var navigation_RightBarButton: UIButton?public var navigation_RightBarButtonText: String?public var navigation_RightBarButtonImage: UIImage?public var navigation_RightBarButtonTintColor: UIColor?public var navigation_RightBarButtonAction: Selector?public func navigation_RigthBarButtonSelector(executeBlock: (() -> Void)?)
复制代码
深色模式切换
框架提供了支持模式切换的功能。开发过程中,建议使用主题文件的形式。
实现模式切换的步骤如下:
制作主题类
重写 updateThemeStyle 方法
制作主题类
主题类需继承DesignColorProtocol协议。
DesignColorProtocol协议提供了标准的颜色定义。详细请查看 DesignColorProtocol 中的定义。
示例代码:
import UIKitimport Foundation
import Aquarius
class ColorDesign: DesignColorProtocol { var textPrimaryColor: UIColor { get { AThemeStyle.getThemeColor([ //普通模式颜色 .Light : 0xF2F2F2.toColor, //深色模式颜色 .Dark : 0x151F2E.toColor ]) } }
var primaryColor: UIColor { get { AThemeStyle.getThemeColor([ .Light : 0xF2F2F2.toColor, .Dark : 0x151F2E.toColor ]) } }
public static let shared = ColorDesign()}
复制代码
updateThemeStyle 方法
定义主题类后,AViewController和AView提供了 updateThemeStyle 方法。
再此方法中更新主题。
示例代码:
import UIKitimport Foundation
import Aquarius
class MainView: AView { public let testLabel: UILabel = A.ui.label public let testButton: UIButton = A.ui.button
override func a_UI() { super.a_UI()
addSubviews(views:[ testLabel, testButton ]) }
override func updateThemeStyle() { super.updateThemeStyle()
testLabel.textColor = ColorDesign.shared.textPrimaryColor testButton.backgroundColor = ColorDesign.shared.primaryColor }}
复制代码
示例中,当系统由普通模式转换为深色模式,或者由深色模式转换为普通模式时,继承AView或者AViewController的类将自动执行 updateThemeStyle 方法。
方法体将重新设置testLabel的 textColor 和testButton的 backgroundColor 属性。
textPrimaryColor和primaryColor将会根据主题类中的设置,自动判断是普通模式还是深色模式,并返回对应的颜色值。
getThemeColor 方法
不使用主题类的情况下,可以直接通过 getThemeColor 方法设置颜色
static func getThemeColor(_ themeColorDict: [AThemeStyleDarkModeType : UIColor]) -> UIColor
复制代码
示例代码:
import UIKitimport Foundation
import Aquarius
class MainView: AView { public let testLabel: UILabel = A.ui.label public let testButton: UIButton = A.ui.button
override func a_UI() { super.a_UI()
addSubviews(views:[ testLabel, testButton ]) }
override func updateThemeStyle() { super.updateThemeStyle()
testLabel.textColor = AThemeStyle.getThemeColor([ .Light : 0xF2F2F2.toColor, .Dark : 0x151F2E.toColor ]) testButton.backgroundColor = ColorDesign.shared.primaryColor }}
复制代码
格式转换
框架提供大部分的格式相互转换的简写方法。
示例代码:
//颜色转换let color: UIColor = 0xFFFFFF.toColor//Int字号转换let font1: UIFont = 18.toFontlet font2: UIFont = 18.toBoldFont//Int转CGFloatlet f: CGFloat = 18.toCGFloat//Int转NSNumberlet n: NSNumber = 18.toNumber//Int转Doublelet double: Double = 18.toDouble//字符串转日期(默认为完整日期,包括日期+时间)let date1: Date = "2025-05-10 18:00:00".toDate()//字符串转日期let date2: Date = "2025-05-10".toShortDate()//字符串转日期(包括日期+时间)let date3: Date = "2025-05-10".toLongDate()//字符串转图片let image1: UIImage = "name.png".toContentsOfFileImage()let image2: UIImage = "name.png".toNamedImage()let image3: UIImage = "setting.png".toSystemNameImage()//字符串转Intlet data: Int? = "1".toInt()//字符串转Boollet flag: Bool = "1".toBool()//字符串转CGFloatlet f: CGFloat = "1".toCGFloat()//字符串转Doublelet double: Double = "18.85".toDouble()//CGFloat转Fontlet font1: UIFont = 18.0.toFontlet font2: UIFont = 18.0.toBoldFont//CGFloat转字符串let string: String = 18.0.toString()//日期转Stringlet string1: String = Date().toString()let string2: String = Date().toShortEnglishString()let string3: String = Date().toShortChineseString()let string4: String = Date().toLongEnglishString()let string5: String = Date().toLongChineseString()let yearString: String = Date().toYearString()let year: Int? = Date().toYear()let monthString: String = Date().toMonthString()let month: Int? = Date().toMonth()let dayString: String = Date().toDayString()let day: Int? = Date().toDay()let time: String = Date().toTimeString()let hourString: String = Date().toHourString()let hour: Int? = Date().toHour()let minuteString: String = Date().toMinuteString()let minute: Int? = Date().toMinute()let secondString: String = Date().toSecondString()let second: Int? = Date().toSecond()//Bool转Intlet flag: Int = false.toInt()//Bool转Stringlet flagString: String = false.toString()//UIColor转Stringlet colorString: String = 0xFFFFFF.toHexString()//UIImage转Datalet data1: Data? = image.toJPEGData()let data2: Data? = image.toPNGData()//Data转UIImagelet image: UIImage? = data.toImage()
复制代码
依赖注入
框架基于KVO提供依赖注入功能。
依赖注入主要解决MVVM设计模式中Controller和viewModel之间的解耦问题
建议此类功能代码放到 a_Observe 中
TestVM
示例代码:
import Aquarius
class TestVM: AViewModel { //依赖注入的变量建议以kObserveTag开头 @objc dynamic public var kObserveTag_RefreshTableView: Bool = false ...}
复制代码
TestVC
示例代码:
import Aquarius
class TestVC: AViewController { private let viewModel: TestVM = TestVM()
override func a_Observe() { super.a_Observe()
self.viewModel.kvo = self.viewModel .observe(.kObserveTag_RefreshTableView, options: .new, changeHandler: { [weak self] (object, change) in if change.newValue! as Bool { ... } }) }}
复制代码
注意:建议将 observe 创建的实例保存到 viewModel.kvo 中,框架未来将提供自动管理 oberve 的能力
自动管理
当前,框架针对Delegate和Notification提供自动管理功能。
基于自动管理模块使用Delegate和Notification只需关心创建即可,框架将在页面销毁时,自动删除创建的Delegate和Notification
Delegate
建议此类功能代码放到 a_Delegate 中
AViewModel提供如下方法:
func Manage_SetDelegate(targetObject: AnyObject, delegateName: String, object: AnyObject)func Manage_SetDelegate(targetObject: AnyObject, delegateNames: Array<String>, object: AnyObject)func Manage_DeleteDelegate(object: AnyObject, delegateName: String)func Manage_DeleteDelegate(object: AnyObject, delegateNames: Array<String>)
复制代码
AProtocol提供如下方法:
public static let delegate: Stringpublic static let emptyDelegate: Stringpublic static let dataSource: Stringpublic static let delegateAndDataSource: [String]
复制代码
建议在Controller中使用。
TestView
示例代码:
class TestView: AView { public let testTableView: UITableView = A.ui.tableView ...}
复制代码
TestVC
示例代码:
class TestVC: AViewController { private let viewModel: TestVM = TestVM() private let a_view: TestView = TestView()
override func a_Delegate() { super.a_Delegate()
viewModel.Manage_SetDelegate( targetObject: a_view, delegateNames: AProtocol.delegateAndDataSource, object: self ) }
/* //另外两种写法 override func a_Delegate() { super.a_Delegate()
viewModel.Manage_SetDelegate( targetObject: a_view, delegateName: AProtocol.delegate, object: self )
viewModel.Manage_SetDelegate( targetObject: a_view, delegateName: AProtocol.dataSource, object: self ) }
override func a_Delegate() { super.a_Delegate()
viewModel.Manage_SetDelegate( targetObject: a_view, delegateName: "delegate", object: self )
viewModel.Manage_SetDelegate( targetObject: a_view, delegateName: "dataSource", object: self ) } */ ...}
复制代码
Notification
建议此类功能代码放到 a_Notification 中
AViewModel和AView提供如下方法:
func Manage_SetNotification(_ notificationName: String)func Manage_SetNotifications(_ notificationNames: Array<String>)func Manage_DeleteNotification(_ notificationName: String)func Manage_DeleteNotifications(_ notificationNames: Array<String>)func Manage_PostNotification(_ notificationName: String, object:[String : Any]?=nil)func Manage_PostNotifications(_ notificationNames: [String], objects: [[String : Any]?]?=nil)func ANotificationReceive(notification: Notification)
复制代码
TestView
示例代码:
class TestView: AView { private let testButton: UIButton = A.ui.button
override func a_Event() { super.a_Event()
testButton.addTouchUpInsideBlock { [weak self] result in self?.Manage_PostNotification( "notificationID", object: ANotification.packageCoreNotificationDataValue(value: "123") ) } } ...}
复制代码
TestVM
示例代码:
class TestVM: AViewModel { override func a_Notification() { Manage_SetNotification("notificationID") }
override func ANotificationReceive(notification: Notification) { super.ANotificationReceive(notification: notification)
if notification.isNotificationName("notificationID") { let paramString: String = notification.objectValue(ANotification.kANotificationData) as! String } } ...}
复制代码
立即体验 Aquarius:
第一步:探索资源
第二步:体验效果
第三步:沟通交流
评论