1.8.1 前者

Former 1.8.1

测试已测试
Lang语言 SwiftSwift
许可证 MIT
发布最新发布2020年3月
SPM支持SPM

ra1028Zachary KhanDavid Greco 维护。



Former 1.8.1

  • 作者:
  • ra1028

Former

Former是一个完全可定制的Swift库,用于轻松创建基于UITableView的表单。

Swift CocoaPods Shield Carthage compatible MIT License

提交问题

点击这里开始提交错误报告。请使用此模板以确保您的错误报告不会因信息不足而被关闭。

提交功能请求

点击这里开始提交功能请求。请使用此模板以确保您的功能请求不会因信息不足而被拒绝。另外请注意,尽管我们希望尽可能让所有人都能胜任,但由于缺乏时间和与插件的定位不符,我们可能无法满足所有的功能请求,您可能需要考虑即使我们同意一个功能对插件有益,也需要进行贡献。

演示

内容

需求

  • Xcode 10+
  • Swift 4.2+
  • iOS 10.0+

仍然想使用 iOS7 和 Swift 2.2 或 2.3 吗?
-> 您可以使用 1.4.0

安装

CocoaPods

在您的 Podfile 中添加以下行

use_frameworks!

target 'YOUR_TARGET_NAME' do

  pod 'Former'
  
end

Carthage

在您的 Cartfile 中添加以下行

github "ra1028/Former"

用法

您可以同时设置单元格的样式和事件回调。
ViewController和Cell不需要覆盖提供的默认值。

简单示例

import Former

final class ViewController: FormViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let labelRow = LabelRowFormer<FormLabelCell>()
            .configure { row in
                row.text = "Label Cell"
            }.onSelected { row in
                // Do Something
        }
        let inlinePickerRow = InlinePickerRowFormer<FormInlinePickerCell, Int>() {
            $0.titleLabel.text = "Inline Picker Cell"
            }.configure { row in
                row.pickerItems = (1...5).map {
                    InlinePickerItem(title: "Option\($0)", value: Int($0))
                }
            }.onValueChanged { item in
                // Do Something
        }
        let header = LabelViewFormer<FormLabelHeaderView>() { view in
            view.titleLabel.text = "Label Header"
        }
        let section = SectionFormer(rowFormer: labelRow, inlinePickerRow)
            .set(headerViewFormer: header)
        former.append(sectionFormer: section)
    }
}

RowFormer

RowFormer是管理单元格的类的基类。受RowFormer类管理的单元格应遵循相应的协议。每个RowFormer类都在名为"on*"的函数(例如,onSelected、onValueChanged等)中暴露事件处理。
下面列出了提供的默认RowFormer类及其相应的协议。

演示 协议 默认提供的单元格
免费 CustomRowFormer
LabelRowFormer LabelFormableRow FormLabelCell
TextFieldRowFormer TextFieldFormableRow FormTextFieldCell
TextViewRowFormer TextViewFormableRow FormTextViewCell
CheckRowFormer CheckFormableRow FormCheckCell
SwitchRowFormer SwitchFormableRow FormSwitchCell
StepperRowFormer StepperFormableRow FormStepperCell
SegmentedRowFormer SegmentedFormableRow FormSegmentedCell
SliderRowFormer SliderFormableRow FormSliderCell
PickerRowFormer PickerFormableRow FormPickerCell
DatePickerRowFormer DatePickerFormableRow FormDatePickerCell
SelectorPickerRowFormer SelectorPickerFormableRow FormSelectorPickerCell
SelectorDatePickerRowFormer SelectorDatePickerFormableRow FormSelectorDatePickerCell
InlinePickerRowFormer InlinePickerFormableRow FormInlinePickerCell
InlineDatePickerRowFormer InlineDatePickerFormableRow FormInlineDatePickerCell

使用LabelRowFormer的示例

let labelRow = LabelRowFormer<YourLabelCell>(instantiateType: .Nib(nibName: "YourLabelCell")) {
    $0.titleLabel.textColor = .blackColor()
    }.configure { row in
        row.rowHeight = 44
        row.text = "Label Cell"
    }.onSelected { row in
        print("\(row.text) Selected !!")
}

更新单元格

row.update()
row.update { row in
    row.text = "Updated title"
}
row.cellUpdate { cell in
    cell.titleLabel.textColor = .redColor()
}

获取单元格实例

let cell = row.cell
print(cell.titleLabel.text)

设置动态行高

row.dynamicRowHeight { tableView, indexPath -> CGFloat in
    return 100
}

ViewFormer

ViewFormer是管理HeaderFooterView的类的基类。
受ViewFormer类管理的HeaderFooterView应遵循相应的协议。下面列出了提供的默认ViewFormer类及其相应的协议。

演示 协议 默认提供的单元格
免费 CustomViewFormer
LabelViewFormer LabelFormableView FormLabelHeaderView 和 FormLabelFooterView

使用LabelViewFormer的示例

let headerView = LabelViewFormer<YourLabelView>(instantiateType: .Nib(nibName: "YourLabelView")) {
    $0.titleLabel.textColor = .blackColor()
    }.configure { view in
        view.viewHeight = 30
        view.text = "Label HeaderFooter View"
}

SectionFormer

SectionFormer是一个表示TableView的节的类。
SectionFormer可以添加、删除行Former,并设置视图Former。
示例

let section = SectionFormer(rowFormer: row1, row2, row3)
    .set(headerViewFormer: headerView)
    .set(footerViewFormer: footerView)

添加单元格

section.append(rowFormer: row1, row2, row3)
section.add(rowFormers: rows)
section.insert(rowFormer: row, toIndex: 3)
section.insert(rowFormer: row, below: otherRow)
// etc...

删除单元格

section.remove(0)
section.remove(0...5)
section.remove(rowFormer: row)
// etc...

设置头部尾部视图

section.set(headerViewFormer: headerView)
section.set(footerViewFormer: footerView)

Former

Former是一个管理整个表单的类。
以下是一些示例。
添加节或单元格

former.append(sectionFormer: row)
former.add(sectionFormers: rows)
former.insert(sectionFormer: section, toSection: 0)
former.insert(rowFormer: row, toIndexPath: indexPath)
former.insert(sectionFormer: section, above: otherSection)
former.insert(rowFormers: row, below: otherRow)
// etc...

// with animation
former.insertUpdate(sectionFormer: section, toSection: 0, rowAnimation: .Automatic)
former.insertUpdate(rowFormer: row, toIndexPath: indexPath, rowAnimation: .Left)
former.insertUpdate(sectionFormer: section, below: otherSection, rowAnimation: .Fade)
former.insertUpdate(rowFormers: rows, above: otherRow, rowAnimation: .Bottom)
// etc...

删除节或单元格

former.removeAll()
former.remove(rowFormer: row1, row2)
former.remove(sectionFormer: section1, section2)
// etc...

// with animation
former.removeAllUpdate(.Fade)
former.removeUpdate(sectionFormers: sections, rowAnimation: .Middle)
// etc...

选择或取消选择单元格

former.select(indexPath: indexPath, animated: true, scrollPosition: .Middle)
former.select(rowFormer: row, animated: true)
former.deselect(true)
// etc...

结束编辑

former.endEditing()

编辑下一个/上一个单元格

if former.canBecomeEditingNext() {
    former.becomeEditingNext()
}
if former.canBecomeEditingPrevious() {
    former.becomeEditingPrevious()
}

事件处理设置函数

public func onCellSelected(handler: (NSIndexPath -> Void)) -> Self
public func onScroll(handler: ((scrollView: UIScrollView) -> Void)) -> Self    
public func onBeginDragging(handler: (UIScrollView -> Void)) -> Self
public func willDeselectCell(handler: (NSIndexPath -> NSIndexPath?)) -> Self
public func willDisplayCell(handler: (NSIndexPath -> Void)) -> Self
public func willDisplayHeader(handler: (/*section:*/Int -> Void)) -> Self
public func willDisplayFooter(handler: (/*section:*/Int -> Void)) -> Self        
public func didDeselectCell(handler: (NSIndexPath -> Void)) -> Self
public func didEndDisplayingCell(handler: (NSIndexPath -> Void)) -> Self
public func didEndDisplayingHeader(handler: (/*section:*/Int -> Void)) -> Self
public func didEndDisplayingFooter(handler: (/*section:*/Int -> Void)) -> Self
public func didHighlightCell(handler: (NSIndexPath -> Void)) -> Self
public func didUnHighlightCell(handler: (NSIndexPath -> Void)) -> Self

