推荐一款Swift开发框架- Aquarius

news/2025/10/7 21:29:25/文章来源:https://www.cnblogs.com/jzxstudio/p/19128908

大家好,我是K哥。一名独立开发者,同时也是Swift开发框架【Aquarius】的作者,悦记爱寻车app的开发者。

Aquarius开发框架旨在帮助独立开发者和中小型团队,完成iOS App的快速实现与迭代。使用框架开发将给你带来简单、高效、易维护的编程体验。


介绍

大家好,我是K哥,一名10多年的iOS老鸟。Swift开发框架 - Aquarius作者,悦记和爱寻车两款app的开发者。

今天和大家推荐一下我开源的Swift开发框架 - Aquarius

Aquarius旨在帮助独立开发者和中小型团队,完成iOS App的快速实现与迭代。使用框架开发将给你带来简单、高效、易维护的编程体验。

希望这款开发框架能够帮助到大家。

框架地址:

https://github.com/JZXStudio/Aquarius
Aquarius.png

描述

Aquarius是以帮助独立开发者规范化开发流程,提高开发效率为目的而设计的Swift开发框架。

框架提供高效率、低侵入式的framework,既支持新的项目工程,也支持加入到老的工程中

框架本身不依赖任何三方类库,不会增大项目体积

框架以MVVM设计模式为核心,通过一系列定义的方法,提供新的开发方式

框架建议通过方法设置UI组件的属性,基于此原则,重新封装了大部分UI组件的属性

框架提供数据绑定功能,既支持变量间的动态数据更新,也支持变量与UI组件属性的动态数据更新

要求

  • iOS15.0
  • Swift5.x

新增功能

液态玻璃效果

新增按钮的液态玻璃效果。

液态玻璃效果包括:

  1. Glass
  2. ClearGlass
  3. ProminentGlass
  4. ProminentClearGlass

针对以上四种按钮液态玻璃效果,框架新增2个枚举类型,包括:

  1. LiquidGlassType

    1. glass
    2. clearGlass
    3. prominentGlass
    4. prominentClearGlass
  2. LiquidGlassConfig

    1. title
    2. attributedTitle
    3. subtitle
    4. attributedSubtitle
    5. titlePadding
    6. titleAlignment
    7. image
    8. imagePadding
    9. baseForegroundColor
    10. 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.button
var config: UIButton.Configuration = UIButton.Configuration.glass()
config.title = "test"
button.liquid(config)

设置液态玻璃类型,并做相关配置

示例:

let button: UIButton = A.ui.button
button.liguid(type: .glass, title: "test"...)

设置液态玻璃类型,并通过字典做相关配置

示例:

let type: LiquidGlassType = .glass
let config: [LiquidGlassConfig: Any] = [title : "test"
]
let button: UIButton = A.ui.button
button.liquid(type, config)

liquid_Glass

设置Glass液态玻璃类型,并做相关配置

示例:

let button: UIButton = A.ui.button
button.liguid_Glass(title: "test")

设置Glass液态玻璃类型,并通过字典做相关配置

let config: [LiquidGlassConfig : Any] = [.title : "test"
]
let button: UIButton = A.ui.button
button.liquid_Glass(config)

liquid_ClearGlass

设置ClearGlass液态玻璃类型,并做相关配置

示例:

let button: UIButton = A.ui.button
button.liguid_ClearGlass(title: "test")

设置ClearGlass液态玻璃类型,并通过字典做相关配置

let config: [LiquidGlassConfig : Any] = [.title : "test"
]
let button: UIButton = A.ui.button
button.liquid_ClearGlass(config)

liquid_prominentGlass

设置prominentGlass液态玻璃类型,并做相关配置

示例:

let button: UIButton = A.ui.button
button.liguid_prominentGlass(title: "test")

设置prominentGlass液态玻璃类型,并通过字典做相关配置

let config: [LiquidGlassConfig : Any] = [.title : "test"
]
let button: UIButton = A.ui.button
button.liquid_prominentGlass(config)

liquid_prominentClearGlass

设置prominentClearGlass液态玻璃类型,并做相关配置

示例:

let button: UIButton = A.ui.button
button.liguid_prominentClearGlass(title: "test")

设置prominentClearGlass液态玻璃类型,并通过字典做相关配置

let config: [LiquidGlassConfig : Any] = [.title : "test"
]
let button: UIButton = A.ui.button
button.liquid_prominentClearGlass(config)

核心功能

框架提供:

  1. MVVM设计模式

  2. 开发方法

  3. 数据绑定

  4. 处理UI的新方法

  5. 深色模式切换

  6. 格式转换

  7. 依赖注入

  8. 自动管理

  9. 工具

    1. 通知
    2. userDefaults
    3. 内购
    4. 日历/提醒
    5. 位置
    6. 日志
    7. Timer
    8. 格式化属性

MVVM设计模式

框架提供AViewAViewControllerAViewModel,开发中,需基于此三个基类开始开发。

AView

主要功能包括:

  1. 键盘管理
  2. 分层管理
  3. 事件管理
  4. Delegate管理
  5. 通知管理
  6. 数据绑定管理
  7. 日志管理
  8. 热更新管理

示例代码:

import Aquariusclass TestView: AView {}

AViewController

主要功能包括:

  1. 埋点
  2. 导航条管理
  3. 分层管理
  4. 主题管理
  5. 日志管理
  6. 热更新管理

示例代码:

import Aquariusclass TestViewController: AViewController {}

AViewModel

主要功能包括:

  1. 分层管理
  2. Delegate管理
  3. 通知管理
  4. 数据绑定管理
  5. 日志管理
  6. 热更新管理

示例代码:

import Aquariusclass TestVM: AViewModel {}

框架提供了代码的低侵入性,可以在老的工程中引入Aquarius。引入后,新开发的功能继承AViewAViewControllerAViewModel,老功能不受影响。

开发方法

洋葱开发法是作者为开发方法起的名字,方法主要将开发工作进行细分。

设计了多个方法,开发时只需要覆盖这些方法体,它们会自动执行。

AViewController

初始化中执行的方法包括:

  1. a_Preview:开始前执行
  2. a_Begin:开始执行时调用
  3. a_Navigation:定制化导航条
  4. a_Delegate:设置delegate
  5. updateThemeStyle:深色模式切换时调用
  6. a_Notification:设置通知
  7. a_Bind:设置数据绑定
  8. a_Observe:设置Observe
  9. a_Event:设置事件

viewDidLoad方法中执行的方法主要包括:

  1. a_UI:设置UI组件
  2. a_UIConfig:设置UI组件参数
  3. a_Layout:设置UI组件的布局
  4. a_Other:设置其它内容
  5. a_End:代码末尾执行
  6. a_Test:测试的代码函数,此函数值在debug模式下执行,发布后不执行

deinit方法中执行的方法包括:

  1. a_Clear:销毁时执行

AView

初始化中执行的方法包括:

  1. a_Preview:开始前执行
  2. a_Begin:开始执行时调用
  3. a_UI:设置UI组件
  4. a_UIConfig:设置UI组件参数
  5. a_Layout:设置UI组件的布局
  6. a_Notification:设置通知
  7. a_Delegate:设置delegate
  8. updateThemeStyle:深色模式切换时调用
  9. a_Bind:设置数据绑定
  10. a_Event:设置事件
  11. a_Other:设置其它内容
  12. a_End:代码末尾执行
  13. a_Test:测试的代码函数,此函数值在debug模式下执行,发布后不执行

deinit方法中执行的方法包括:

  1. a_Clear:销毁时执行

AViewModel

初始化中执行的方法包括:

  1. a_Preview:开始前执行
  2. a_Begin:开始执行时调用
  3. a_Notification:设置通知
  4. a_Delegate:设置delegate
  5. a_Observe:设置Observe
  6. a_Other:设置其它内容
  7. a_End:代码末尾执行
  8. a_Test:测试的代码函数,此函数值在debug模式下执行,发布后不执行

deinit方法中执行的方法包括:

  1. a_Clear:销毁时执行

ATableViewCell

初始化中执行的方法包括:

  1. a_Preview:开始前执行
  2. a_Begin:开始执行时调用
  3. a_UI:设置UI组件
  4. a_UIConfig:设置UI组件参数
  5. a_Layout:设置UI组件的布局
  6. updateThemeStyle:深色模式切换时调用
  7. a_Notification:设置通知
  8. a_Delegate:设置delegate
  9. a_Observe:设置Observe
  10. a_Bind:设置数据绑定
  11. a_Event:设置事件
  12. a_Other:设置其它内容
  13. a_End:代码末尾执行
  14. configWithCell(cellData: Any):cell接收数据时调用

deinit方法中执行的方法包括:

  1. a_Clear:销毁时执行

数据绑定

框架中AViewAViewModel,提供了数据绑定功能,帮助实现完全解耦的数据更新。

数据绑定主要提供如下方法:

bindableFrom(_ dict: Dictionary<String, String>)
bindablesFrom(_ o: Array<Dictionary<String, String>>)
bindableTo(_ dict: Dictionary<String, String>)
bindablesTo(_ o: Array<Dictionary<String, String>>)

方法需要联动使用。

bindableFrom、bindablesFrom,负责更新数据。

bindableTobindalbesTo,负责接收更新数据。

TestView

示例代码:

import UIKit
import Foundationimport Aquariusclass TestView: AView {private let testButton: UIButton = A.ui.button@objc dynamicprivate 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 inself?.testString = String.random(length: 16)}}
}

TestVM

示例代码:

import Foundationimport Aquariusclass TestVM: AViewModel {@objc dynamicprivate 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 UIKit
import Foundationimport Aquariusclass TestView: AView {private let testButton: UIButton = A.ui.buttonprivate let testLabel: UILabel = A.ui.labelprivate let testTableView: UITableView = A.ui.tableView...
}

UI布局

基础布局

UI控件提供如下基础布局属性和方法:

//获取UI控件顶端y值
func y() -> CGFloat
func top() -> CGFloat
//获取UI控件底端y值
func bottom() -> CGFloat
//获取UI控件左侧x值
func x() -> CGFloat
func left() -> CGFloat
//获取UI控件右侧y值
func right() -> CGFloat
//获取UI控件宽度
func width() -> CGFloat
//获取UI控件高度
func height() -> CGFloat
//获取UI控件的size
func size() -> CGSize
//获取UI控件的frame
func frame() -> CGRect
//获取UI控件中间点x坐标
func centerX() -> CGFloat
//获取UI控件中间点y坐标
func centerY() -> CGFloat
//获取屏幕的Size
func 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控件左侧位置为0
func equalZeroLeft()
//UI控件顶部位置为0
func equalZeroTop()
//UI控件左侧和顶部均为0
func equalZeroTopAndLeft()
//UI控件size等于屏幕的size
func equalScreenSize()
//UI控件宽度等于屏幕宽度(offset为内间距)
func equalScreenWidth(_ offset: CGFloat=0.0)
//UI控件高度等于屏幕高度(offset为内间距)
func equalScreenHeight(_ offset: CGFloat=0.0)

批量布局

当两个控件间有多个属性相同,可以采用批量布局的方法

示例代码:

private let testLabel: UILabel = A.ui.lable
private let testButton: UIButton = A.ui.buttonoverride 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])...
}

支持批量设置的属性包括:

widthheightlefttoprightbottompointsizerectbackgroundColorisHiddenalpha

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.lable
private let testButton: UIButton = A.ui.buttonoverride func a_UI() {super.a_UI()addSubViews(views:[testLabel,testButton])
}

UITableViewCell也支持单独添加UI控件和批量添加UI控件。在实际开发中,建议使用批量添加UI控件的方法。

示例代码:

private let testLabel: UILabel = A.ui.lable
private let testButton: UIButton = A.ui.buttonoverride func a_UI() {super.a_UI()addSubviewInContentView(views:[testLabel,testButton])
}

导航条的相关设置

继承于AViewControllerUIViewController可以快速的设置导航条

框架提供的方法包括:

public var navigation_Title: String
public 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)?)

深色模式切换

框架提供了支持模式切换的功能。开发过程中,建议使用主题文件的形式。

实现模式切换的步骤如下:

  1. 制作主题类
  2. 重写updateThemeStyle方法

制作主题类

主题类需继承DesignColorProtocol协议。

DesignColorProtocol协议提供了标准的颜色定义。详细请查看DesignColorProtocol中的定义。

示例代码:

import UIKit
import Foundationimport Aquariusclass 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方法

定义主题类后,AViewControllerAView提供了updateThemeStyle方法。

再此方法中更新主题。

示例代码:

import UIKit
import Foundationimport Aquariusclass MainView: AView {public let testLabel: UILabel = A.ui.labelpublic let testButton: UIButton = A.ui.buttonoverride func a_UI() {super.a_UI()addSubviews(views:[testLabel,testButton])}override func updateThemeStyle() {super.updateThemeStyle()testLabel.textColor = ColorDesign.shared.textPrimaryColortestButton.backgroundColor = ColorDesign.shared.primaryColor}
}

示例中,当系统由普通模式转换为深色模式,或者由深色模式转换为普通模式时,继承AView或者AViewController的类将自动执行updateThemeStyle方法。

方法体将重新设置testLabeltextColortestButtonbackgroundColor属性。

textPrimaryColorprimaryColor将会根据主题类中的设置,自动判断是普通模式还是深色模式,并返回对应的颜色值。

getThemeColor方法

不使用主题类的情况下,可以直接通过getThemeColor方法设置颜色

static func getThemeColor(_ themeColorDict: [AThemeStyleDarkModeType : UIColor]) -> UIColor

示例代码:

import UIKit
import Foundationimport Aquariusclass MainView: AView {public let testLabel: UILabel = A.ui.labelpublic let testButton: UIButton = A.ui.buttonoverride 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.toFont
let font2: UIFont = 18.toBoldFont
//Int转CGFloat
let f: CGFloat = 18.toCGFloat
//Int转NSNumber
let n: NSNumber = 18.toNumber
//Int转Double
let 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()
//字符串转Int
let data: Int? = "1".toInt()
//字符串转Bool
let flag: Bool = "1".toBool()
//字符串转CGFloat
let f: CGFloat = "1".toCGFloat()
//字符串转Double
let double: Double = "18.85".toDouble()
//CGFloat转Font
let font1: UIFont = 18.0.toFont
let font2: UIFont = 18.0.toBoldFont
//CGFloat转字符串
let string: String = 18.0.toString()
//日期转String
let 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转Int
let flag: Int = false.toInt()
//Bool转String
let flagString: String = false.toString()
//UIColor转String
let colorString: String = 0xFFFFFF.toHexString()
//UIImage转Data
let data1: Data? = image.toJPEGData()
let data2: Data? = image.toPNGData()
//Data转UIImage
let image: UIImage? = data.toImage()

依赖注入

框架基于KVO提供依赖注入功能。

依赖注入主要解决MVVM设计模式中ControllerviewModel之间的解耦问题

建议此类功能代码放到a_Observe

TestVM

示例代码:

import Aquariusclass TestVM: AViewModel {//依赖注入的变量建议以kObserveTag开头@objc dynamicpublic var kObserveTag_RefreshTableView: Bool = false...
}

TestVC

示例代码:

import Aquariusclass 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) inif change.newValue! as Bool {...}})}
}

注意:建议将observe创建的实例保存到viewModel.kvo中,框架未来将提供自动管理oberve的能力

自动管理

当前,框架针对DelegateNotification提供自动管理功能。

基于自动管理模块使用DelegateNotification只需关心创建即可,框架将在页面销毁时,自动删除创建的DelegateNotification

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: String
public static let emptyDelegate: String
public static let dataSource: String
public 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

