LazyKit是一个框架,允许您编写快速且易于使用的视图。
构造视图可能很费时、无聊且重复,特别是在构建了n个视图之后。
现在您可以使用基本的CSS文件来设置元素样式。
内嵌框架需要iOS 8的最小部署目标。
cd
进入您项目的顶层目录,然后运行以下命令“如果”您的项目尚未初始化为Git仓库$ git init
$ git submodule add https://github.com/kmalkic/LazyKit.git
打开新的LazyKit
文件夹,然后将LazyKit.xcodeproj
拖放到应用程序的Xcode项目的Project Navigator中。
它应该出现在应用程序蓝色项目图标之下。它是否在所有其他Xcode组之上或之下并不重要。
在Project Navigator中选择LazyKit.xcodeproj
并验证部署目标是否与应用程序目标匹配。
+
按钮。您将看到两个不同的 LazyKit.xcodeproj
文件夹,每个文件夹中包含两个不同版本的 LazyKit.framework
,它们嵌套在 Products
文件夹中。
您选择哪个
Products
文件夹都无关紧要,但是选择最上面或最下面的LazyKit.framework
是有关系的。
这样就可以了!
LazyKit.framework
会自动添加为目标依赖、链接框架和嵌入框架,这所有的要求都满足,您就可以在模拟器和设备上构建了。
可以是一个结构体或类。简单加入一个标签。
import LazyKit
struct MyConfigurations: LazyViewConfigurations {
static func elementsOptions() -> [ElementOptions]? {
return [
LabelOptions(identifier: "title",
classType: CustomLabel.self,
viewBaseOptions: ViewBaseOptions(backgroundColor: .blueColor()),
textOptions: TextBaseOptions(text: "hello", font: .systemFontOfSize(20), textAlignment: .Center)),
]
}
//Will need some knowledges in visual format constraints
static func visualFormatConstraintOptions() -> [VisualFormatConstraintOptions]? {
return [
VisualFormatConstraintOptions(string: "H:|-[title]-|"),
VisualFormatConstraintOptions(string: "V:|-top-[title(==titleHeight)]")
]
}
static func visualFormatMetrics() -> [String: AnyObject]? {
return ["top" : 30, "titleHeight" : 44]
}
//Can use this function to return the conventional way of using constraints
static func layoutConstraints() -> [ConstraintOptions]? {
return nil
}
}
就是这些了。
import LazyKit
class MyViewController: LazyBaseViewController <MyConfigurations> {
}
就是这些了。不要同时使用 LazyBaseViewController 和具有 LazyBaseView 类型的视图。首先,这样做没有意义,其次,您最终会得到重复的视图。
import LazyKit
class MyViewController: UIViewController {
override func loadView() {
view = MyView()
}
}
class MyView: LazyBaseView <MyConfigurations> {
}
import LazyKit
struct MyConfigurations: LazyViewConfigurations {
static func elementsOptions() -> [ElementOptions]? {
return [
LabelOptions(identifier: "title",
classType: CustomLabel.self,
viewBaseOptions: ViewBaseOptions(backgroundColor: .blueColor()),
textOptions: TextBaseOptions(text: "hello", font: .systemFontOfSize(20), textAlignment: .Center)
),
LabelOptions(identifier: "subtitle",
viewBaseOptions: ViewBaseOptions(backgroundColor: .greenColor()),
textOptions: TextBaseOptions(text: "hey", textAlignment: .Center)
),
ButtonOptions(identifier: "button",
viewBaseOptions: ViewBaseOptions(backgroundColor: .redColor()),
textOptionsForType: [.Normal: TextBaseOptions(text: "button"), .Highlighted: TextBaseOptions(text: "highlighted")]
),
ViewOptions(identifier: "line",
viewBaseOptions: ViewBaseOptions(backgroundColor: .lightGrayColor())
),
ImageOptions(identifier: "photo",
viewBaseOptions: ViewBaseOptions(backgroundColor: .lightGrayColor()),
imageBaseOptions: ImageBaseOptions(imageNamed: "image", contentMode: .ScaleAspectFill)
),
TextFieldOptions(identifier: "textfield",
viewBaseOptions: ViewBaseOptions(backgroundColor: UIColor.orangeColor()),
textOptions: TextBaseOptions(font: .systemFontOfSize(16), textAlignment: .Center),
placeholderOptions: TextBaseOptions(text: "placeholder", font: .systemFontOfSize(16), textColor: .redColor(), textAlignment: .Center),
textInputOptions: TextInputBaseOptions(autocapitalizationType: .Sentences, autocorrectionType: .No, spellCheckingType: .No, keyboardType: .NumbersAndPunctuation, keyboardAppearance: .Dark, returnKeyType: .Done, enablesReturnKeyAutomatically: true, secureTextEntry: false)
),
TextViewOptions(identifier: "textview",
viewBaseOptions: ViewBaseOptions(backgroundColor: UIColor.cyanColor()),
textOptions: TextBaseOptions(text: "TextView", font: .systemFontOfSize(14), textAlignment: .Left),
textInputOptions: TextInputBaseOptions(autocapitalizationType: .Sentences, autocorrectionType: .No, spellCheckingType: .No, keyboardType: .EmailAddress, keyboardAppearance: .Dark, returnKeyType: .Done, enablesReturnKeyAutomatically: true, secureTextEntry: false)
)
]
}
static func visualFormatConstraintOptions() -> [VisualFormatConstraintOptions]? {
return [
VisualFormatConstraintOptions(string: "H:|-[photo(==photoW)]-[title]-|"),
VisualFormatConstraintOptions(string: "H:[subtitle(==title)]"),
VisualFormatConstraintOptions(string: "H:[textfield(==title)]"),
VisualFormatConstraintOptions(string: "H:|-40-[line]-40-|"),
VisualFormatConstraintOptions(string: "H:|-[textview]-|"),
VisualFormatConstraintOptions(string: "H:|-buttonLeft-[button]-buttonRight-|"),
VisualFormatConstraintOptions(string: "V:|-top-[title]-[subtitle]-[textfield]", options: .AlignAllLeft),
VisualFormatConstraintOptions(string: "V:|-top-[photo(==photoH)]"),
VisualFormatConstraintOptions(string: "V:[line(==1)]-[textview(==200)]-200-[button(==buttonH)]-8-|")
]
}
static func visualFormatMetrics() -> [String: AnyObject]? {
return ["top" : 30, "buttonH" : 44, "buttonLeft" : 100, "buttonRight" : 100, "photoW" : 100, "photoH" : 60]
}
static func layoutConstraints() -> [ConstraintOptions]? {
return [
ConstraintOptions(identifier: "titleHeight", itemIdentifier: "title", attribute: .Height, relatedBy: .Equal, toItemIdentifier: nil, attribute: .Height, multiplier: 1, constant: 40)
]
}
}
这里的结果无需额外工作 :),但颜色很丑陋。
样式声明使用类似于 CSS 的语法,并且支持变量。
@global_bold_font_name: RobotoSlab-Bold;
@global_regular_font_name: RobotoSlab-Regular;
@titleColor: #ff0000;
@tintColor: #3e8fdb;
@bodyColor: #333333;
body {
color: @bodyColor;
font-family: @global_bold_font_name;
placeholder-font-family: @global_bold_font_name;
}
#title {
color: @titleColor;
font-size: 14px;
text-align:left;
text-maxline: 2;
}
.subtitle {
font-size: 12px;
text-align:left;
text-indent: 5px;
text-decoration: underline;
text-decoration-color: rgba(0,0,0,1);
}
#photo {
background-image-content: scaleToFill;
}
.photo {
background-image: myimage;
}
以下是可用属性的列表。
******************************************************************
GENERAL KEYS:
'background'
'background-color'
'tint-color'
'bartint-color'
Usage: #RBG | #ARGB | #RRGGBB | #AARRGGBB | rgb(red(0-255),green(0-255),blue(0-255)) | rgba(red(0-255),green(0-255),blue(0-255),alpha(0.0-1.0))
'background-image'
Usage: image name, without ""
'background-image-content'
Usage: scaleToFit | scaleToFill | center | top | left | bottom | right
TEXT KEYS:
'color'
Usage: #RBG | #ARGB | #RRGGBB | #AARRGGBB | rgb(red(0-255),green(0-255),blue(0-255)) | rgba(red(0-255),green(0-255),blue(0-255),alpha(0.0-1.0))
'font-family'
Usage: font name, without ""
'font-size'
Usage: size in px
'text-align'
Usage: left | center | right | justify
'text-maxline'
Usage: number of lines max (integer)
'line-height'
Usage: height in px
'paragraph-spacing'
Usage: spacing in px
'text-indent'
Usage: header in px. Used to indent first line of any new paragraph.
'word-wrap'
Usage: word-wrapping | char-wrapping | clipping | truncating-head | truncating-tail | truncating-middle
'text-stroke-color'
Usage: #RBG | #ARGB | #RRGGBB | #AARRGGBB | rgb(red(0-255),green(0-255),blue(0-255)) | rgba(red(0-255),green(0-255),blue(0-255),alpha(0.0-1.0))
'text-stroke-width'
Usage: width in px
'text-decoration'
Usage: none|underline|line-through
'text-decoration-color'
Usage: #RBG | #ARGB | #RRGGBB | #AARRGGBB | rgb(red(0-255),green(0-255),blue(0-255)) | rgba(red(0-255),green(0-255),blue(0-255),alpha(0.0-1.0))
For placeholder styling
'placeholder-'
Usage: You can add 'placeholder-' to any of the above text keys
DECORATIONS KEYS:
'border'
Patterns:
- width color
'border-color'
Usage: #RBG | #ARGB | #RRGGBB | #AARRGGBB | rgb(red(0-255),green(0-255),blue(0-255)) | rgba(red(0-255),green(0-255),blue(0-255),alpha(0.0-1.0))
'border-width'
Patterns:
- width
'border-radius'
Usage: radius in px
******************************************************************
为了增加灵活性,可以嵌套 id 和类,例如:
非常类似于在 HTML 中做的,但限制在这些。
#title.commonText {} //will apply this style to any element that as styleClass = "commonText" and styleId = "title"
#title.commonText.link {} //will apply this style to any element that as styleClass = "commonText link" and styleId = "title"
.commonText.link {} //will apply this style to any element that as styleClass = "commonText link"
UILabel.commonText.link {} //will apply this style to all UILabel that as styleClass = "commonText link"
UITextField {} //will apply this style to all UITextField
如果您倾向于分离 CSS 文件,可以将它们添加到数组中。
您会发现它们是 URL,因此您可以使用 http。 :)
//Load style from bundle
let defaultUrls = [
NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("default.css", ofType: nil)!)
]
LazyStyleSheetManager.shared.setDefaultStylesFromFileAtUrls(defaultUrls)
可以针对给定的集合名称加载一组不同的 CSS 文件。
let defaultUrls = [
NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("default.css", ofType: nil)!)
]
LazyStyleSheetManager.shared.setDefaultStylesFromFileAtUrls(defaultUrls)
let alternativeUrls = [
NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("alt.css", ofType: nil)!)
]
LazyStyleSheetManager.shared.setStylesFromFileAtUrls(alternativeUrls, collectionName: kAlternativeCollectionName)
在任何需要的时候,您都可以通过更改 currentCollecionName 为其他样式来交换。这将触发 kUpdateStylesNotificationKey 下的通知。它是自动的,因此不需要为它添加观察者,除非是为了其他目的。
LazyStyleSheetManager.shared.currentCollectionName = kAlternativeCollectionName
用于打印 CSS 属性和选项。
LazyStyleSheetManager.shared.help()
基本上与上面一样,但更简单。
import LazyKit
struct MyConfigurations: LazyViewConfigurations {
static func elementsOptions() -> [ElementOptions]? {
return [
LabelOptions(identifier: "title",
text: "hello",
styleId: "title"),
LabelOptions(identifier: "subtitle",
text: "hey",
styleId: "subtitle"),
ButtonOptions(identifier: "button",
texts: [.Normal: "button", .Highlighted: "highlighted"],
styleId: "button"),
ViewOptions(identifier: "line",
viewBaseOptions: ViewBaseOptions(backgroundColor: .lightGrayColor())),
ImageOptions(identifier: "photo",
styleId: "photo",
styleClass: "photo"),
TextFieldOptions(identifier: "textfield",
placeholderText: "placeholder",
styleId: "textfield",
textInputOptions: TextInputBaseOptions(autocapitalizationType: .Sentences, autocorrectionType: .No, spellCheckingType: .No, keyboardType: .NumbersAndPunctuation, keyboardAppearance: .Dark, returnKeyType: .Done)),
TextViewOptions(identifier: "textview",
styleId: "textview",
textInputOptions: TextInputBaseOptions(autocapitalizationType: .Sentences, autocorrectionType: .No, spellCheckingType: .No, keyboardType: .EmailAddress, keyboardAppearance: .Dark, returnKeyType: .Done)
)
]
}
static func visualFormatConstraintOptions() -> [VisualFormatConstraintOptions]? {
return [
VisualFormatConstraintOptions(string: "H:|-[photo(==photoW)]-[title]-|"),
VisualFormatConstraintOptions(string: "H:[subtitle(==title)]"),
VisualFormatConstraintOptions(string: "H:[textfield(==title)]"),
VisualFormatConstraintOptions(string: "H:|-40-[line]-40-|"),
VisualFormatConstraintOptions(string: "H:|-[textview]-|"),
VisualFormatConstraintOptions(string: "H:|-buttonLeft-[button]-buttonRight-|"),
VisualFormatConstraintOptions(string: "V:|-top-[title]-[subtitle]-[textfield]", options: .AlignAllLeft),
VisualFormatConstraintOptions(string: "V:|-top-[photo(==photoH)]"),
VisualFormatConstraintOptions(string: "V:[line(==1)]-[textview(==200)]-200-[button(==buttonH)]-8-|")
]
}
static func visualFormatMetrics() -> [String: AnyObject]? {
return ["top" : 30, "buttonH" : 44, "buttonLeft" : 100, "buttonRight" : 100, "photoW" : 100, "photoH" : 60]
}
static func layoutConstraints() -> [ConstraintOptions]? {
return [
ConstraintOptions(identifier: "titleHeight", itemIdentifier: "title", attribute: .Height, relatedBy: .Equal, toItemIdentifier: nil, attribute: .Height, multiplier: 1, constant: 40)
]
}
}
各种实现方式。
viewManager.updateElement("title", elementOptions: LabelOptions(textOptions: TextBaseOptions(text: "Bonjour")))
viewManager.updateElement("title", type: UILabel.self) { (element) -> Void in
element.text = "Bonjour"
}
if let title: UILabel = viewManager.element("title") {
title.text = "Bonjour"
}
if let title = viewManager.label("title") {
title.text = "Bonjour"
}
viewManager.label("title")!.text = "Bonjour"
您可以用任何基本选项更新元素。
请注意,新选项将替换非 nil 的属性。
viewManager.updateElement("title", elementOptions: LabelOptions(textOptions: TextBaseOptions(text: "Bonjour")))
viewManager.updateElement("button", elementOptions: ButtonOptions(textOptionsForType: [.Normal: TextBaseOptions(text: "Done"), .Highlighted: TextBaseOptions(text: "Highlighted")]))
针对这次特定的更改,建议不要使用视觉格式约束,因为这会创建一系列NSLayoutConstraints。最佳的做法是使用此函数创建约束。
static func layoutConstraints() -> [ConstraintOptions]? {
return [
ConstraintOptions(identifier: "titleHeight", itemIdentifier: "title", attribute: .Height, relatedBy: .Equal, toItemIdentifier: nil, attribute: .Height, multiplier: 1, constant: 40)
]
现在您将能够针对要更改的具体约束进行操作。
//This will make your title height to change from 40 to 120. Usefull if you want to expand/collapse an element.
viewManager.changeConstantOfLayoutConstaint("titleHeight", constant: 120)
Kevin Malkic
LazyKit是在MIT许可下发布的。有关详细信息,请参阅LICENSE文件。