FlyCoding - Xcode版 Emmet
?? 請使用 Swift 5 編譯 ??
FlyCoding 是一個 Xcode 插件胸懈,使用蘋果提供的插件機制編寫逞敷,可以運行在最新的Xcode上, 它提供了類似于前端中 Emmet 的功能。你可以通過特殊語法來快速的生成你想要的 Swfit / Objective-C 代碼逢享,特別是在大量的編寫界面 UI 時, 重復的編寫 UI 控件和約束是一件非常繁瑣和機械的勞動吴藻, 但是這又是你不可避免的瞒爬。
而 FlyCoding 則可以幫助你快速的生成屬性、方法沟堡、約束(Masonry / SnapKit)侧但,目前 FlyCoding 剛剛發(fā)布了第一個版本,更多的功能還在構思當中航罗,希望大家提供寶貴的意見和想法禀横。
目前開發(fā)進度:
- 2.0 版本中新增加強大的 @do 命令, 通過類shell命令對文本進行操作
- remove 命令
- to 命令
- copy 命令
- move 命令
- sort 命令
- Objective-C / Swift 屬性生成
- Objective-C / Swift 視圖的快速創(chuàng)建
- Masonry / SnapKit 約束生成
- Swift 下的系統原生的 AutoLayout 約束
- 快速生成方法
- 任何完整操作都可以使用 ' + ' 進行分隔, 使用 '* N' 進行批量操作
生成 Snipkit
布局代碼示例
@do 命令
@do move 10 34 to 44
// 將 10 行到 34 行的內容移動到 44 行
//
//命令的使用方法非常的簡單粥血,你可以任何地方直接編寫命令
//命令以 @do 開頭柏锄,接下來是你要操作的命令
//這里的 move 是移動命令酿箭,接下來餓 10 是起始行 34 是結束行
//to 也是一個命令敷矫,它是負責將內容移動到指定的位置
//to 并不是 move 命令的組合命令顶瞳,它是一個獨立的命令世囊,詳細的會在 to 命令中介紹中
//接下來是 to 命令的參數
理論上可以銜接無限制的命令數量娃殖,每個命令都是獨立處理的單元蜜宪,處理完畢后會通過一個通用的 context
進行狀態(tài)傳遞魔市,隨著命令越來越多针饥,一定會有更多神奇的連接用法凌摄。
刪除命令
-
remove/rm
@do rm 10 .
-
arg1
[arg2]
-
arg1
表示起始行數 -
arg2
表示結束行數笤成,此參數可以為空讥耗,此時arg1
表示要刪除的行 - 除了可以使用
數字
表示行數外,也可以通過.
來代表命令的當前行
-
移動命令
-
move/mv
@do mv 10 . to 30
-
arg1
[arg2]
*arg1
表示起始行數
*arg2
表示結束行數疹启,此參數可以為空古程,此時arg1
表示要移動的行
* 除了可以使用數字
表示行數外,也可以通過.
來代表命令的當前行 -
to arg1
*to
移動到指定位置需要配合to
命令
*arg1
表示要移動到的行
拷貝命令
-
copy/cp
@do cp 10 . to 30
-
arg1
[arg2]
*arg1
表示起始行數
*arg2
表示結束行數喊崖,此參數可以為空挣磨,此時arg1
表示要拷貝的行
* 除了可以使用數字
表示行數外,也可以通過.
來代表命令的當前行 -
to arg1
*to
移動到指定位置需要配合to
命令
*arg1
表示要移動到的行
排序命令
將范圍內的代碼根據每行的長度荤懂,按照從少到多排列
-
sort/st
- `@do st 10 .
-
arg1
[arg2]
-
arg1
表示起始行數, 如果arg2
為空則表示結束行為命令當前行茁裙,而開始行表示命令當前行減去arg1
行 -
arg2
表示結束行數,此時arg1
表示結束行 -
arg2
除了可以使用數字
表示行數外节仿,也可以通過.
來代表命令的當前行
-
屬性生成
Swift屬性生成
- 單個屬性
pv.UIImageView
// pv 是屬性控制晤锥,p 是 private, v 是 var廊宪,具體的列表可以在后文中查看; . 用于區(qū)分屬性和類名
private var <#name#>: UIImageView
Pv.Int/age
// Pv: public var
// `/age` 這里的 `/` 用來標記屬性名
public var age: Int
- 可選屬性
fv.UILabel?
// fv 是屬性控制矾瘾, f 是 fileprivate, v 是 var; ?表示屬性是可選的
fileprivate var <#name#>: UILabel?
- 有默認值的屬性
Pl.UIView{}
// Pl 是屬性控制箭启, P 是 public, l 是 let; {} 表示有默認值
// 默認值使用 Class() 來生成
// 如果有默認值壕翩,就不會再顯示類型,因為 Swift 可以自己推斷類型
public let <#name#> = UIView()
Pl.Int{100}
// 如果在 {} 里面添加默認值傅寡,會直接使用此默認值
public let <#name#> = 100
- 懶加載屬性
lv.UIButton
// lv 是屬性控制放妈,lv 是一個特殊的組合,分來時 l 表示 let, v 表示 var; 合并在一起時表示 lazy var
lazy var <#name#>: UIButton = {
<#code#>
}()
- OC可訪問屬性
@Pv.UIImageView
// 添加 @ 將把屬性標記為 @objc
@objc public var <#name#>: UIImageView
- 特殊的屬性標識
wv.EatProtocol?
// 添加 w 將把屬性標記為 weak, 除了 w 之外,還有 u/unowned荐操、 c/class 和 s/static
weak var <#name#>: EatProtocol?
- 批量生成屬性
pl.UILabel{} *2
// *2 中間不能有空格芜抒, 一般用于編寫數據模型,或是編寫 UI 時使用
private let <#name#> = UILabel()
private let <#name#> = UILabel()
- 生成block初始化值
plb.UIButton
// 標記 b 表示的是 block 的意思
private let <#name#>: UIButton = {
<#code#>
}()
Tips: 如果屬性沒有寫標記托启,會自動使用 let 來標記屬性
.UIImageView
let <#name#>: UIImageView
Swift 屬性標記快速查詢表
符號 | 標記 |
---|---|
l | Let |
v | var |
lv | lazy var |
p | private |
P | public |
o | open |
f | fileprivate |
pl | private let |
pv | private var |
plv | private lazy var |
Pl | public let |
Pv | public var |
Plv | public lazy var |
ol | open let |
ov | open var |
olv | open lazy var |
fl | fileprivate let |
fv | fileprivate var |
flv | fileprivate lazy var |
-- | -- |
@ | @objc |
u | unowned |
w | weak |
c | class |
s | static |
特殊符號 | 功能 |
---|---|
b | block, 為屬性生成block形式的初始化值宅倒,類似于 lazy var |
F | 自用,屬性的初始值是由 config 函數來提供的 |
Objective-C屬性生成
Objective-C 中的使用語法和 Swift 區(qū)別不大驾中,主要是關鍵字和生成的樣子不同
- 單個屬性
.UIImageView *
// 默認描述就是 nonatomic, strong
@property (nonatomic, strong) UIImageView *<#name#>
- 生成完整屬性
c.NSString *name;
// 如果在末尾添加 ' ; ' 表示 Class 后面已經銜接了屬性名唉堪, 為了方便快速編碼
@property (nonatomic, copy) NSString *name;
Tips: class 可以用來標記類屬性
Objective-C 屬性標記快速查詢表
符號 | 標記 |
---|---|
s | strong |
w | weak |
a | assign |
r | readonly |
g | getter=<#getterName#> |
c | copy |
n | nullable |
N | nonnull |
c | class |
生成約束代碼
我選取了最常用的兩個框架來實現模聋, 在 Objective-C 中使用 Masonry,而在 Swift 當中使用 SnapKit唠亚。
SnapKit
- 添加布局
#snpm(iconView, e=self)
// snpm 就是 makeConstraints链方, 在 () 中使用,號來分割各個語句
// 第一個參數是要添加約束的對象灶搜,剩下的都是布局語句
// 每個語句都分為三個部分祟蚀,左邊是被約束對象的屬性,中間是約束方式割卖,
// 而右邊是約束的值或是其它的約束對象
iconView.snp.makeConstraints {
$0.edges.equalTo(self)
}
- 更新布局
#snpu(iconView, h=100)
// snpu 是 updateConstraints
iconView.snp.updateConstraints {
$0.height.equalTo(100)
}
- 重置布局
#snprm(iconView, r=self - 20)
// snprm 是 remakeConstraints
iconView.snp.remakeConstraints {
$0.right.equalTo(self).offset(-20)
}
- 布局演示 1 (相對距離)
#snpm(iconView, r=titleLabel.l-20, wh=20)
// 更加直觀的使用 + - 來進行相對距離的設置
iconView.snp.makeConstraints {
$0.right.equalTo(titleLabel.snp.left).offset(-20)
$0.width.height.equalTo(20)
}
- 布局演示 2 (+-的作用)
#snpm(iconView, t=titleLabel.b-superView.height-20, wh=100)
// 在約束語句中前酿,第一個加減號除了有正負的含義,還是分割前后語句的標記
iconView.snp.makeConstraints {
$0.top.equalTo(titleLabel.snp.bottom).offset(-superView.height-20)
$0.width.height.equalTo(100)
}
- 布局演示 3 (比例約束)
#snpm(iconView, wh=self/2)
// 進行比例約束也是常用的約束手法
iconView.snp.makeConstraints {
$0.width.height.equalTo(self).dividedBy(2)
}
// 相同作用
#snpm(iconView, wh=self*0.5)
// 使用 * 法當然也是可以的
iconView.snp.makeConstraints {
$0.width.height.equalTo(self).multipliedBy(0.5)
}
- 布局演示 4 (比較)
#snpm(titleLabel, tl=self, r<=self - 20)
// 常用的根據文本的長度自適應寬度
// 也可以使用 >= 表示大于等于
titleLabel.snp.makeConstraints {
$0.top.left.equalTo(self)
$0.right.lessThanOrEqualTo(self).offset(-20)
}
- 布局演示 4 (約束等級)
#snpm(iconView, l = self, r <= superView~20, r <= titleLabel.l - 20~h)
// 在約束語句的最后使用 ~ 可以用來設置約束登記
// 你可以使用數字來表示約束登記鹏溯,也可以使用 r\h\m\l 來標記
iconView.snp.makeConstraints {
$0.left.equalTo(self)
$0.right.lessThanOrEqualTo(superView).priority(20)
$0.right.lessThanOrEqualTo(titleLabel.snp.left).offset(-20).priority(.high)
}
SnapKit 屬性標記快速查詢表
- 屬性
符號 | 屬性 |
---|---|
l | left |
t | top |
b | bottom |
r | right |
w | width |
h | height |
x | centerX |
y | centerY |
c | center |
s | size |
e | edges |
--- | 約束等級 |
r | .required |
h | .high |
m | .medium |
l | .low |
--- | 比較參數 |
>= | greaterThanOrEqualTo |
<= | lessThanOrEqualTo |
= | equalTo |
--- | 運算符號 |
- | Offset(-value) |
+ | Offset(value) |
* | multipliedBy(value) |
/ | dividedBy(value) |
Masonry
主要的用法和 SnapKit 一致罢维, 下面主要說不同點
- 創(chuàng)建、更新丙挽、重置
@masm(iconView, e=self) // 創(chuàng)建
@masu(iconView, e=self) // 更新
@masrm(iconView, e=self) // 重置
Tips: 在 OC 中可以使用 @ 作為命令的前綴肺孵,主要是 # 在OC文件中會自動變第一列, 影響代碼結構
- 約束中沒有 r 這個等級了
- 比較里面新加了 == / >== / <==颜阐, 主要是相比少一個 = 的版本平窘,在前面加上了 mas_
@masm(iconView, e=self) // 創(chuàng)建
@masu(iconView, e=self) // 更新
@masrm(iconView, e=self) // 重置
AutoLayout(Swift)
主要的用法和 SnapKit/Masonry 一致, 下面主要說不同點
- 使用 #layout 來執(zhí)行語句
- 移除了 s(size) / c(center) / e(edges) 的支持凳怨, 在以后的版本更新當中會重新添加回來
- 移除了約束中除法的運算不能再使用
/
- 對于偏移的控制不在簡單的使用
+``-
, 如果想要設置常量約束或是偏移使用:100
的形式
@layout(view, l=self:100, t=self:-20, w=self*2, h=:50)
視圖的快速創(chuàng)建
這部分使用 Xcode 的代碼塊也可以實現瑰艘,但是寫代碼的時候,打出了對應的短語后還要看一眼和等待Xcode反應實在是令人著急肤舞。我們?yōu)榈木褪强欤紫新。∪蓿〔⑶椅覀兛梢灾苯淤x予視圖一個變量名弊琴,而代碼塊還是不行的
通過 #make 命令我們可以快速的添加創(chuàng)建一個 View 的代碼
這是目前支持的創(chuàng)建類型
UIView
UILabel
UIButton
UIImageView
UITableView
UICollectionView
普通創(chuàng)建 UIImageView
#make(UIImageView)
// 生成 Swift 視圖
let <#name#> = UIImageView()
<#name#>.backgroundColor = <#color#>
<#name#>.image = <#image#>
<#superView#>.addSubview(<#name#>)
// 生成 OC 視圖
UIImageView *<#name#> = [[UIImageView alloc] init];
self.<#name#> = <#name#>;
<#name#>.backgroundColor = <#color#>;
<#name#>.image = <#image#>;
[<#superView#> addSubview: <#name#>];
- 設置屬性名創(chuàng)建 UILabel
@make(UILabel, titleLabel)
// 生成 Swift 視圖
let titleLabel = UILabel()
titleLabel.font = <#font#>
titleLabel.textColor = <#color#>
titleLabel.text = <#text#>
titleLabel.backgroundColor = <#color#>
<#superView#>.addSubview(titleLabel)
// 生成 OC 視圖
UILabel *titleLabel = [[UILabel alloc] init];
self.titleLabel = titleLabel;
titleLabel.font = <#font#>;
titleLabel.textColor = <#color#>;
titleLabel.text = <#text#>;
titleLabel.backgroundColor = <#color#>;
[<#superView#> addSubview:titleLabel];
創(chuàng)建方法
Swift
- 創(chuàng)建方法
#func
可以使用#f
縮寫
#func(eat)
// 生成一個簡單的方法
func eat() {
<#code#>
}
- 設定權限的方法
#func(@p.run)
// 標記和屬性一樣
@objc private func run() {
<#code#>
}
- 有參數的方法
#func(run::)
// 一個 : 代表有一個參數
func run(<#name#>: <#type#>, <#name#>: <#type#>) {
<#code#>
}
- 有返回值的方法
#func(run>)
// 一個 > 代表有一個返回值
func run() -> <#return#> {
<#code#>
}
// 多個返回值會返回元組
#func(run>>)
func run() -> (<#return#>, <#return#>) {
<#code#>
}
Objective-C
- 創(chuàng)建方法
#func(run)
// 生成一個簡單的方法
- (void)run {
<#code#>
}
- 有返回值的方法
#func(run>)
// 一個 > 代表有一個返回值
- (<#type#>)run {
<#code#>
}
- 有參數的方法
#func(run::)
// 一個 : 代表有一個參數
- (void)run:(<#type#>)<#param0#> <#name1#>:(<#type#>)<#param1#> {
<#code#>
}
通用語法功能
- 批量處理: 以上所有的命令都可以通過后接 *n 進行批量的生成
- 多命令執(zhí)行: 你可以通過 + 連續(xù)的編寫多句命令一塊生成
希望大家提出寶貴的意見和建議, 你可以提出 issue 或是發(fā)郵件到 caishilin@yahoo.com