AViewModelAView提供如下方法:

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.buttonoverride func a_Event() {super.a_Event()testButton.addTouchUpInsideBlock { [weak self] result inself?.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:

  • ⭐ Star & Fork 框架源码: GitHub - JZXStudio/Aquarius
  • 📱 下载示例APP: 悦记 | 爱寻车
  • 💌 联系与反馈: studio_jzx@163.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/930859.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1.如何导入Aquarius开发框架

Aquarius开发框架旨在帮助独立开发者和中小型团队,完成iOS App的快速实现与迭代。使用框架开发将给你带来简单、高效、易维护的编程体验。大家好,我是K哥。一名独立开发者,同时也是Swift开发框架【Aquarius】的作者…

课程作业(10月8日)

1.编写一个方法,使用以上算法生成指定数目(比如1000个)的随机整数。 public class PureRandomNumberGenerator { // 模数,即 2^31 - 1 private static final long MODULUS = 2147483647L; // 乘数 private static …

班级网站 php戴尔网站建设的目标

路由 vue-router 1.对路由的理解&#xff1a; vue的一个插件库&#xff0c;专门用来实现SPA应用 2.对SPA应用的理解&#xff1a; 1.单页web应用2.整个应用只有一个完整的页面&#xff08;index.html&#xff09;3.点击页面中的导航链接不会刷新页面&#xff0c;只做页面的局部…

帮宣——可控核聚变

本文从章鱼本人的博客转载而来 这是一个 \(GC\)!(\(Great\) \(Convenience\),极大便利) 众所周知,\(NKOJ\) 的评测机性能堪忧,评测速度较于各 \(OJ\) 存在不容轻视的差距,当大规模评测时更是有直接停止评测,从…

浅谈导数

引入 我们在初中学一次函数的时候,知道有一个东西叫做斜率。令在某一次函数上的两点分别为 \((x_0, y_0)\) , \((x_1,y_1)\) ,则它的表达式为 \(k = \large{\frac{x_0 - x_1}{y_0 - y_1}}\)。

洛谷P5304 [GXOI/GZOI2019] 旅行者(二进制分类技巧)

假设我们把特殊点分成 A,B 两个集合,新建 s 连 A 集合的所有点,边权 0 ,新建 t 连接 B 集合里的所有点,边权 0 ,那么 s 到 t 的最短路就是 A,B 集合点之间的最短路的最小值。 那么对于 k 个特殊点,我们枚举二进制…

【C++】AVL树的概念及完成(万字图文超详解)

【C++】AVL树的概念及完成(万字图文超详解)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &qu…

打造自主学习的AI Agent:强化学习+LangGraph代码示例

在充满不确定性的现实世界里,AI的价值不在于预设规则,而在于持续学习和适应AI Agent这个概念最近被炒得很热,从管理日程的语音助手到仓库里跑来跑去的机器人,大家都在谈论Agent的"自主性"。但是真正让Ag…

宁波网站优化技术免费推广渠道有哪些

源码地址:https://github.com/weilanhanf/PythonDesignPatterns 说明&#xff1a; 访问者模式的基本想法是&#xff0c;软件系统中拥有一个由许多对象构成的、比较稳定的对象结构&#xff0c;这些对象的类都拥有一个 accept 方法用来接受访问者对象的访问。访问者是一个接口&am…

NKOJ全TJ计划——NP11721

前言 我的做法也是成功的拿到了最优解,开一瓶可乐(其实只喝得起免费的学校饮用水)庆祝。顺便说一句,INTP男叫柯乐。但这显然并不是重点。 只是一个简单的小优化,大家可以看到,只有2行(显然不是章鱼的核聚变,不…

印度全球能力中心2030年展望与技术基建规划

印度工业联合会发布政策框架,建议各邦建立审批促进机构、设计财政激励措施,并投资高性能计算集群和数据中心等数字基础设施,预计到2030年全球能力中心可为印度经济贡献2000亿美元。印度全球能力中心2030年有望贡献2…

NOI Linux 食用教程

一、前置工作:安装虚拟机软件 + 下载 NOI Linux 镜像 1.安装 VMware(如果已经安装跳过即可) VWware,毫无疑问应该是目前最好用的免费虚拟机软件。 官方网站,官方最新版本,需要注册账号并登录 下载完就按照提示安…

营销运营主要做什么seo推广教学

七大原则网站地址&#xff1a;设计模式7大原则&#xff0b;类图关系-CSDN博客 创建型设计模式&#xff1a;创建型设计模式合集-CSDN博客 七大结构型设计模式&#xff1a;7大结构型设计模式-CSDN博客 11种行为型设计模式&#xff1a; 11种行为型模式&#xff08;上&#xff0…

详细介绍:基于 Android 和 JBox2D 的简单小游戏

详细介绍:基于 Android 和 JBox2D 的简单小游戏pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", …

CF2152H2 Victorious Coloring (Hard Version) 题解

Description 给定一棵有 \(n\) 个顶点的树,每个顶点编号为 \(1\) 到 \(n\)。每条边都被赋予一个正整数权值 \(w_1, w_2, \ldots, w_{n-1}\)。 一种“胜利染色”指的是将所有顶点染成红色或黄色两种颜色,其中必须至少…

题解:P6162 [Cnoi2020] 四角链

传送门 绝大多数的计数题都可以用 dp 和容斥解决。 本题的 dp 比较好想,设 \(f_{i,j}\) 表示前 \(i\) 个位置填了 \(j\) 个数。考虑如果第 \(i\) 个位置不填,则贡献是 \(f_{i-1,j}\);否则前面 \(i-1\) 个位置一共填…

题解:P3301 [SDOI2013] 方程

传送门 首先如果没有任何限制条件,则原问题即变为简单的「求方程 \(\sum_{i=1}^nx_i=m\) 的解的个数」。此时考虑插板法,等价于将 \(m\) 个 \(1\) 分成 \(n\) 份,这时有 \(m-1\) 个空隙,要插 \(n-1\) 个板,方案数…

# 20232321 2025-2026-1 《网络与系统攻防技术》实验一实验报告

1.实验内容1.1直接修改程序机器指令,改变程序执行流程————通过直接修改可执行文件改变流程 1.2通过构造输入参数,造成BOF攻击,改变程序执行流————通过利用缓冲区溢出的漏洞,使返回的地址跳转到getshell 1.…

基于深度学习的语音识别高效的系统设计与实现

基于深度学习的语音识别高效的系统设计与实现pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &qu…