Eureka可以幫你簡單優雅的實現動態table-view表單。它由rows,sections和forms組成。如果你的app包括大量表單,Eureka可以真正幫你節省時間。
推薦使用CocoaPods進行導入,CocoaPods是1個負責管理iOS項目中第3方開源庫的工具,安裝CocoaPods以后使用命令行就可以輕松地對所有第3方開源庫進行安裝和更新,而不需要每次上GitHub去下載。
CocoaPods的安裝進程傳送門:iOS 9 導入類庫全面詳實進程(Ruby安裝->CocoaPods安裝->導入類庫)
手動安裝:GitHub-Eureka主頁
裝好CocoaPods后,修改Podfile文件內容為以下:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'
use_frameworks!
target 'Web' do
pod 'Eureka', '~> 1.6'
end
xcodeproj 'Desktop/Web/Web.xcodeproj'
target后面為工程名,最后1行動工程路徑(這里的Web是我的工程名)
再履行命令:
$ pod install
另外還需要在Target->工程名->Build Settings->Search Paths->User Header Search Paths處添加Eureka所在的目錄:
最后在你需要用到Eureka的類中加上:
import Eureka
下面來創建1個最簡單的表單,表單只包括1個區域和1行,點擊該行可以切換到其它頁面
import UIKit
import Eureka
//ViewController繼承于FormViewController
class MyViewController: FormViewController {
override func viewDidLoad() {
super.viewDidLoad()
//表單form增加1個Section區域,區域名為First form
form +++ Section("First form")
//在區域中添加1個ButtonRow(ButtonRow為點擊直接觸發事件的行),行tag為Rows
<<< ButtonRow("Rows"){
//設置行標題為行tag
$0.title = $0.tag
//設置點擊事件,履行名為"Main"的Segue(需在Interface Builder中自定義)
$0.presentationMode = .SegueName(segueName: "Main", completionCallback: nil)
}
//自定義Row,在后面會講到
// <<< WeekDayRow(){
// $0.value = [.Monday, .Wednesday, .Friday]
// }
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
效果以下圖所示,與UITableview實現的界面大體1致,點擊該行后會進入名為”Main”的Segue所指向的界面
下面來創建1個包括標簽,日期選擇器,勾選,開關,滑動條,增減器等我們經常使用功能的表單。
//設置標簽行的默許內容色彩為橙色
LabelRow.defaultCellUpdate = { cell, row in cell.detailTextLabel?.textColor = .orangeColor() }
//設置勾選行中勾色彩為橙色
CheckRow.defaultCellUpdate = { cell, row in cell.tintColor = .orangeColor() }
//為表單添加1個區域
form +++ Section("Row examples")
//為區域添加1個標簽行
<<< LabelRow("LabelRow"){
$0.title = $0.tag
$0.value = "tap the row"
}//選中標簽行會在tittle后面加上" Summer "
.onCellSelection{cell, row in
row.title = (row.title ?? "") + " Summer "
row.reload()
}
//為區域添加1個日期行。點擊日期行會在屏幕底部彈出1個日期選擇器
<<< DateRow(){
$0.value = NSDate()
$0.title = "DateRow"
}
//為區域添加1個勾選行,默許為選中
<<< CheckRow(){
$0.title = "CheckRow"
$0.value = true
}
//為區域添加1個開關行,默許為開
<<< SwitchRow(){
$0.title = "SwitchRow"
$0.value = true
}
//為區域添加1個滑動條行,默許值為5
<<< SliderRow(){
$0.title = "SliderRow"
$0.value = 5.0
}
//為區域添加1個增減器行,每次增減的大小為1
<<< StepperRow(){
$0.title = "StepperRow"
$0.value = 1.0
}
效果以下區域Row examples 中所示
點擊DateRow彈出日期選擇器效果
+++ Section("SegmentedRow examples")
//只包括3個選擇項
<<< SegmentedRow<String>(){
$0.options = ["One","Two","Three"]
}
//包括標題和3個選擇項
<<< SegmentedRow<String>(){
$0.title = "Who are you?"
$0.options = ["Summer", "Seven", "Leg", "Cannon Fly", "another one"]
//默許選中"Leg"
$0.value = "Leg"
}
//包括圖片和3個選擇項
<<< SegmentedRow<String>(){
$0.options = ["One", "Two", "Three", "Four"]
$0.value = "Three"
}.cellSetup{ cell, row in
cell.imageView?.image = UIImage(named: "sps.png")
}
+++ Section("Selectors Rows Examples")
//選擇框以對話框的情勢彈出
<<< ActionSheetRow<String>(){
$0.title = "ActionSheetRow"
$0.selectorTitle = "Your favorite player?"
$0.options = ["Diego Forlán", "Edinson Cavani", "Diego Lugano", "Luis Suarez"]
$0.value = "Luis Suarez"
}
//選擇框以Alert的情勢彈出
<<< AlertRow<String>(){
$0.title = "AlertRow"
$0.selectorTitle = "Who is there"
$0.options = ["Summer", "Seven", "Leg", "Cannon Fly", "another one"]
$0.value = "Summer"
//選中非當前值時打印新的值
}.onChange{ (row) in
print(row.value)
//選擇框出現時,設置字體色彩為紫色
}.onPresent({ (_, to) in
to.view.tintColor = .purpleColor()
})
//以navigation的情勢進入到1個新界面,其中每行動選擇內容
<<< PushRow<String>(){
$0.title = "PushRow"
$0.options = ["Summer", "Seven", "Leg", "Cannon Fly", "another one"]
$0.value = "Cannon Fly"
$0.selectorTitle = "Choose an Emoji!"
}
//ipad獨有的彈出框顯示方式
if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
//獲得section為當前表單最后1個區域
let section = form.last!
section <<< PopoverSelectorRow<String>(){
$0.title = "PopoverSelectorRow"
$0.options = ["Summer", "Seven", "Leg", "Cannon Fly", "another one"]
$0.value = "Seven"
$0.selectorTitle = "Choose an Emoji!"
}
}
let section = form.last!
section
//圖片選擇器,點擊從本地圖片庫選擇
<<< ImageRow(){
$0.title = "ImageRow"
}
//多選器,以navigation的情勢進入到1個新界面,其中每行動選擇內容
<<< MultipleSelectorRow<String>(){
$0.title = "MultipleSelectorRow"
$0.options = ["Summer", "Seven", "Leg", "Cannon Fly", "another one"]
$0.value = ["Summer", "Seven", "Leg"]
}
.onPresent{ from, to in
to.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Done, target: from, action: #selector(ViewController.multipleSelectorDone(_:)))
}
form +++ Section("Generic picker")
//普通picker選擇器
<<< PickerRow<String>("PickerRow"){(row : PickerRow<String>) -> Void in
row.options = []
for i in 1...10{
row.options.append("opition\(i)")
}
}
//內聯picker選擇器,可以通過點擊展開或收起選擇器
<<< PickerInlineRow("Inline picker"){(row : PickerInlineRow<String>) -> Void in
row.title = "Inline picker"
row.options = []
for i in 1...10{
row.options.append("opition\(i)")
}
}
由于博客上的編譯器不支持上面截圖中的圖片型的字符串,所以以下都替換為普通字符串
PushRow效果展現:
PopoverSelectorRow效果展現:
+++ Section("FieldRow examples")
//文本輸入框
<<< TextRow(){
$0.title = "TextRow"
$0.placeholder = "Placeholder"
}
//數字輸入框
<<< DecimalRow(){
$0.title = "DecimalRow"
$0.value = 5
$0.formatter = DecimalFormatter()
$0.useFormatterDuringInput = true
//設置輸入鍵盤為數字鍵盤
}.cellSetup{cell, _ in
cell.textField.keyboardType = .NumberPad
}
//url輸入框
<<< URLRow(){
$0.title = "URLRow"
$0.value = NSURL(string: "http://blog.csdn.net/sps900608")
}
//電話輸入框
<<< PhoneRow() {
$0.title = "PhoneRow (disabled)"
$0.value = "+598 9898983510"
$0.disabled = true
}
//姓名輸入框
<<< NameRow() {
$0.title = "NameRow"
}
//密碼輸入框
<<< PasswordRow() {
$0.title = "PasswordRow"
$0.value = "password"
}
//整數輸入框
<<< IntRow() {
$0.title = "IntRow"
$0.value = 2016
}
//電子郵箱輸入框
<<< EmailRow() {
$0.title = "EmailRow"
$0.value = "scuxiatian@foxmail.com"
}
//推特地址輸入框
<<< TwitterRow() {
$0.title = "TwitterRow"
$0.value = "@xmartlabs"
}
//賬戶輸入框
<<< AccountRow() {
$0.title = "AccountRow"
$0.placeholder = "Placeholder"
}
//zip碼輸入框
<<< ZipCodeRow{
$0.title = "ZipCodeRow"
$0.placeholder = "90210"
}
+++ Section("PostalAddressRow example")
//郵政地址輸入框
<<< PostalAddressRow(){
$0.title = "Address"
$0.streetPlaceholder = "Street"
$0.statePlaceholder = "State"
$0.postalCodePlaceholder = "ZipCode"
$0.cityPlaceholder = "City"
$0.countryPlaceholder = "Country"
//設置郵政地址的街道,郵編,城市,國家
$0.value = PostalAddress(
street: "Dr. Mario Cassinoni 1011",
state: nil,
postalCode: "11200",
city: "Montevideo",
country: "Uruguay"
)
}
效果以下所示:
除使用框架自帶的Row,還可以根據自己的需求自定義Row,下面以1個星期選擇行動例。首先創建類WeekDayRow.Swift
和nib文件WeekDaysCell.xib
。nib文件中只有1個TableViewCell,cell里并排有7個按鈕分別對應周日~周1,按鈕tittle為周日~周1英文的第1個字母,例如Monday對應的按鈕,tittle為M。這個nib文件可以在GitHub上下載,也能夠自己創建,另外需要用到選中和未選中的兩張圖片也都可以在GitHub上下載(選中時的圖片,未選中時的圖片)或用自己的,這里我用的是自己的。
import Foundation
import UIKit
import MapKit
import Eureka
//MARK: WeeklyDayCell
public enum WeekDay{
case Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}
public class WeekDayCell : Cell<Set<WeekDay>>, CellType{
//與nib中的7個按鈕建立鏈接
@IBOutlet var sundayButton: UIButton!
@IBOutlet var mondayButton: UIButton!
@IBOutlet var tuesdayButton: UIButton!
@IBOutlet var wednesdayButton: UIButton!
@IBOutlet var thursdayButton: UIButton!
@IBOutlet var fridayButton: UIButton!
@IBOutlet var saturdayButton: UIButton!
//重寫cell創建方法
public override func setup() {
height = {60}
row.title = nil
super.setup()
selectionStyle = .None
for subviews in contentView.subviews{
if let button = subviews as? UIButton{
//為每一個按鈕設置選中和未選中時的圖片
button.setImage(UIImage(named: "check.png"), forState: .Selected)
button.setImage(UIImage(named: "uncheck.png"), forState: .Normal)
//默許情況下,按鈕在被禁用時,圖象會被畫的色彩淡1些,設置為false是制止此功能
button.adjustsImageWhenDisabled = false
//自定義函數,設置按鈕標簽與圖片的位置
imageTopTittle(button)
}
}
}
//重寫cell更新方法
public override func update() {
row.title = nil
super.update()
let value = row.value
//根據value是不是包括某枚舉值來設置對應按鈕的選中狀態
mondayButton.selected = value?.contains(.Monday) ?? false
tuesdayButton.selected = value?.contains(.Tuesday) ?? false
wednesdayButton.selected = value?.contains(.Wednesday) ?? false
thursdayButton.selected = value?.contains(.Thursday) ?? false
fridayButton.selected = value?.contains(.Friday) ?? false
saturdayButton.selected = value?.contains(.Saturday) ?? false
sundayButton.selected = value?.contains(.Sunday) ?? false
//設置按鈕在不同狀態下的透明度
mondayButton.alpha = row.isDisabled ? 0.6 : 1.0
tuesdayButton.alpha = mondayButton.alpha
wednesdayButton.alpha = mondayButton.alpha
thursdayButton.alpha = mondayButton.alpha
fridayButton.alpha = mondayButton.alpha
saturdayButton.alpha = mondayButton.alpha
sundayButton.alpha = mondayButton.alpha
}
//每一個按鈕的點擊事件
@IBAction func dayTapped(sender : UIButton){
dayTapped(sender, day: getDayFromButton(sender))
}
//根據點擊的按鈕返回對應的枚舉值
private func getDayFromButton(button : UIButton) -> WeekDay{
switch button{
case sundayButton:
return .Sunday
case mondayButton:
return .Monday
case tuesdayButton:
return .Tuesday
case wednesdayButton:
return .Wednesday
case thursdayButton:
return .Thursday
case fridayButton:
return .Friday
default:
return .Saturday
}
}
//點擊改變按鈕的選中狀態,并從value中插入或刪除對應的枚舉值
private func dayTapped(button : UIButton, day:WeekDay){
button.selected = !button.selected
if button.selected {
row.value?.insert(day)
}
else{
row.value?.remove(day)
}
}
//設置按鈕標題和圖片的位置
private func imageTopTittle(button : UIButton){
guard let imageSize = button.imageView?.image?.size else{ return }
let spacing : CGFloat = 3.0
button.titleEdgeInsets = UIEdgeInsetsMake(0.0, -imageSize.width, -(imageSize.height + spacing), 0.0)
guard let titleLabel = button.titleLabel, let title = titleLabel.text else{ return }
let titleSize = title.sizeWithAttributes([NSFontAttributeName: titleLabel.font])
button.imageEdgeInsets = UIEdgeInsetsMake(-(titleSize.height + spacing), 0, 0, -titleSize.width)
}
}
//MARK: WeekDayRow
public final class WeekDayRow: Row<Set<WeekDay>, WeekDayCell>, RowType{
//重寫init方法
required public init(tag: String?) {
super.init(tag: tag)
displayValueFor = nil
cellProvider = CellProvider<WeekDayCell>(nibName: "WeekDaysCell")
}
}
完成以后就能夠用與其他Row1樣的方法來使用WeekDayRow了
<<< WeekDayRow(){
$0.value = [.Monday, .Wednesday, .Friday]
}
運行效果如圖所示:
這里列出了Eureka最基本的操作,Eureka還有更多豐富的功能,如果想要深入學習Eureka,可之前往GitHub-Eureka主頁!