自定义能力

ViewController
无需继承FormViewController类。
相反,创建一个UITableView和Former的实例,如下例所示。

final class YourViewController: UIViewController {    

    private let tableView: UITableView = UITableView(frame: CGRect.zero, style: .Grouped) // It may be IBOutlet. Not forget to addSubview.
    private lazy var former: Former = Former(tableView: self.tableView)

    ...

**单元格** 同样无需继承默认提供的单元格类(如FormLabelCell等);只需符合相应的协议。当然可以使用Nib。以下是一个使用LabelRowFormer的示例

final class YourCell: UITableViewCell, LabelFormableRow {

    // MARK: LabelFormableRow

    func formTextLabel() -> UILabel? {
        return titleLabel
    }

    func formSubTextLabel() -> UILabel? {
        return subTitleLabel
    }

    func updateWithRowFormer(rowFormer: RowFormer) {
        // Do something
    }

    // MARK: UITableViewCell

    var titleLabel: UILabel?
    var subTitleLabel: UILabel?

    ...

**行Former** 如果要创建自定义RowFormer,则让您的类继承自BaseRowFormer并符合Formable协议。
它必须符合ConfigurableInlineForm。在InlineRowFomer的情况下,符合SelectorRowFormer的UpdatableSelectorForm情况。请参阅源代码以获取详细信息。
使用两个UITextFields单元格的RowFormer示例

public protocol DoubleTextFieldFormableRow: FormableRow {

    func formTextField1() -> UITextField
    func formTextField2() -> UITextField
}

public final class DoubleTextFieldRowFormer<T: UITableViewCell where T: DoubleTextFieldFormableRow>
: BaseRowFormer<T>, Formable {

    // MARK: Public

    override public var canBecomeEditing: Bool {
        return enabled
    }

    public var text1: String?
    public var text2: String?

    public required init(instantiateType: Former.InstantiateType = .Class, cellSetup: (T -> Void)? = nil) {
        super.init(instantiateType: instantiateType, cellSetup: cellSetup)
    }

    public final func onText1Changed(handler: (String -> Void)) -> Self {
        onText1Changed = handler
        return self
    }

    public final func onText2Changed(handler: (String -> Void)) -> Self {
        onText2Changed = handler
        return self
    }

    open override func cellInitialized(cell: T) {
        super.cellInitialized(cell)
        cell.formTextField1().addTarget(self, action: "text1Changed:", forControlEvents: .EditingChanged)
        cell.formTextField2().addTarget(self, action: "text2Changed:", forControlEvents: .EditingChanged)
    }

    open override func update() {
        super.update()

        cell.selectionStyle = .None
        let textField1 = cell.formTextField1()
        let textField2 = cell.formTextField2()
        textField1.text = text1
        textField2.text = text2        
    }

    // MARK: Private

    private final var onText1Changed: (String -> Void)?
    private final var onText2Changed: (String -> Void)?    

    private dynamic func text1Changed(textField: UITextField) {
        if enabled {
            let text = textField.text ?? ""
            self.text1 = text
            onText1Changed?(text)
        }
    }

    private dynamic func text2Changed(textField: UITextField) {
        if enabled {
            let text = textField.text ?? ""
            self.text2 = text
            onText2Changed?(text)
        }
    }
}

贡献

如果您有兴趣帮助我们改进和维护Former,强烈建议您分支存储库,并以您的更新提交_pull请求。

如果选择提交_pull请求,请确保在PR描述中清晰地记录您所做的更改。

许可证

Former可在MIT许可证下使用。有关更多信息,请参阅LICENSE文件。