Commit 8437ea60 authored by 禤美坚's avatar 禤美坚

初始化项目

parent 2c6f5142

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

......@@ -16,7 +16,7 @@ project.xcworkspace
xcuserdata
UserInterfaceState.xcuserstate
# CocoaPods
CocoaPods
Pods/
# Carthage
......
Pod::Spec.new do |s|
s.name = 'CaamDau'
s.version = '0.16.42'
s.summary = 'A iOS development toolbox (iOS 开发工具箱(模块组件) Swift 版).'
s.description = <<-DESC
TODO: iOS 开发组件 Swift 版:iOS项目开发通用&非通用型模块代码,多功能组件,可快速集成使用以大幅减少基础工作量;便利性扩展&链式扩展、UI排班组件Form、正则表达式扩展RegEx、计时器管理Timer、简易提示窗HUD、AppDelegate解耦方案、分页控制Page、自定义导航栏TopBar、阿里矢量图标管理IconFonts、MJRefresh扩展、Alamofire扩展......
附.各种类库使用示例demo.
DESC
s.homepage = 'https://github.com/liucaide/CaamDau'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'liucaide' => '565726319@qq.com' }
s.source = { :git => 'https://github.com/liucaide/CaamDau.git', :tag => s.version }
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
s.ios.deployment_target = '9.0'
s.swift_version = ['4.0', '4.2', '5.0']
# s.source_files = 'CaamDau/**/*'
s.default_subspec = 'Core'
s.subspec 'Core' do |ex|
ex.source_files = 'CaamDau/Core/*.swift',
'CaamDau/Extension/*.swift',
'CaamDau/RegEx/*.{swift}'
ex.dependency 'CaamDau/Value'
ex.dependency 'CaamDau/Form'
end
s.subspec 'Module' do |mo|
mo.dependency 'CaamDau/Core'
mo.dependency 'CaamDau/IBInspectable'
mo.dependency 'CaamDau/Timer'
mo.dependency 'CaamDau/InputBox'
mo.dependency 'CaamDau/IconFont'
mo.dependency 'CaamDau/Page'
mo.dependency 'CaamDau/TopBar'
mo.dependency 'CaamDau/AppDelegate'
mo.dependency 'CaamDau/Router'
mo.dependency 'CaamDau/HUD'
mo.dependency 'CaamDau/ViewModel/Core'
mo.dependency 'CaamDau/Indexes'
mo.dependency 'CaamDau/Calendar'
end
s.subspec 'All' do |all|
all.dependency 'CaamDau/Module'
all.dependency 'CaamDau/FDFullscreenPopGesture'
all.dependency 'CaamDau/MJRefresh'
all.dependency 'CaamDau/Net/All'
all.dependency 'CaamDau/ViewModel/BaseUI'
end
# ---- 核心插件 组件
s.subspec 'IBInspectable' do |ib|
ib.source_files = 'CaamDau/IBInspectable/*.{swift}'
end
s.subspec 'RegEx' do |rex|
rex.dependency 'CaamDau/Core'
end
s.subspec 'Form' do |form|
form.source_files = 'CaamDau/Form/*.{swift}'
end
s.subspec 'Timer' do |t|
t.source_files = 'CaamDau/Timer/*.{swift}'
t.dependency 'CaamDau/Core'
end
s.subspec 'Value' do |v|
v.source_files = 'CaamDau/Value/*.{swift}'
end
s.subspec 'AppDelegate' do |app|
app.source_files = 'CaamDau/AppDelegate/*.{swift}'
end
s.subspec 'IconFont' do |ifont|
ifont.source_files = 'CaamDau/IconFont/Classes/*.{swift}'
ifont.resource_bundles = {
'CaamDauIconFont' => ['CaamDau/IconFont/Assets/*.{ttf}']
}
ifont.dependency 'CaamDau/Core'
end
s.subspec 'TopBar' do |topbar|
topbar.source_files = 'CaamDau/TopBar/*.{swift}'
topbar.dependency 'CaamDau/Core'
topbar.dependency 'CaamDau/Value'
topbar.dependency 'CaamDau/IconFont'
topbar.dependency 'CaamDau/FDFullscreenPopGesture'
topbar.dependency 'SnapKit', '4.2.0'
end
s.subspec 'Page' do |page|
page.source_files = 'CaamDau/Page/*.{swift}'
page.dependency 'CaamDau/Core'
page.dependency 'CaamDau/FDFullscreenPopGesture'
page.dependency 'SnapKit'
end
s.subspec 'InputBox' do |input|
input.source_files = 'CaamDau/InputBox/Classes/*.{swift}'
input.dependency 'CaamDau/Core'
input.dependency 'SnapKit'
input.resource_bundles = {
'CaamDauInputBox' => ['CaamDau/InputBox/Nib/*.{xib}']
}
end
s.subspec 'HUD' do |hud|
hud.source_files = 'CaamDau/HUD/*.{swift}'
hud.dependency 'CaamDau/Core'
hud.dependency 'CaamDau/Timer'
hud.dependency 'CaamDau/IconFont'
hud.dependency 'SnapKit'
end
s.subspec 'ViewModel' do |vm|
vm.subspec 'Core' do |core|
core.source_files = 'CaamDau/ViewModel/Core/*.{swift}'
core.dependency 'CaamDau/Core'
end
vm.subspec 'BaseUI' do |bui|
bui.source_files = 'CaamDau/ViewModel/BaseUI/*.{swift}'
bui.dependency 'CaamDau/ViewModel/Core'
bui.dependency 'CaamDau/TopBar'
bui.dependency 'CaamDau/MJRefresh'
bui.dependency 'SnapKit'
end
end
s.subspec 'Router' do |rr|
rr.source_files = 'CaamDau/Router/*.{swift}'
rr.dependency 'CaamDau/Core'
end
s.subspec 'Indexes' do |indx|
indx.source_files = 'CaamDau/Indexes/*.{swift}'
indx.dependency 'CaamDau/Core'
indx.dependency 'SnapKit'
end
s.subspec 'Calendar' do |date|
date.source_files = 'CaamDau/Calendar/*.{swift}'
date.dependency 'CaamDau/Core'
date.dependency 'SnapKit'
end
# ---- 第三方 扩展 或 桥接
s.subspec 'MJRefresh' do |mj|
mj.source_files = 'CaamDau/MJRefresh/*.{swift}'
mj.dependency 'CaamDau/Core'
mj.dependency 'MJRefresh', '3.2.0'
end
s.subspec 'FDFullscreenPopGesture' do |fd|
fd.source_files = 'CaamDau/FDFullscreenPopGesture/*.{swift}'
fd.dependency 'CaamDau/Core'
fd.dependency 'FDFullscreenPopGesture'
end
s.subspec 'Net' do |net|
net.subspec 'Core' do |core|
core.source_files = 'CaamDau/NetWork/Core/*'
core.dependency 'Alamofire', '4.8.2'
core.dependency 'CaamDau/Core'
end
net.subspec 'All' do |all|
all.dependency 'CaamDau/Net/Core'
all.dependency 'CaamDau/Net/SwiftyJSON'
all.dependency 'CaamDau/Net/Cache'
all.dependency 'CaamDau/Net/Codable'
end
net.subspec 'SwiftyJSON' do |json|
json.source_files = 'CaamDau/NetWork/SwiftyJSON/*.{swift}'
json.dependency 'CaamDau/Net/Core'
json.dependency 'SwiftyJSON'
end
net.subspec 'Cache' do |cache|
cache.source_files = 'CaamDau/NetWork/Cache/*.{swift}'
cache.dependency 'CaamDau/Core'
cache.dependency 'CaamDau/Net/Core'
cache.dependency 'Cache','5.2.0'
end
net.subspec 'Codable' do |codable|
codable.source_files = 'CaamDau/NetWork/Codable/*.{swift}'
codable.dependency 'CaamDau/Net/Core'
codable.dependency 'CleanJSON'
end
end
s.frameworks = 'UIKit', 'Foundation'
# s.dependency 'Then'
end
This diff is collapsed.
# CD_AppDelegate
> AppDelegate 解耦
## Installation
CaamDau is available through [CocoaPods](https://cocoapods.org). To install
it, simply add the following line to your Podfile:
```ruby
pod 'CD/AppDelegate'
```
### AppDelegate
```
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
lazy var composite: CD_AppDelegateComposite = {
return CD_AppDelegateComposite([AppDelegate_VC(window),AppDelegate_UM()])
}()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return composite.application(application, didFinishLaunchingWithOptions:launchOptions)
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return composite.application(app, open: url, options: options)
}
}
```
### AppDelegate Modul
```
class AppDelegate_VC: CD_AppDelegate {
var window: UIWindow?
init(_ win: UIWindow?) {
window = win
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
let vc = VC_Tab.show()
window?.rootViewController = vc
window?.makeKeyAndVisible()
return true
}
}
```
```
class AppDelegate_UM: CD_AppDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return true
}
}
```
```
class AppDelegate_Notifications: CD_AppDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
}
}
```
- [参考](https://juejin.im/post/5bd0259d5188251a29719086#comment)
## Author
liucaide, 565726319@qq.com
## License
CaamDau is available under the MIT license. See the LICENSE file for more info.
This diff is collapsed.
//Created on 2019/10/9 by LCD:https://github.com/liucaide .
/***** 模块文档 *****
*
*/
import UIKit
import CaamDau
extension CD_DatePickerAlert {
public class func show(_ style:CD_DatePicker.Style = .yyyyMMdd, date:Date = Date(), preferredStyle:CD_DatePickerAlert.Style = .sheet, callback:((Date)->Void)? = nil, then:((CD_DatePickerAlert)->Void)? = nil) {
let vc = CD_DatePickerAlert()
vc.style = style
vc.preferredStyle = preferredStyle
vc.date = date
vc.callback = callback
then?(vc)
vc.modalTransitionStyle = .crossDissolve
vc.modalPresentationStyle = .custom
CD.present(vc)
}
}
public class CD_DatePickerAlert: UIViewController {
public enum Style {
case alert
case sheet
}
var preferredStyle:Style = .sheet
var callback:((Date)->Void)?
var style:CD_DatePicker.Style = .yyyyMMdd
var date:Date = Date()
public var minDate: Date?
public var maxDate: Date?
public var colorLine:UIColor = UIColor.cd_hex("c")
public var colorCancel:UIColor = .darkText
public var colorDone:UIColor = .darkText
public var font:UIFont = .systemFont(ofSize: 16)
public var action:(String, String) = ("取消", "确定")
lazy var view_bg:UIView = {
return UIView()
}()
override public func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.black.withAlphaComponent(0.3)
switch preferredStyle {
case .alert:
makeAlertUI()
case .sheet:
makeSheetUI()
}
}
override public func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
addAnimation(false)
}
func addAnimation(_ remove:Bool){
guard preferredStyle == .sheet else { return }
view_bg.superview?.layoutIfNeeded()
let value0 = view_bg.layer.position.y + CD.screenW
let value1 = view_bg.layer.position.y
let animote = CABasicAnimation(keyPath: "position.y")
animote.duration = 0.25
animote.isRemovedOnCompletion = false
animote.fillMode = .forwards
animote.fromValue = remove ? value1 : value0
animote.toValue = remove ? value0 : value1
animote.timingFunction = CAMediaTimingFunction(name: .easeOut)
view_bg.layer.add(animote, forKey: animote.keyPath)
}
func makeAlertUI() {
view_bg.cd
.corner(12, clips: true)
.background(.white)
.add(toSuperview: self.view)
.then({
$0.translatesAutoresizingMaskIntoConstraints = false
$0.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
$0.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
$0.heightAnchor.constraint(equalToConstant: 280*0.618).isActive = true
$0.widthAnchor.constraint(equalToConstant: 280).isActive = true
})
self.view.layoutIfNeeded()
let stack = UIStackView(frame: view_bg.bounds).cd
.axis(.vertical)
.add(toSuperview: view_bg)
.then{ _ in
}
.build
let picker = CD_DatePicker().cd
.add(toSuperstack: stack)
.build
picker.callback = { [weak self]date in
self?.date = date
}
picker.style = style
picker.minDate = minDate
picker.maxDate = maxDate
picker.date = date
UIView().cd
.background(colorLine)
.add(toSuperstack: stack)
.then {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.heightAnchor.constraint(equalToConstant: 0.5).isActive = true
}
UIStackView().cd
.axis(.horizontal)
.distribution(.fill)
.add(toSuperstack: stack)
.then {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.heightAnchor.constraint(equalToConstant: 45).isActive = true
let btn1 = UIButton().cd
.tag(1)
.text(font)
.text(colorCancel)
.text(action.0)
.add(toSuperstack: $0)
.build
btn1.addTarget(self, action: #selector(CD_DatePickerAlert.buttonClick(_:)), for: UIControl.Event.touchUpInside)
UIView().cd
.background(colorLine)
.add(toSuperstack: $0)
.then {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.widthAnchor.constraint(equalToConstant: 0.5).isActive = true
}
let btn2 = UIButton().cd
.tag(2)
.text(font)
.text(colorDone)
.text(action.1)
.add(toSuperstack: $0)
.then {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.widthAnchor.constraint(equalTo: btn1.widthAnchor, multiplier: 1).isActive = true
}
.build
btn2.addTarget(self, action: #selector(CD_DatePickerAlert.buttonClick(_:)), for: UIControl.Event.touchUpInside)
}
}
func makeSheetUI() {
view_bg.cd
.clips(true)
.background(.white)
.add(toSuperview: self.view)
.then({
$0.translatesAutoresizingMaskIntoConstraints = false
$0.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
$0.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
$0.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
$0.heightAnchor.constraint(equalToConstant: CD.screenW).isActive = true
})
self.view.layoutIfNeeded()
let stack = UIStackView(frame: view_bg.bounds).cd
.axis(.vertical)
.add(toSuperview: view_bg)
.then{ _ in
}
.build
UIStackView().cd
.axis(.horizontal)
.distribution(.fill)
.add(toSuperstack: stack)
.then {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.heightAnchor.constraint(equalToConstant: 45).isActive = true
UIStackView().cd
.axis(.horizontal)
.add(toSuperstack: $0)
.then {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.widthAnchor.constraint(equalToConstant: 15).isActive = true
}
let btn1 = UIButton().cd
.tag(1)
.text(font)
.text(colorCancel)
.text(action.0)
.add(toSuperstack: $0)
.build
btn1.addTarget(self, action: #selector(CD_DatePickerAlert.buttonClick(_:)), for: .touchUpInside)
UIStackView().cd.axis(.horizontal).add(toSuperstack: $0)
let btn2 = UIButton().cd
.tag(2)
.text(font)
.text(colorDone)
.text(action.1)
.add(toSuperstack: $0)
.build
btn2.addTarget(self, action: #selector(CD_DatePickerAlert.buttonClick(_:)), for: .touchUpInside)
UIStackView().cd
.axis(.horizontal)
.add(toSuperstack: $0)
.then {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.widthAnchor.constraint(equalToConstant: 15).isActive = true
}
}
UIView().cd
.background(colorLine)
.add(toSuperstack: stack)
.then {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.heightAnchor.constraint(equalToConstant: 0.5).isActive = true
}
let picker = CD_DatePicker().cd
.add(toSuperstack: stack)
.build
picker.callback = { [weak self]date in
self?.date = date
}
picker.style = style
picker.minDate = minDate
picker.maxDate = maxDate
picker.date = date
if #available(iOS 11.0, *) {
guard let b = CD.window?.safeAreaInsets.bottom, b > 0 else { return }
UIStackView().cd
.axis(.horizontal)
.add(toSuperstack: stack)
.then {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.heightAnchor.constraint(equalToConstant: b).isActive = true
}
} else {
}
}
@objc func buttonClick(_ sender:UIButton) {
switch sender.tag {
case 2:
callback?(date)
default:
addAnimation(true)
}
self.dismiss(animated: true, completion: nil)
}
}
//Created on 2019/10/8 by LCD:https://github.com/liucaide .
/***** 模块文档 *****
*
*/
import UIKit
open class CD_Picker: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
makeUI()
}
required public init?(coder: NSCoder) {
super.init(coder: coder)
makeUI()
}
lazy var picker: UIPickerView = {
let vv = UIPickerView(frame: self.bounds)
vv.delegate = self
vv.dataSource = self
return vv
}()
open var rows:[[Model]] = [] {
didSet {
picker.reloadAllComponents()
}
}
var _selects:[Int:String] = [:]
open var callback:((_ component:Int, _ row:Int, _ selects:[Int:String])->Void)?
func select(_ res:[Int:String], animated:Bool) {
_selects = res
for item in res where rows.count > item.key && !rows[item.key].isEmpty {
picker.selectRow(rows[item.key].firstIndex{ $0.title == item.value } ?? 0, inComponent: item.key, animated: animated)
}
}
func makeUI(){
self.addSubview(picker)
picker.translatesAutoresizingMaskIntoConstraints = false
picker.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
picker.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
picker.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
picker.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
}
}
extension CD_Picker: UIPickerViewDelegate, UIPickerViewDataSource {
public func numberOfComponents(in pickerView: UIPickerView) -> Int {
return rows.count
}
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return rows[component].count
}
/*
public func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return rows[component][row].title
}*/
public func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
let model = rows[component][row]
let ats = NSAttributedString(string: model.title, attributes: [.foregroundColor : model.isEnabled ? UIColor.darkText : UIColor.lightGray])
return ats
}
public func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
guard row < rows[component].count else { return }
_selects[component] = rows[component][row].title
callback?(component, row, _selects)
}
}
extension CD_Picker {
public struct Model {
public var title = ""
public var isEnabled = true
}
}
# Calendar 日历组件
## Installation
CaamDau is available through [CocoaPods](https://cocoapods.org). To install
it, simply add the following line to your Podfile:
```ruby
pod 'CaamDau/Calendar'
```
<p>
<img src="https://github.com/liucaide/Images/blob/master/CD/calendar0.png" width="20%" />
<img src="https://github.com/liucaide/Images/blob/master/CD/calendar1.png" width="20%" />
<img src="https://github.com/liucaide/Images/blob/master/CD/calendar2.png" width="20%" />
<img src="https://github.com/liucaide/Images/blob/master/CD/calendar3.png" width="20%" />
</p>
## Usage
#### 日期选择器
```ruby
CD_DatePickerAlert.show(.yyyyMMdd, date: Date(), preferredStyle: .sheet, callback: { (da) in
print_cd(da)
}) {
$0.colorLine = Config.color.line_1
$0.colorCancel = Config.color.txt_1
$0.colorDone = Config.color.main_1
$0.minDate = "2019-3-10".cd_date("yyyy-MM-dd")!
$0.maxDate = "2020-11-20".cd_date("yyyy-MM-dd")!
}
```
#### 日历
```ruby
```
## Author
liucaide, 565726319@qq.com
## License
CaamDau is available under the MIT license. See the LICENSE file for more info.
This diff is collapsed.
//Created on 2018/12/11 by LCD :https://github.com/liucaide .
import Foundation
public struct CaamDau<Base> {
public let base: Base
public init(_ base: Base) {
self.base = base
}
public var build: Base {
return base
}
}
public protocol CaamDauCompatible {
associatedtype CompatibleType
var cd: CompatibleType { get }
}
extension CaamDauCompatible {
public var cd: CaamDau<Self> {
return CaamDau(self)
}
}
extension NSObject: CaamDauCompatible {}
//Created on 2019/2/17 by LCD:https://github.com/liucaide .
/***** 模块文档 *****
*
*/
import Foundation
public extension Array {
/// 数组去重
func cd_filter<E: Equatable>(_ repeated: (Element) -> E) -> [Element] {
var result = [Element]()
self.forEach { (e) in
let key = repeated(e)
let keys = result.map{repeated($0)}
guard !keys.contains(key) else {return}
result.append(e)
}
return result
}
}
//Created on 2018/12/13 by LCD :https://github.com/liucaide .
import Foundation
import UIKit
public extension CaamDau where Base: Bundle {
}
public extension Bundle{
//MARK:--- Pod Bundle 检索 ----------
/// - from:bundle.url(forResource ‘(pod s.resource_bundles -> key)’
static func cd_bundle(_ forClass:AnyClass, _ from:String? = nil) -> Bundle? {
let bundle = Bundle(for: forClass)
guard let bundleURL = bundle.url(forResource: from, withExtension: "bundle") else {
//assertionFailure("👉👉👉\(from) - 无法找到 Bundle 👻")
return nil
}
return Bundle(url: bundleURL)
}
}
//Created on 2018/12/11 by LCD :https://github.com/liucaide .
import Foundation
import UIKit
public extension CGRect{
init(x:CGFloat = 0, y:CGFloat = 0, w:CGFloat = 0, h:CGFloat = 0) {
self.init(x: x, y: y, width: w, height: h)
}
}
public extension CGPoint{
init(xx:CGFloat = 0, yy:CGFloat = 0) {
self.init(x: xx, y: yy)
}
}
public extension CGSize{
init(w:CGFloat = 0, h:CGFloat = 0) {
self.init(width: w, height: h)
}
}
public extension UIEdgeInsets {
init(t:CGFloat = 0, l:CGFloat = 0, b:CGFloat = 0, r:CGFloat = 0) {
self.init(top: t, left: l, bottom: b, right: r)
}
}
public extension CGFloat {
static var auto:CGFloat {
return -66.66
}
}
//Created on 2019/2/28 by LCD:https://github.com/liucaide .
/***** 模块文档 *****
*
*/
import Foundation
import UIKit
public protocol CaamDauTextProtocol {
/// T: String、NSAttributedString、UIColor、NSTextAlignment、UIFont、、
func setText<T>(_ t: T?, _ state:UIControl.State?)
}
extension CaamDauTextProtocol {
/// T: String、NSAttributedString、UIColor、NSTextAlignment、UIFont、、
public func setText<T>(_ t: T?, _ state:UIControl.State?){
switch self {
case let ui as UILabel:
switch t {
case let txt as String:
ui.text = txt
case let attributed as NSAttributedString:
ui.attributedText = attributed
case let color as UIColor:
ui.textColor = color
case let alignment as NSTextAlignment:
ui.textAlignment = alignment
case let font as UIFont:
ui.font = font
default:
break
}
case let ui as UITextField:
switch t {
case let txt as String:
ui.text = txt
case let attributed as NSAttributedString:
ui.attributedText = attributed
case let color as UIColor:
ui.textColor = color
case let alignment as NSTextAlignment:
ui.textAlignment = alignment
case let font as UIFont:
ui.font = font
default:
break
}
case let ui as UITextView:
switch t {
case let txt as String:
ui.text = txt
case let attributed as NSAttributedString:
ui.attributedText = attributed
case let color as UIColor:
ui.textColor = color
case let alignment as NSTextAlignment:
ui.textAlignment = alignment
case let font as UIFont:
ui.font = font
default:
break
}
case let ui as UIButton:
switch t {
case let txt as String:
ui.setTitle(txt, for: state ?? .normal)
case let attributed as NSAttributedString:
ui.setAttributedTitle(attributed, for: state ?? .normal)
case let color as UIColor:
ui.setTitleColor(color, for: state ?? .normal)
case let font as UIFont:
ui.titleLabel?.font = font
default:
break
}
default:
break
}
}
}
public extension CaamDau where Base: CaamDauTextProtocol {
/// T: String、NSAttributedString、UIColor、NSTextAlignment、UIFont、、 state -> button use
@discardableResult
func text<T>(_ t: T?, _ state:UIControl.State? = .normal) -> CaamDau {
base.setText(t, state)
return self
}
}
extension UILabel: CaamDauTextProtocol {}
extension UIButton: CaamDauTextProtocol {}
extension UITextField: CaamDauTextProtocol {}
extension UITextView: CaamDauTextProtocol {}
//Created on 2019/3/7 by LCD:https://github.com/liucaide .
/***** 模块文档 *****
* 时间处理
*/
import Foundation
public extension Date {
enum CD_TimeSince {
case s1970
case s2001
case sNow
case s(_ date:Date)
var rawValue:Int {
switch self {
case .s1970:
return 1970
case .s2001:
return 2001
case .sNow:
return 1
case .s(let date):
return Int(date.cd_timestamp())
}
}
}
}
public extension TimeInterval {
/// 时间戳 转时间
func cd_date(_ since:Date.CD_TimeSince = .s1970) -> Date {
switch since {
case .s1970:
return Date(timeIntervalSince1970: self)
case .s2001:
return Date(timeIntervalSinceReferenceDate: self)
case .sNow:
return Date(timeIntervalSinceNow: self)
case .s(let d):
return Date(timeInterval: self, since: d)
}
}
/// 时间戳 相对时间转换
func cd_timestamp(_ from:Date.CD_TimeSince, _ to:Date.CD_TimeSince) -> TimeInterval {
return self.cd_date(from).cd_timestamp(to)
}
}
public extension Date {
/// Returns the timestamp or time interval
/// 时间戳 | 时间间隔 110.cd_date(.s2001).cd_timestamp(.sNow)
func cd_timestamp(_ since:CD_TimeSince = .s1970) -> TimeInterval {
switch since {
case .s1970:
return self.timeIntervalSince1970
case .s2001:
return self.timeIntervalSinceReferenceDate
case .sNow:
return self.timeIntervalSinceNow
case .s(let d):
return self.timeIntervalSince(d)
}
}
/// 转时间字符串
func cd_time(_ format:String = "yyyy-MM-dd HH:mm:ss:SSS") -> String {
let formatter = DateFormatter()
formatter.dateFormat = format
return formatter.string(from: self)
}
/// 转时间字符串
func cd_time(forStyle date:DateFormatter.Style = .none, time:DateFormatter.Style = .none) -> String {
let formatter = DateFormatter()
formatter.dateStyle = date
formatter.timeStyle = time
return formatter.string(from: self)
}
/// 时间 间隔
func cd_interval(_ to:Date, components: Set<Calendar.Component> = [.year, .month, .day, .hour, .minute, .second], calendar:Calendar = Calendar.current) -> DateComponents {
return calendar.dateComponents(components, from: self, to: to)
}
/// 单独取得时间中的单元,
/// 注意!当 .weekday 的时候,返回的是第几天而非周几,周日是第一天
/// calendar 默认 Calendar.current,可指定算法
func cd_component(_ component:Calendar.Component, calendar:Calendar = Calendar.current) -> Int {
return calendar.component(component, from: self)
}
/// 转日历 取得时间中的单元组,
func cd_components(_ components:Set<Calendar.Component> = [.year, .month, .day, .hour, .minute, .second], calendar:Calendar = Calendar.current) -> DateComponents {
return calendar.dateComponents(components, from: self)
}
func cd_count(of smaller: Calendar.Component, in larger: Calendar.Component, calendar:Calendar = Calendar.current) -> Int? {
return calendar.range(of: smaller, in: larger, for: self)?.count
}
}
public extension String {
func cd_date(_ format:String = "yyyy-MM-dd HH:mm:ss") -> Date? {
let formatter = DateFormatter()
formatter.dateFormat = format
return formatter.date(from: self)
}
}
//Created on 2019/2/17 by LCD:https://github.com/liucaide .
/***** 模块文档 *****
*
*/
import Foundation
//MARK:--- 重载运算符 两个字典合并为一个字典 ----------
public func += <key, value> ( cd_one: inout Dictionary<key, value>, cd_two: Dictionary<key, value>) {
for (k, v) in cd_two {
cd_one.updateValue(v, forKey: k)
}
}
public extension Dictionary {
}
//Created on 2019/6/3 by LCD:https://github.com/liucaide .
/***** 模块文档 *****
* CD_NotificationProtocol 通知管理协议 遵循此协议,更方便管理通知
* 示例
enum NoticeUser:String {
case login = "login"
}
extension NoticeUser:CD_NotificationProtocol {
var name: Notification.Name {
return Notification.Name("user."+self.rawValue)
}
}
class Test {
init() {
//Selector
NoticeUser.login.add(withSelector: #selector(notificationTo(_:)), observer: self, object: "123")
}
@objc func notificationTo(_ n:Notification) {
debugPrint(n)
}
deinit {
NoticeUser.login.remove(self)
}
}
//Block
NoticeUser.login.add { (n) in
debugPrint(n)
}
NoticeUser.login.post("123", userInfo: ["id":"456"])
*/
import Foundation
public protocol CaamDauNotificationProtocol {
var name: Notification.Name { get }
func post(_ object:Any?, userInfo:[AnyHashable:Any]?)
func add(withSelector selector: Selector, observer: Any, object: Any?)
func add(withBlock object: Any?, queue: OperationQueue?, block:@escaping (Notification) -> Void) -> NSObjectProtocol
func remove(_ observer: Any, object:Any?)
}
public extension CaamDauNotificationProtocol {
func post(_ object:Any? = nil, userInfo:[AnyHashable:Any]? = nil) {
NotificationCenter.default.post(name: name, object: object, userInfo: userInfo)
}
func add(withBlock object: Any? = nil, queue: OperationQueue? = .main, block: @escaping (Notification) -> Void) -> NSObjectProtocol {
return NotificationCenter.default.addObserver(forName: name, object: object, queue: queue, using: block)
}
func add(withSelector selector: Selector, observer: Any, object: Any? = nil) {
NotificationCenter.default.addObserver(observer, selector: selector, name: name, object: object)
}
func remove(_ observer: Any, object:Any? = nil) {
NotificationCenter.default.removeObserver(observer, name: name, object: object)
}
}
//MARK:--- RxSwift 扩展 ----------
extension CaamDauNotificationProtocol {
}
public extension Notification {
static func cd_post(name str:String, object:Any? = nil, userInfo:[AnyHashable : Any]? = nil) {
Notification.cd_post(notificationName: .cd_name(str), object: object, userInfo: userInfo)
}
static func cd_post(notificationName name:Notification.Name, object:Any? = nil, userInfo:[AnyHashable : Any]? = nil) {
CD.notice.post(name: name, object: object, userInfo: userInfo)
}
}
public extension Notification.Name {
static func cd_name(_ name:String) -> Notification.Name {
return Notification.Name(CD.appId + "." + name)
}
}
# CaamDau/Core
## Installation
CaamDau is available through [CocoaPods](https://cocoapods.org). To install
it, simply add the following line to your Podfile:
```ruby
pod 'CaamDau/Core'
```
>
####
```ruby
self.textLabel?.cd
.text("内容")
.text(Config.color.txt_2)
.text(Config.font.fontBold(13).fit())
```
## Author
liucaide, 565726319@qq.com
## License
CaamDau is available under the MIT license. See the LICENSE file for more info.
This diff is collapsed.
//Created on 2018/12/11 by LCD :https://github.com/liucaide .
import Foundation
import UIKit
public extension UIAlertController {
@discardableResult
static func cd_init(title: String? = nil, message: String? = nil, style : UIAlertController.Style = .alert) -> UIAlertController {
return UIAlertController(title: title, message: message, preferredStyle: style)
}
}
public extension CaamDau where Base: UIAlertController {
@discardableResult
func show(_ vc:UIViewController? = CD.visibleVC, block:(()->Void)? = nil) -> CaamDau {
if base.title == nil && base.message == nil && base.actions.count == 0 {
assertionFailure("👻💀大哥!你别什么东西都不放💀👻")
return self
}
vc?.present(base, animated: true, completion: block)
return self
}
@discardableResult
func hidden(_ time:TimeInterval, block:(()->Void)? = nil) -> CaamDau {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + time) { [weak base] in
base?.dismiss(animated: true, completion: block)
}
return self
}
@discardableResult
func title(_ a:String) -> CaamDau {
base.title = a
return self
}
@discardableResult
func title(_ font:UIFont) -> CaamDau {
let attributed:NSAttributedString = base.value(forKey: "attributedTitle") as? NSAttributedString ?? NSMutableAttributedString(string: base.title ?? "")
let attributedM = NSMutableAttributedString(attributedString: attributed)
attributedM.addAttribute(NSAttributedString.Key.font, value: font, range: NSMakeRange(0, attributedM.length))
base.setValue(attributedM, forKey: "attributedTitle")
return self
}
@discardableResult
func title(_ color:UIColor) -> CaamDau {
let attributed:NSAttributedString = base.value(forKey: "attributedTitle") as? NSAttributedString ?? NSMutableAttributedString(string: base.title ?? "")
let attributedM = NSMutableAttributedString(attributedString: attributed)
attributedM.addAttribute(NSAttributedString.Key.foregroundColor, value: color, range: NSMakeRange(0, attributedM.length))
base.setValue(attributedM, forKey: "attributedTitle")
return self
}
@discardableResult
func title(_ attributed:NSAttributedString) -> CaamDau {
base.setValue(attributed, forKey: "attributedTitle")
return self
}
@discardableResult
func message(_ a:String) -> CaamDau {
base.message = a
return self
}
@discardableResult
func message(_ font:UIFont) -> CaamDau {
let attributed:NSAttributedString = base.value(forKey: "attributedMessage") as? NSAttributedString ?? NSMutableAttributedString(string: base.message ?? "")
let attributedM = NSMutableAttributedString(attributedString: attributed)
attributedM.addAttribute(NSAttributedString.Key.font, value: font, range: NSMakeRange(0, attributedM.length))
base.setValue(attributedM, forKey: "attributedMessage")
return self
}
@discardableResult
func message(_ color:UIColor) -> CaamDau {
let attributed:NSAttributedString = base.value(forKey: "attributedMessage") as? NSAttributedString ?? NSMutableAttributedString(string: base.message ?? "")
let attributedM = NSMutableAttributedString(attributedString: attributed)
attributedM.addAttribute(NSAttributedString.Key.foregroundColor, value: color, range: NSMakeRange(0, attributedM.length))
base.setValue(attributedM, forKey: "attributedMessage")
return self
}
@discardableResult
func message(_ attributed:NSAttributedString) -> CaamDau {
base.setValue(attributed, forKey: "attributedMessage")
return self
}
@discardableResult
func action(_ title:String = "",
style:UIAlertAction.Style = .default,
custom:((UIAlertAction) -> Void)? = nil,
handler:((UIAlertAction) -> Void)? = nil) -> CaamDau {
let action = UIAlertAction(title: title, style: style, handler: handler)
custom?(action)
base.addAction(action)
return self
}
}
public extension CaamDau where Base: UIAlertAction {
@discardableResult
func title(_ a:String) -> CaamDau {
base.setValue(a, forKey: "title")
return self
}
@discardableResult
func title(_ color:UIColor) -> CaamDau {
base.setValue(color, forKey: "titleTextColor")
return self
}
@discardableResult
func style(_ a:UIAlertAction.Style) -> CaamDau {
base.setValue(a, forKey: "style")
return self
}
@discardableResult
func handler(_ a:((UIAlertAction) -> Void)? = nil) -> CaamDau {
base.setValue(a, forKey: "handler")
return self
}
}
//Created on 2018/12/11 by LCD :https://github.com/liucaide .
import Foundation
import UIKit
public extension CaamDau where Base: UIButton {
@discardableResult
func select(_ b: Bool) -> CaamDau {
base.isSelected = b
return self
}
@discardableResult
func line(breakMode mode: NSLineBreakMode) -> CaamDau {
base.titleLabel?.lineBreakMode = mode
return self
}
@discardableResult
func image(_ image: UIImage?, for state:UIControl.State = .normal) -> CaamDau {
base.setImage(image, for: state)
return self
}
@discardableResult
func background(_ image: UIImage?, for state:UIControl.State = .normal) -> CaamDau {
base.setBackgroundImage(image, for: state)
return self
}
@discardableResult
func attributed(_ title: NSAttributedString, for state:UIControl.State = .normal) -> CaamDau {
base.setAttributedTitle(title, for: state)
return self
}
@discardableResult
func title(_ edgeInsets: UIEdgeInsets) -> CaamDau {
base.titleEdgeInsets = edgeInsets
return self
}
@discardableResult
func title(edgeInsets top: CGFloat = 0, left:CGFloat = 0, bottom:CGFloat = 0, right:CGFloat = 0) -> CaamDau {
base.titleEdgeInsets = UIEdgeInsets(top: top, left: left, bottom: bottom, right: right)
return self
}
@discardableResult
func image(_ edgeInsets: UIEdgeInsets) -> CaamDau {
base.imageEdgeInsets = edgeInsets
return self
}
@discardableResult
func image(edgeInsets top: CGFloat = 0, left:CGFloat = 0, bottom:CGFloat = 0, right:CGFloat = 0) -> CaamDau {
base.imageEdgeInsets = UIEdgeInsets(top: top, left: left, bottom: bottom, right: right)
return self
}
@discardableResult
func contentAlignment(horizontal: UIControl.ContentHorizontalAlignment) -> CaamDau {
base.contentHorizontalAlignment = horizontal
return self
}
@discardableResult
func contentAlignment(vertical: UIControl.ContentVerticalAlignment) -> CaamDau {
base.contentVerticalAlignment = vertical
return self
}
@discardableResult
func imageViewContent(_ mode: UIView.ContentMode) -> CaamDau {
base.imageView?.contentMode = mode
return self
}
@discardableResult
func reverses(_ titleShadowWhenHighlighted: Bool) -> CaamDau {
base.reversesTitleShadowWhenHighlighted = titleShadowWhenHighlighted
return self
}
@discardableResult
func adjusts(imageWhenHighlighted a: Bool) -> CaamDau {
base.adjustsImageWhenHighlighted = a
return self
}
@discardableResult
func adjusts(imageWhenDisabled a: Bool) -> CaamDau {
base.adjustsImageWhenDisabled = a
return self
}
@discardableResult
func shows(_ touchWhenHighlighted: Bool) -> CaamDau {
base.showsTouchWhenHighlighted = touchWhenHighlighted
return self
}
@discardableResult
func loading(bgViewColor: UIColor = .clear,
bgViewFrame:CGRect = .zero,
style:UIActivityIndicatorView.Style = .gray,
activityColor:UIColor = .clear) -> CaamDau {
base.isEnabled = false
let activity = UIActivityIndicatorView(style: style)
activity.startAnimating()
let view = UIView()
view.tag = -8668
if bgViewFrame == .zero {
base.superview?.layoutIfNeeded()
view.frame = base.bounds
}else{
view.frame = bgViewFrame
}
if bgViewColor == .clear {
view.backgroundColor = bgViewColor
}else{
view.backgroundColor = base.backgroundColor
}
if activityColor != .clear {
activity.color = activityColor
}
activity.frame = view.bounds
base.addSubview(view)
view.addSubview(activity)
return self
}
@discardableResult
func loading(_ custom:(()->Void)) -> CaamDau {
base.isEnabled = false
custom()
return self
}
@discardableResult
func loadingHidden(_ tag:Int = -8668) -> CaamDau {
base.viewWithTag(tag)?.removeFromSuperview()
base.isEnabled = true
return self
}
}
//Created on 2019/2/28 by LCD:https://github.com/liucaide .
/***** 模块文档 *****
*
*/
import Foundation
import UIKit
public extension CaamDau where Base: UICollectionView {
@discardableResult
func background(view v: UIView?) -> CaamDau {
base.backgroundView = v
return self
}
@discardableResult
func layout(_ l: UICollectionViewLayout) -> CaamDau {
base.collectionViewLayout = l
return self
}
@discardableResult
func dataSource(_ d: UICollectionViewDataSource?) -> CaamDau {
base.dataSource = d
return self
}
@discardableResult
func delegate(_ d: UICollectionViewDelegate?) -> CaamDau {
base.delegate = d
return self
}
@discardableResult
func prefetch(dataSource d: UICollectionViewDataSourcePrefetching?) -> CaamDau {
if #available(iOS 10.0, *) {
base.prefetchDataSource = d
} else {
// Fallback on earlier versions
}
return self
}
@discardableResult
func isPrefetching(enabled e: Bool) -> CaamDau {
if #available(iOS 10.0, *) {
base.isPrefetchingEnabled = e
} else {
// Fallback on earlier versions
}
return self
}
}
public extension CaamDau where Base: UICollectionView {
public enum Kind:Int {
case tHeader = 0
case tFooter = 1
public var stringValue:String{
switch self {
case .tHeader:
return UICollectionView.elementKindSectionHeader
default:
return UICollectionView.elementKindSectionFooter
}
}
}
public enum View {
case tCell(_ cellClass:AnyClass, _ id:String?, _ bundleFrom:String?)
case tView(_ viewClass:AnyClass, _ id:String?, _ kind:Kind, _ bundleFrom:String?)
}
@discardableResult
func register(_ model:[View]) -> CaamDau {
for (_, item) in model.enumerated() {
switch item {
case .tCell(let cellClass, let id, let from):
let identifier = id ?? String(describing: cellClass)
let bundleFrom = from ?? ""
if bundleFrom.isEmpty {
let bundle = Bundle.main.path(forResource:identifier, ofType: "nib")
if bundle == nil{
base.register(cellClass, forCellWithReuseIdentifier: identifier)
}else{
let nib = UINib(nibName:identifier, bundle: nil)
base.register(nib, forCellWithReuseIdentifier: identifier)
}
}else{
let nib = UINib(nibName:identifier, bundle: Bundle.cd_bundle(cellClass, bundleFrom))
base.register(nib, forCellWithReuseIdentifier: identifier)
}
case .tView(let viewClass, let id, let kind, let from):
let identifier = id ?? String(describing: viewClass)
let bundleFrom = from ?? ""
if bundleFrom.isEmpty {
let bundle = Bundle.main.path(forResource:identifier, ofType: "nib")
if bundle == nil{
base.register(viewClass, forSupplementaryViewOfKind: kind.stringValue, withReuseIdentifier: identifier)
}else{
let nib = UINib(nibName:identifier, bundle: nil)
base.register(nib, forSupplementaryViewOfKind: kind.stringValue, withReuseIdentifier: identifier)
}
}else{
let nib = UINib(nibName:identifier, bundle: Bundle.cd_bundle(viewClass, bundleFrom))
base.register(nib, forSupplementaryViewOfKind: kind.stringValue, withReuseIdentifier: identifier)
}
}
}
return self
}
func cell(_ id:String, _ index:IndexPath) -> UICollectionViewCell{
return base.dequeueReusableCell(withReuseIdentifier: id, for: index)
}
func view(_ id:String,_ kind:Kind, _ index:IndexPath) -> UICollectionReusableView{
return base.dequeueReusableSupplementaryView(ofKind: kind.stringValue, withReuseIdentifier: id, for: index)
}
func view(_ id:String,_ kind:String, _ index:IndexPath) -> UICollectionReusableView{
return base.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: id, for: index)
}
}
//Created on 2019/2/17 by LCD:https://github.com/liucaide .
/***** 模块文档 *****
*
*/
import Foundation
import UIKit
public extension CaamDau where Base: UIColor {
@discardableResult
func alpha(_ a:CGFloat) -> CaamDau {
base.withAlphaComponent(a)
return self
}
public var hex:String {
let rgba = self.rgba
let rs:String = String(Int(rgba.0*255), radix: 16)
let gs:String = String(Int(rgba.1*255), radix: 16)
let bs:String = String(Int(rgba.2*255), radix: 16)
return "#" + rs + gs + bs
}
public var rgba:(CGFloat,CGFloat,CGFloat,CGFloat) {
var r:CGFloat = 0
var g:CGFloat = 0
var b:CGFloat = 0
var a:CGFloat = 1
base.getRed(&r, green: &g, blue: &b, alpha: &a)
return (r,g,b,a)
}
public var alpha:CGFloat {
return self.rgba.3
}
}
public extension UIColor {
convenience init(r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 1) {
self.init(red: CGFloat(r)/255.0, green: CGFloat(g)/255.0, blue: CGFloat(b)/255.0, alpha: a)
}
@discardableResult
func cd_alpha(_ a:CGFloat) -> UIColor {
return self.withAlphaComponent(a)
}
@discardableResult
static func cd_hex(_ hex:String) -> UIColor {
var str: String = hex.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).uppercased()
if str.hasPrefix("#") {
str = str[1..<7]
}else if str.hasPrefix("0X") {
str = str[2..<8]
}
// str[0..<6] 这是String的一个扩展需要在String扩展中找
str = str[0..<6]
let count = str.count
if count%2 == 0 {
for _ in 0..<(6-count)/2 {
str.append(str[count-2..<count])
}
}else{
for _ in 0..<6-count {
str.append(str[count-1..<count])
}
}
let sr = str[0..<2]
let sg = str[2..<4]
let sb = str[4..<6]
var r:CUnsignedInt = 0, g:CUnsignedInt = 0, b:CUnsignedInt = 0;
Scanner(string: sr).scanHexInt32(&r)
Scanner(string: sg).scanHexInt32(&g)
Scanner(string: sb).scanHexInt32(&b)
return UIColor(r: CGFloat(r), g: CGFloat(g), b: CGFloat(b))
}
var cd_hex:String {
let rgba = self.cd_rgba
let rs:String = String(Int(rgba.0*255), radix: 16)
let gs:String = String(Int(rgba.1*255), radix: 16)
let bs:String = String(Int(rgba.2*255), radix: 16)
return "#" + rs + gs + bs
}
var cd_rgba:(CGFloat,CGFloat,CGFloat,CGFloat) {
var r:CGFloat = 0
var g:CGFloat = 0
var b:CGFloat = 0
var a:CGFloat = 1
self.getRed(&r, green: &g, blue: &b, alpha: &a)
return (r,g,b,a)
}
var cd_alpha:CGFloat {
return self.cd_rgba.3
}
}
//Created on 2018/12/13 by LCD :https://github.com/liucaide .
import Foundation
import UIKit
public extension CaamDau where Base: UIFont {
var fit:UIFont {
base.withSize(base.pointSize+UIFont.cd_fontFitSizeRatio)
return base
}
func fit(_ size:CGFloat) -> UIFont {
base.withSize(base.pointSize+size)
return base
}
}
public extension UIFont {
public static var cd_fontFitSizeRatio:CGFloat = 0
func cd_fit(_ size:CGFloat = UIFont.cd_fontFitSizeRatio) -> UIFont {
return self.withSize(self.pointSize+size)
}
//MARK:--- IconFont ----------
/*
///IconFont 未使用pod 管理,需要在info.plist 中添加 Fonts provided by application
static func iconFont(name:String, size:CGFloat) -> UIFont {
guard let font = UIFont(name: name, size: size) else{
assertionFailure("👉👉👉IconFont-请确认\(name).ttf 和 font-family是否配置正确 👻")
return UIFont.systemFont(ofSize: size)
}
return font
}*/
///IconFont name:font-family forClass:class from: pod resource_bundles key
static func iconFont(_ name:String, size:CGFloat, forClass:AnyClass? = nil, from:String? = nil) -> UIFont {
if let clas = forClass, let bu = Bundle.cd_bundle(clas, from) {
let path = String(format: "%@/%@.ttf", bu.bundlePath, name)
return UIFont.iconFont(name, size: size, url:URL(fileURLWithPath: path))
}
else if let font = UIFont(name: name, size: size){
return font
}
else{
// 如果info.plist没有添加 Fonts provided by application 则可以直接检索 Bundle 读取
guard let url = Bundle.main.url(forResource: name, withExtension: "ttf") else {
assertionFailure("👉👉👉IconFont-请确认\(name).ttf 和 font-family是否配置正确 👻")
return UIFont.systemFont(ofSize: size)
}
return UIFont.iconFont(name, size: size, url:url)
}
}
///IconFont name:font-family url: Bundle url
static func iconFont(_ name:String, size:CGFloat, url:URL) -> UIFont {
guard let data = try? Data(contentsOf: url) else {
assertionFailure("👉👉👉IconFont- 失败 👻")
return UIFont.systemFont(ofSize: size)
}
guard let provider = CGDataProvider.init(data: data as CFData) else {
assertionFailure("👉👉👉IconFont- 失败 👻")
return UIFont.systemFont(ofSize: size)
}
guard let fontCG = CGFont(provider) else{
assertionFailure("👉👉👉IconFont- 失败 👻")
return UIFont.systemFont(ofSize: size)
}
CTFontManagerRegisterGraphicsFont(fontCG, nil)
guard let font = UIFont(name: name, size: size) else{
assertionFailure("👉👉👉IconFont-请确认\(name).ttf 和 font-family是否配置正确 👻")
return UIFont.systemFont(ofSize: size)
}
return font
}
}
//Created on 2018/12/13 by LCD :https://github.com/liucaide .
import Foundation
import UIKit
public extension CaamDau where Base: UIImage {
}
//MARK:--- pod 资源图片 ----------
public extension UIImage{
///- forClass:class from: pod resource_bundles key
///- from:bundle.url(forResource ‘(pod s.resource_bundles -> key)’
static func cd_bundle(_ name:String, forClass:AnyClass, from:String = "") -> UIImage {
let from = from.isEmpty ? String(describing: forClass) : from
return UIImage(named: name, in: Bundle.cd_bundle(forClass, from), compatibleWith: nil) ?? UIImage()
}
/// - 由颜色 生成图片
static func cd_color(_ color: UIColor) -> UIImage {
let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context?.setFillColor(color.cgColor)
context?.fill(rect)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return img!
}
}
//Created on 2018/12/11 by LCD :https://github.com/liucaide .
import Foundation
import UIKit
public extension CaamDau where Base: UIImageView {
@discardableResult
func image(_ a:UIImage?) -> CaamDau {
base.image = a
return self
}
@discardableResult
func highlighted(_ image:UIImage?) -> CaamDau {
base.highlightedImage = image
return self
}
@discardableResult
func isHighlighted(_ a:Bool) -> CaamDau {
base.isHighlighted = a
return self
}
@discardableResult
func animation(_ images:[UIImage]?) -> CaamDau {
base.animationImages = images
return self
}
@discardableResult
func highlighted(_ animationImages:[UIImage]?) -> CaamDau {
base.highlightedAnimationImages = animationImages
return self
}
@discardableResult
func animation(_ duration:TimeInterval) -> CaamDau {
base.animationDuration = duration
return self
}
@discardableResult
func animation(_ repeatCount:Int) -> CaamDau {
base.animationRepeatCount = repeatCount
return self
}
@discardableResult
func startAnimating() -> CaamDau {
base.startAnimating()
return self
}
@discardableResult
func stopAnimating() -> CaamDau {
base.stopAnimating()
return self
}
@discardableResult
func animation(_ images:[UIImage], duration:TimeInterval = 1, repeatCount:Int = 1) -> CaamDau {
base.animationImages = images
base.animationDuration = duration
base.animationRepeatCount = repeatCount
base.startAnimating()
return self
}
@discardableResult
func animation(_ names:[String], duration:TimeInterval = 1, repeatCount:Int = 1) -> CaamDau {
//let images:[UIImage] = try names.map{ UIImage(named: $0)}
var images:[UIImage] = []
for item in names {
guard let img = UIImage(named: item) else{
assertionFailure("👉👉👉 UIImage(named: \(item))错误,w请检查 names")
continue
}
images.append(img)
}
guard images.count > 0 else {
return self
}
base.animationImages = images
base.animationDuration = duration
base.animationRepeatCount = repeatCount
base.startAnimating()
return self
}
}
//Created on 2018/12/11 by LCD :https://github.com/liucaide .
import Foundation
import UIKit
public extension CaamDau where Base: UILabel {
@discardableResult
func number(_ ofLines: Int) -> CaamDau {
base.numberOfLines = ofLines
return self
}
@discardableResult
func line(_ breakMode:NSLineBreakMode) -> CaamDau {
base.lineBreakMode = breakMode
return self
}
@discardableResult
func baseline(_ adjustment:UIBaselineAdjustment) -> CaamDau {
base.baselineAdjustment = adjustment
return self
}
@discardableResult
func allows(_ defaultTighteningForTruncation:Bool) -> CaamDau {
base.allowsDefaultTighteningForTruncation = defaultTighteningForTruncation
return self
}
@discardableResult
func preferred(_ maxLayoutWidth:CGFloat) -> CaamDau {
base.preferredMaxLayoutWidth = maxLayoutWidth
return self
}
@discardableResult
func adjusts(_ fontSizeToFitWidth:Bool) -> CaamDau {
base.adjustsFontSizeToFitWidth = fontSizeToFitWidth
return self
}
@discardableResult
func highlighted(_ textColor:UIColor) -> CaamDau {
base.highlightedTextColor = textColor
return self
}
@discardableResult
func minimum(_ scaleFactor:CGFloat) -> CaamDau {
base.minimumScaleFactor = scaleFactor
return self
}
/*
@discardableResult
func line(_ spacing:CGFloat) -> CaamDau {
var textDic =
[NSAttributedString.Key.foregroundColor:base.textColor,
NSAttributedString.Key.font:base.font]
let style = NSMutableParagraphStyle()
style.lineSpacing = spacing
textDic[NSAttributedString.Key.paragraphStyle] = style
if base.text!.count > 0 {
base.attributedText = NSAttributedString(string: base.text!, attributes: textDic)
}
else if base.attributedText!.length > 0 {
var attStr = NSMutableAttributedString(attributedString: base.attributedText ?? NSAttributedString(string: base.text!))
attStr.setAttributes(textDic, range: NSMakeRange(0, base.attributedText!.length))
}
return self
}*/
}
//Created on 2018/12/13 by LCD :https://github.com/liucaide .
import Foundation
import UIKit
public extension UINib{
static func cd_xib(_ name:String? = nil, from:String? = nil) -> UINib? {
return UINib(nibName: name ?? String(describing: self), bundle: Bundle.cd_bundle(self, from))
}
}
//Created on 2019/2/28 by LCD:https://github.com/liucaide .
/***** 模块文档 *****
*
*/
import Foundation
import UIKit
public extension CaamDau where Base: UIScrollView {
@discardableResult
func delegate(_ d: UIScrollViewDelegate?) -> CaamDau {
base.delegate = d
return self
}
@discardableResult
func content(offset p: CGPoint) -> CaamDau {
base.contentOffset = p
return self
}
@discardableResult
func content(size s: CGSize) -> CaamDau {
base.contentSize = s
return self
}
@discardableResult
func content(inset i: UIEdgeInsets) -> CaamDau {
base.contentInset = i
return self
}
@available(iOS 11.0, *)
@discardableResult
func content(insetAdjustmentBehavior i: UIScrollView.ContentInsetAdjustmentBehavior) -> CaamDau {
base.contentInsetAdjustmentBehavior = i
return self
}
@discardableResult
func isDirectional(lockEnabled l: Bool) -> CaamDau {
base.isDirectionalLockEnabled = l
return self
}
@discardableResult
func bounces(_ b: Bool) -> CaamDau {
base.bounces = b
return self
}
@discardableResult
func always(bounceVertical b: Bool) -> CaamDau {
base.alwaysBounceVertical = b
return self
}
@discardableResult
func always(bounceHorizontal b: Bool) -> CaamDau {
base.alwaysBounceHorizontal = b
return self
}
@discardableResult
func isPaging(enabled e: Bool) -> CaamDau {
base.isPagingEnabled = e
return self
}
@discardableResult
func isScroll(enabled e: Bool) -> CaamDau {
base.isScrollEnabled = e
return self
}
@discardableResult
func shows(horizontalScrollIndicator b: Bool) -> CaamDau {
base.showsHorizontalScrollIndicator = b
return self
}
@discardableResult
func shows(verticalScrollIndicator b: Bool) -> CaamDau {
base.showsVerticalScrollIndicator = b
return self
}
@discardableResult
func scroll(indicatorInsets i: UIEdgeInsets) -> CaamDau {
base.scrollIndicatorInsets = i
return self
}
@discardableResult
func indicator(style s: UIScrollView.IndicatorStyle) -> CaamDau {
base.indicatorStyle = s
return self
}
@discardableResult
func deceleration(rate r: UIScrollView.DecelerationRate) -> CaamDau {
base.decelerationRate = r
return self
}
@discardableResult
func index(displayMode m: UIScrollView.IndexDisplayMode) -> CaamDau {
base.indexDisplayMode = m
return self
}
@discardableResult
func set(contentOffset p:CGPoint, _ animated:Bool = true) -> CaamDau {
base.setContentOffset(p, animated: animated)
return self
}
@discardableResult
func scroll(rectToVisible r:CGRect, _ animated:Bool = true) -> CaamDau {
base.scrollRectToVisible(r, animated: animated)
return self
}
@discardableResult
func flashScrollIndicators() -> CaamDau {
base.flashScrollIndicators()
return self
}
@discardableResult
func delays(contentTouches b:Bool) -> CaamDau {
base.delaysContentTouches = b
return self
}
@discardableResult
func canCancel(contentTouches b:Bool) -> CaamDau {
base.canCancelContentTouches = b
return self
}
@discardableResult
func bounces(zoom b:Bool) -> CaamDau {
base.bouncesZoom = b
return self
}
@discardableResult
func scrollsToTop(_ b:Bool = true) -> CaamDau {
base.scrollsToTop = b
return self
}
@discardableResult
func min(imumZoomScale a:CGFloat) -> CaamDau {
base.minimumZoomScale = a
return self
}
@discardableResult
func max(imumZoomScale a:CGFloat) -> CaamDau {
base.maximumZoomScale = a
return self
}
@discardableResult
func zoom(scale a:CGFloat) -> CaamDau {
base.maximumZoomScale = a
return self
}
@discardableResult
func set(zoomScale a:CGFloat, _ animated:Bool = true) -> CaamDau {
base.setZoomScale(a, animated: animated)
return self
}
@discardableResult
func zoom(toRect a:CGRect, _ animated:Bool = true) -> CaamDau {
base.zoom(to: a, animated: animated)
return self
}
@discardableResult
func keyboard(dismissMode a:UIScrollView.KeyboardDismissMode) -> CaamDau {
base.keyboardDismissMode = a
return self
}
@available(iOS 10.0, *)
@discardableResult
func refresh(control a:UIRefreshControl?) -> CaamDau {
base.refreshControl = a
return self
}
/// 右滑返回
@discardableResult
func panBack(_ gesture: UIGestureRecognizer, otherGesture:UIGestureRecognizer) -> Bool {
if base.contentOffset.x <= 0,
let delegate = otherGesture.delegate,
let fdFulls = NSClassFromString("_FDFullscreenPopGestureRecognizerDelegate").self,
delegate.isKind(of: fdFulls) {
return true
}
else if gesture == base.panGestureRecognizer,
let pan:UIPanGestureRecognizer = gesture as? UIPanGestureRecognizer {
let point = pan.translation(in: base)
let state = pan.state
if state == .began || state == .possible {
let location = pan.location(in: base)
if point.x >= 0 && location.x < 60 && base.contentOffset.x <= 0 {
return true
}
}
}
return false
}
}
//Created on 2018/12/11 by LCD :https://github.com/liucaide .
import Foundation
import UIKit
public extension CaamDau where Base: UIStackView {
@discardableResult
func addArranged(subview view: UIView) -> CaamDau {
base.addArrangedSubview(view)
return self
}
@discardableResult
func removeArranged(subview view: UIView) -> CaamDau {
base.removeArrangedSubview(view)
return self
}
@discardableResult
func insertArranged(subview view: UIView, at:Int) -> CaamDau {
base.insertArrangedSubview(view, at: at)
return self
}
@discardableResult
func axis(_ a: NSLayoutConstraint.Axis) -> CaamDau {
base.axis = a
return self
}
@discardableResult
func distribution(_ a: UIStackView.Distribution) -> CaamDau {
base.distribution = a
return self
}
@discardableResult
func alignment(_ a: UIStackView.Alignment) -> CaamDau {
base.alignment = a
return self
}
@discardableResult
func spacing(_ a: CGFloat) -> CaamDau {
base.spacing = a
return self
}
@discardableResult
@available(iOS 11.0, *)
func custom(_ spacing: CGFloat, after arrangedSubview: UIView) -> CaamDau {
base.setCustomSpacing(spacing, after: arrangedSubview)
return self
}
@discardableResult
func a(_ a: UIView) -> CaamDau {
return self
}
@discardableResult
func isBaselineRelativeArrangement(_ a: Bool) -> CaamDau {
base.isBaselineRelativeArrangement = a
return self
}
@discardableResult
func isLayoutMarginsRelativeArrangement(_ a: Bool) -> CaamDau {
base.isLayoutMarginsRelativeArrangement = a
return self
}
}
This diff is collapsed.
//Created on 2018/12/13 by LCD :https://github.com/liucaide .
import Foundation
import UIKit
public extension CaamDau where Base: UITableView {
@discardableResult
func estimatedAll(_ height:CGFloat = CGFloat.leastNormalMagnitude) -> CaamDau {
if #available(iOS 11.0, *) {
base.contentInsetAdjustmentBehavior = .never
base.estimatedRowHeight = height
base.estimatedSectionHeaderHeight = height
base.estimatedSectionFooterHeight = height
}else{
let height = height >= 2 ? height : 2
base.estimatedRowHeight = height
base.estimatedSectionHeaderHeight = height
base.estimatedSectionFooterHeight = height
}
base.rowHeight = UITableView.automaticDimension
base.sectionHeaderHeight = UITableView.automaticDimension
base.sectionFooterHeight = UITableView.automaticDimension
return self
}
@discardableResult
func dataSource(_ d: UITableViewDataSource?) -> CaamDau {
base.dataSource = d
return self
}
@discardableResult
func delegate(_ d: UITableViewDelegate?) -> CaamDau {
base.delegate = d
return self
}
@available(iOS 10.0, *)
@discardableResult
func prefetch(dataSource d: UITableViewDataSourcePrefetching?) -> CaamDau {
base.prefetchDataSource = d
return self
}
@available(iOS 11.0, *)
@discardableResult
func drag(delegate d: UITableViewDragDelegate?) -> CaamDau {
return self
}
@available(iOS 11.0, *)
@discardableResult
func drop(delegate d: UITableViewDropDelegate?) -> CaamDau {
base.dropDelegate = d
return self
}
@discardableResult
func background(view v: UIView?) -> CaamDau {
base.backgroundView = v
return self
}
@discardableResult
func table(headerView v: UIView?) -> CaamDau {
base.tableHeaderView = v
return self
}
@discardableResult
func table(footerView v: UIView?) -> CaamDau {
base.tableFooterView = v
return self
}
@discardableResult
func row(height h: CGFloat) -> CaamDau {
base.rowHeight = h
return self
}
@discardableResult
func section(headerHeight h: CGFloat) -> CaamDau {
base.sectionHeaderHeight = h
return self
}
@discardableResult
func section(footerHeight h: CGFloat) -> CaamDau {
base.sectionFooterHeight = h
return self
}
@discardableResult
func estimated(rowHeight h: CGFloat) -> CaamDau {
base.estimatedRowHeight = h
return self
}
@discardableResult
func estimated(sectionHeaderHeight h: CGFloat) -> CaamDau {
base.estimatedSectionHeaderHeight = h
return self
}
@discardableResult
func estimated(sectionFooterHeight h: CGFloat) -> CaamDau {
base.estimatedSectionFooterHeight = h
return self
}
@discardableResult
func section(indexColor c: UIColor?) -> CaamDau {
base.sectionIndexColor = c
return self
}
@discardableResult
func section(indexBackgroundColor c: UIColor?) -> CaamDau {
base.sectionIndexBackgroundColor = c
return self
}
@discardableResult
func section(indexTrackingBackgroundColor c: UIColor?) -> CaamDau {
base.sectionIndexTrackingBackgroundColor = c
return self
}
@discardableResult
func section(indexMinimumDisplayRowCount c: Int) -> CaamDau {
base.sectionIndexMinimumDisplayRowCount = c
return self
}
@discardableResult
func separator(style s: UITableViewCell.SeparatorStyle) -> CaamDau {
base.separatorStyle = s
return self
}
@discardableResult
func separator(color c: UIColor?) -> CaamDau {
base.separatorColor = c
return self
}
@discardableResult
func separator(inset i: UIEdgeInsets) -> CaamDau {
base.separatorInset = i
return self
}
@available(iOS 11.0, *)
@discardableResult
func separator(insetReference i: UITableView.SeparatorInsetReference) -> CaamDau {
base.separatorInsetReference = i
return self
}
}
public extension CaamDau where Base: UITableView {
func cell(_ cellClass:AnyClass, id:String = "", bundleFrom:String = "") -> UITableViewCell? {
let identifier = id=="" ? String(describing: cellClass) : id
var cell = base.dequeueReusableCell(withIdentifier: identifier)
if cell == nil {
if bundleFrom.isEmpty {
let bundle = Bundle.main.path(forResource:identifier, ofType: "nib")
if bundle == nil{
base.register(cellClass, forCellReuseIdentifier: identifier)
}else{
let nib = UINib(nibName:identifier, bundle: nil)
base.register(nib, forCellReuseIdentifier: identifier)
}
}else{
let nib = UINib(nibName:identifier, bundle: Bundle.cd_bundle(cellClass, bundleFrom))
base.register(nib, forCellReuseIdentifier: identifier)
}
cell = base.dequeueReusableCell(withIdentifier: identifier)
}
guard let ce = cell else {
assertionFailure("👉👉👉dequeueReusableCell 失败,请检查你的cell 👻")
return nil
}
return ce
}
func view(_ viewClass:AnyClass, id:String = "", bundleFrom:String = "") -> UITableViewHeaderFooterView? {
let identifier = id=="" ? String(describing: viewClass) : id
var cell = base.dequeueReusableHeaderFooterView(withIdentifier: identifier)
if cell == nil {
if bundleFrom.isEmpty {
let bundle = Bundle.main.path(forResource:identifier, ofType: "nib")
if bundle == nil{
base.register(viewClass, forHeaderFooterViewReuseIdentifier: identifier)
}else{
let nib = UINib(nibName:identifier, bundle: nil)
base.register(nib, forHeaderFooterViewReuseIdentifier: identifier)
}
}else{
let nib = UINib(nibName:identifier, bundle: Bundle.cd_bundle(viewClass, bundleFrom))
base.register(nib, forHeaderFooterViewReuseIdentifier: identifier)
}
cell = base.dequeueReusableHeaderFooterView(withIdentifier: identifier)
}
guard let ce = cell else {
assertionFailure("👉👉👉dequeueReusableHeaderFooterView 失败,请检查你的View 👻")
return nil
}
return ce
}
}
public extension UITableView {
}
This diff is collapsed.
This diff is collapsed.
//Created on 2018/12/11 by LCD :https://github.com/liucaide .
import Foundation
import UIKit
public extension UIViewController{
enum UIViewControllerError:Error {
case noBundle
}
static func cd_storyboard(_ name:String = "Main", id:String = "") -> UIViewController {
let identifier = id == "" ? String(describing: self) : id
return UIStoryboard(name: name, bundle: nil).instantiateViewController(withIdentifier: identifier)
}
/// - from:bundle.url(forResource (s.resource_bundles -> key) ; name:storyboard name
static func cd_storyboard(_ name:String, id:String = "", from:String? = nil) -> UIViewController? {
let identifier = id.isEmpty ? String(describing: self) : id
let storyboard = UIStoryboard(name: name, bundle: Bundle.cd_bundle(self, from) ?? Bundle.main)
return storyboard.instantiateViewController(withIdentifier: identifier)
}
}
//Created on 2019/6/3 by LCD:https://github.com/liucaide .
/***** 模块文档 *****
* UserDefaults 管理协议 遵循此协议,更方便管理
* 示例
enum UserDefaulsUser:String {
case token = "token"
}
extension UserDefaulsUser:CD_NotificationProtocol {
var name: String {
return "user."+self.rawValue
}
}
UserDefaulsUser.token.save("123")
*/
import Foundation
public protocol CaamDauUserDefaultsProtocol {
var name: String { get }
var value:Any? {get}
var string:String? {get}
var bool:Bool {get}
var dictionary:[String:Any]? {get}
var array:[Any]? {get}
func save(_ value:Any?)
func remove()
}
extension CaamDauUserDefaultsProtocol {
public var value:Any? {
return UserDefaults.standard.value(forKey: name)
}
public var string:String? {
return UserDefaults.standard.string(forKey: name)
}
public var bool:Bool {
return UserDefaults.standard.bool(forKey: name)
}
public var dictionary:[String:Any]? {
return UserDefaults.standard.dictionary(forKey: name)
}
public var array:[Any]? {
return UserDefaults.standard.array(forKey: name)
}
public func save(_ value:Any?) {
UserDefaults.standard.set(value, forKey: name)
UserDefaults.standard.synchronize()
}
public func remove() {
UserDefaults.standard.removeObject(forKey: name)
}
}
//Created on 2019/3/25 by LCD:https://github.com/liucaide .
/***** 模块文档 *****
* 这是对 FDFullscreenPopGesture 的桥接
* https://github.com/forkingdog/FDFullscreenPopGesture
*/
import UIKit
import FDFullscreenPopGesture
public extension CaamDau where Base: UINavigationController {
/// 导航栏滑动手势、处理用户的侧滑弹出操作
public var gestureRecognizer:UIPanGestureRecognizer {
get{
return base.fd_fullscreenPopGestureRecognizer
}
}
///视图控制器可以自己控制,而不是全局的方式控制,导航栏的外观。,默认是YES
public var navigationBarAppearanceEnabled:Bool {
get{
return base.fd_viewControllerBasedNavigationBarAppearanceEnabled
}
}
///视图控制器可以自己控制,而不是全局的方式控制,导航栏的外观。,默认是YES
@discardableResult
func navigationBar(appearanceEnabled b: Bool) -> CaamDau {
base.fd_viewControllerBasedNavigationBarAppearanceEnabled = b
return self
}
}
public extension CaamDau where Base: UIViewController {
///viewcontroller的侧滑功能是否禁用 默认启用
public var popDisabled:Bool {
get{
return base.fd_interactivePopDisabled
}
}
///viewcontroller的侧滑功能是否禁用 默认启用
@discardableResult
func pop(disabled b: Bool) -> CaamDau {
base.fd_interactivePopDisabled = b
return self
}
/// 导航栏是否隐藏
public var navigationBarHidden:Bool {
get{
return base.fd_prefersNavigationBarHidden
}
}
/// 导航栏是否隐藏
@discardableResult
func navigationBar(hidden b: Bool) -> CaamDau {
base.fd_prefersNavigationBarHidden = b
return self
}
}
//Created on 2018/12/13 by LCD :https://github.com/liucaide .
import Foundation
public struct CD_Form {
public var rows:[CD_RowProtocol]
public init(_ rows:[CD_RowProtocol] = []) {
self.rows = rows
}
public mutating func append(_ row:CD_RowProtocol) {
self.rows.append(row)
}
public mutating func insert(_ row:CD_RowProtocol, at:Int) {
self.rows.insert(row, at: at)
}
}
//Created on 2018/12/13 by LCD :https://github.com/liucaide .
import Foundation
public class CD_TableViewCellBase: UITableViewCell{
public static let id:String = "CD_CollectionViewCellNone"
public static let bundle:String = "CaamDau"
public struct Model {
let icon:UIImage?
let title:String?
let titleColor:UIColor?
let titleFont:UIFont?
let detail:String?
let detailColor:UIColor?
let detailFont:UIFont?
let accType: UITableViewCell.AccessoryType
let accView:UIView?
public init(icon:UIImage? = nil,
title:String? = nil,
titleColor:UIColor? = nil,
titleFont:UIFont? = nil,
detail:String? = nil,
detailColor:UIColor? = nil,
detailFont:UIFont? = nil,
accType:UITableViewCell.AccessoryType = .disclosureIndicator,
accView:UIView? = nil) {
self.icon = icon
self.title = title
self.titleColor = titleColor
self.titleFont = titleFont
self.detail = detail
self.detailColor = detailColor
self.detailFont = detailFont
self.accType = accType
self.accView = accView
}
}
public func update(_ data: CD_TableViewCellBase.Model, id: String, tag: Int, frame: CGRect, callBack: CD_RowCallBack?) {
update(dataSource:data)
}
public func update(config data: Any) {
}
public func update(dataSource data: CD_TableViewCellBase.Model) {
self.accessoryType = data.accType
self.textLabel?.text = data.title ?? ""
self.textLabel?.textColor = data.titleColor ?? UIColor.black
self.textLabel?.font = data.titleFont ?? UIFont.systemFont(ofSize: 14)
self.detailTextLabel?.text = data.detail ?? ""
self.detailTextLabel?.textColor = data.detailColor ?? UIColor.lightGray
self.detailTextLabel?.font = data.detailFont ?? UIFont.systemFont(ofSize: 12)
if let img = data.icon {
self.imageView?.image = img
}
if let vv = data.accView {
self.accessoryView = vv
}
}
public func update(callBack block: CD_RowCallBack?) {
}
}
extension CD_TableViewCellBase:CD_RowUpdateProtocol{
public typealias DataSource = CD_TableViewCellBase.Model
public func row_update(_ data: CD_TableViewCellBase.Model, id: String, tag: Int, frame: CGRect, callBack: CD_RowCallBack?) {
self.update(data, id: id, tag: tag, frame: frame, callBack: callBack)
}
}
extension CD_TableViewCellBase: CD_RowCellUpdateProtocol {
public typealias ConfigModel = Any
public func row_update(config data: Any) {
update(config: data)
}
public func row_update(dataSource data: CD_TableViewCellBase.Model) {
update(dataSource: data)
}
public func row_update(callBack block: CD_RowCallBack?) {
update(callBack: block)
}
}
//MARK:--- 默认的空 UICollectionViewCell CD_CollectionReusableView ----------
public class CD_CollectionViewCellNone: UICollectionViewCell{
public static let id:String = "CD_CollectionViewCellNone"
public static let bundle:String = "CaamDau"
}
extension CD_CollectionViewCellNone:CD_RowUpdateProtocol{
public typealias DataSource = Any
public func row_update(_ data: Any, id: String, tag: Int, frame: CGRect, callBack: CD_RowCallBack?) {
}
}
extension CD_CollectionViewCellNone: CD_RowCellUpdateProtocol {
public typealias ConfigModel = Any
public func row_update(config data: Any) {
}
public func row_update(dataSource data: Any) {
}
public func row_update(callBack block: CD_RowCallBack?) {
}
}
public class CD_CollectionReusableViewNone: UICollectionReusableView {
public static let id:String = "CD_CollectionReusableViewNone"
public static let bundle:String = "CaamDau"
}
extension CD_CollectionReusableViewNone:CD_RowUpdateProtocol{
public typealias DataSource = Any
public func row_update(_ data: Any, id: String, tag: Int, frame: CGRect, callBack: CD_RowCallBack?) {
}
}
extension CD_CollectionReusableViewNone: CD_RowCellUpdateProtocol {
public typealias ConfigModel = Any
public func row_update(config data: Any) {
}
public func row_update(dataSource data: Any) {
}
public func row_update(callBack block: CD_RowCallBack?) {
}
}
This diff is collapsed.
# CD_Form ([OC版本在这里](https://github.com/liucaide/CD_ObjC/tree/master/CD_ObjC/CD_Form))
## Installation
CaamDau is available through [CocoaPods](https://cocoapods.org). To install
it, simply add the following line to your Podfile:
```ruby
pod 'CaamDau/Form'
```
#### 目标:用一点点代码 实现 高耦合的 UI 排版解耦,增强排版随机、变更、扩展能力,增强 UI-Data 关联强度;解决TableView,CollectionView 混合排版 section row height didselect 等多点关系的灾难
#### 无论界面多复杂,都是一样的代码,使用这种方式即可轻松完成复杂的 UI 排版,适用所有 UIView,编写可读性、扩展性、维护性强的代码
### 原理:这是一个UI排版模型,将UI排版逻辑 事先转换为 Row 模型!
### 更新:
- 核心代码在 CD_Row。CD_Form 尚未完全编写。
- CD_Row 已变更到新的协议,旧的协议 CD_RowProtocol 比较单一,新的协议进行了更多的拆分,分工更加明确,当然旧的协议由于历史项目原因依然可用。
- CaamDau 在 ViewModel 模块中提供了一个 TableView & CollectionView 代理的中间件 [.....DelegateDataSource](https://github.com/liucaide/CaamDau/tree/master/CaamDau/ViewModel),使用此中间件无需编写重复性的.....Delegate/.....DataSource 代码,如下示例:
```
var delegateData:CD_TableViewDelegateDataSource?
delegateData = CD_TableViewDelegateDataSource(vm)
tableView.cd.background(Config.color.bg)
.delegate(delegateData)
.dataSource(delegateData)
//--- 剩下的几十行甚至 上百上千行 Delegate/DataSource 代码无需编写、无需理会
```
- 排版示例
```
do{// 倒计时 - 旧的协议
let row = CD_Row<Cell_MineCountDown>(data: model, frame: CGRect(h:100))
self.forms[Section.countdown.rawValue].append(row)
}
do{// 倒计时 - 新的协议
let row = CD_RowCell<Cell_MineCountDown>(data: model, frame: CGRect(h:100))
self.forms[Section.countdown.rawValue].append(row)
}
do{// 倒计时 点击回调didSelect 与内部事件回调 callBack
let row = CD_RowCell<Cell_MineCountDown>(data: model, frame: CGRect(h:100), callBack:{_ in}, didSelect:{})
self.forms[Section.countdown.rawValue].append(row)
}
```
- 当混合排版的时候 section row height didselect 等多点关系简直就是灾难
- 而使用CD_Row 就是如此简单
```ruby
//MARK:--- 应对混合排版 ----------
extension VM_MineTableView{
func makeForm() {
for (i,item) in models.enumerated() {
self.makeFormCountDown(item)
// 除倒计时外 其余随机排版
switch Int(arc4random() % 3) {
case 0:...
default:
self.makeFormDetail(i)
}
do{//分割线
let row = CD_Row<Cell_MineLine>(data: .bgF0, frame: CGRect(h:10))
self.forms[Section.countdown.rawValue].append(row)
}
}
}
func makeFormCountDown(_ model:VM_MineTableView.Model) {
do{//分割线
let row = CD_Row<Cell_MineLine>(data: .bgFF, frame: CGRect(h:10))
self.forms[Section.countdown.rawValue].append(row)
}
do{// 倒计时
let row = CD_Row<Cell_MineCountDown>(data: model, frame: CGRect(h:100))
self.forms[Section.countdown.rawValue].append(row)
}
do{//分割线
let row = CD_Row<Cell_MineLine>(data: .bgFF, frame: CGRect(h:10))
self.forms[Section.countdown.rawValue].append(row)
}
do{//分割线
let row = CD_Row<Cell_MineLine>(data: .bgF0, frame: CGRect(h:0.5))
self.forms[Section.countdown.rawValue].append(row)
}
}
}
```
#### 对于 UITableView/UICollectionView,都是一样的代码,基本无需维护,无需考虑检查 section row height didselect 等多点关系,...ViewDelegate/...ViewDataSource 代码无需编写;如果有更高一点的要求,比如....ViewDelegateFlowLayout 、 scrollViewDidScroll 等,可将中间件 [.....DelegateDataSource](https://github.com/liucaide/CaamDau/tree/master/CaamDau/ViewModel) 里的代码完全复制或继承,无需改动任何地方,而后扩展添加未实现的功能即可。
## Author
liucaide, 565726319@qq.com
## License
CaamDau is available under the MIT license. See the LICENSE file for more info.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
//Created on 2019/5/14 by LCD:https://github.com/liucaide .
/***** 模块文档 *****
* 内容容器
*/
import UIKit
class CD_HUDContentView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
init() {
super.init(frame: CGRect.zero)
self.backgroundColor = UIColor.black.cd_alpha(0.8)
}
lazy var view_text: CD_HUDTextView = {
return CD_HUDTextView().cd.build
}()
lazy var view_icon: CD_HUDActivityView = {
return CD_HUDActivityView().cd.build
}()
var title:String = ""
var detail:String = ""
var model:CD_HUD.Model = CD_HUD.modelDefault
}
extension CD_HUDContentView {
func show(_ style:CD_HUD.Style, title:String, detail:String, model:CD_HUD.Model) {
self.title = title
self.detail = detail
self.model = model
switch style {
case .text:
makeText()
makeTextLayout(true)
case .loading, .info, .succeed, .warning, .error, .progress:
self.cd.add(view_icon)
view_icon.show(style, model:model)
if !title.isEmpty || !detail.isEmpty {
makeText()
makeTextLayout(false)
makeIconLayout(false)
}else{
makeIconLayout(true)
}
case .custom(_):
break
}
if model._isBlurEffect {
self.cd.blurEffect(model._colorBg) { (v) in
v.cd.corner(model._radius, clips: true)
}
}
if model._isShadow {
self.cd
.background(model._colorBg.cd_alpha(1))
.corner(model._radius, clips: false)
.shadow(color: model._shadow.0,
opacity: model._shadow.1,
offset: model._shadow.2,
radius: model._shadow.3)
}
}
func makeText() {
self.cd.add(view_text)
view_text.show(title: title, detail: detail, model: model)
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
# CD_IconFont 阿里矢量图标库 管理与使用范例
## Installation
CaamDau is available through [CocoaPods](https://cocoapods.org). To install
it, simply add the following line to your Podfile:
```ruby
pod 'CaamDau/IconFont'
```
>
####
```ruby
self.img.cd.iconfont(CD_IconFont.temoji(60), color: UIColor.red, mode: .center)
self.lab_icon.cd.iconfont(CD_IconFont.temoji(60))
self.lab_icon.cd.text(CD_IconFont.temoji(60).attributedString)
self.btn.cd
.text(CD_IconFont.temoji(60).font)
.text(CD_IconFont.temoji(60).text)
self.btn.cd.text(CD_IconFont.temoji(60).attributedString)
self.btn.cd.iconfont(CD_IconFont.temoji(60), style: .image(.normal, color: UIColor.red, mode: .center))
```
#### 附:[阿里矢量图标资源管理 代码自动化脚本](https://github.com/liucaide/SapSapSeoi)
## Author
liucaide, 565726319@qq.com
## License
CaamDau is available under the MIT license. See the LICENSE file for more info.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment