
XmartLabsによって❤️で作られています。これは、SwiftのXLFormの再作成です。
简体中文
![]() | ![]() | ![]() |
|---|
詳細については、ユーレカを紹介するブログ投稿をご覧ください。
Eumekaの機能のほとんどの例を確認するために、プロジェクトのサンプルをクローンして実行できます。
![]() | ![]() |
|---|
FormViewController拡張することにより、 form変数にセクションと行を追加するだけです。
import Eureka
class MyFormViewController : FormViewController {
override func viewDidLoad ( ) {
super . viewDidLoad ( )
form +++ Section ( " Section1 " )
<<< TextRow ( ) { row in
row . title = " Text Row "
row . placeholder = " Enter text here "
}
<<< PhoneRow ( ) {
$0 . title = " Phone Row "
$0 . placeholder = " And numbers here "
}
+++ Section ( " Section2 " )
<<< DateRow ( ) {
$0 . title = " Date Row "
$0 . value = Date ( timeIntervalSinceReferenceDate : 0 )
}
}
}この例では、標準の行を持つ2つのセクションを作成します。結果は次のとおりです。

FormViewControllerから拡張せずに、 formプロパティを自分で設定するだけでフォームを作成できますが、この方法は通常、より便利です。
これの動作を変更するには、コントローラーのナビゲーションオプションを設定する必要があります。 FormViewControllerには、 navigationOptionsであり、次の値の1つ以上を持つことができます。
canBecomeFirstResponder()にfalseを返す行をスキップする必要がある場合デフォルト値がenabled & skipCanNotBecomeFirstResponderRow
画面外の行への滑らかなスクロールを有効にするには、 animateScrollプロパティを介してそれを有効にします。デフォルトでは、 FormViewController 、ユーザーが次の行が画面外にあるときを含め、キーボードナビゲーションの付属品の次または以前のボタンにヒットするときに行の間にジャンプします。
キーボードとナビゲーションイベントに続くハイライトされた行の間にスペースの量を設定するには、 rowKeyboardSpacingプロパティを設定します。デフォルトでは、フォームがオフスクリーンビューにスクロールすると、キーボードの上部と行の下部の間にスペースが残されません。
class MyFormViewController : FormViewController {
override func viewDidLoad ( ) {
super . viewDidLoad ( )
form = ...
// Enables the navigation accessory and stops navigation when a disabled row is encountered
navigationOptions = RowNavigationOptions . Enabled . union ( . StopDisabledRow )
// Enables smooth scrolling on navigation to off-screen rows
animateScroll = true
// Leaves 20pt of space between the keyboard and the highlighted row after scrolling to an off screen row
rowKeyboardSpacing = 20
}
}ナビゲーションアクセサリビュー全体を変更する場合は、 FormViewControllerのサブクラスのnavigationAccessoryView変数をオーバーライドする必要があります。
Rowオブジェクトは、特定のタイプの値を保持します。たとえば、 SwitchRow Bool値を保持しますが、 TextRow String値を保持します。
// Get the value of a single row
let row : TextRow ? = form . rowBy ( tag : " MyRowTag " )
let value = row . value
// Get the value of all rows which have a Tag assigned
// The dictionary contains the 'rowTag':value pairs.
let valuesDictionary = form . values ( )ユーレカには、フォーム作成を簡単にするためのカスタムオペレーターが含まれています。
form +++ Section ( )
// Chain it to add multiple Sections
form +++ Section ( " First Section " ) +++ Section ( " Another Section " )
// Or use it with rows and get a blank section for free
form +++ TextRow ( )
+++ TextRow ( ) // Each row will be on a separate sectionform +++ Section ( )
<<< TextRow ( )
<<< DateRow ( )
// Or implicitly create the Section
form +++ TextRow ( )
<<< DateRow ( ) // Append Sections into a Form
form += [ Section ( " A " ) , Section ( " B " ) , Section ( " C " ) ]
// Append Rows into a Section
section += [ TextRow ( ) , DateRow ( ) ]ユーレカには、フォーム作成を簡単にするための結果ビルダーが含まれています。
// Section + Section
form = ( Section ( " A " ) +++ {
URLRow ( " UrlRow_f1 " ) { $0 . title = " Url " }
if something {
TwitterRow ( " TwitterRow_f2 " ) { $0 . title = " Twitter " }
} else {
TwitterRow ( " TwitterRow_f1 " ) { $0 . title = " Twitter " }
}
AccountRow ( " AccountRow_f1 " ) { $0 . title = " Account " }
} )
// Form + Section
form +++ {
if something {
PhoneRow ( " PhoneRow_f1 " ) { $0 . title = " Phone " }
} else {
PhoneRow ( " PhoneRow_f2 " ) { $0 . title = " Phone " }
}
PasswordRow ( " PasswordRow_f1 " ) { $0 . title = " Password " }
} @ FormBuilder
var form : Form {
Section ( " Section A " ) { section in
section . tag = " Section_A "
}
if true {
Section ( " Section B " ) { section in
section . tag = " Section_B "
}
}
NameRow ( " NameRow_f1 " ) { $0 . title = " Name " }
}ユーレカには、行の外観と動作を変更するためのコールバックが含まれています。
Row 、eurekaが使用する抽象化であり、値を保持し、 Cellを含みます。 Cellビューを管理し、サブクラスはUITableViewCellです。
これが例です:
let row = SwitchRow ( " SwitchRow " ) { row in // initializer
row . title = " The title "
} . onChange { row in
row . title = ( row . value ?? false ) ? " The title expands when on " : " The title "
row . updateCell ( )
} . cellSetup { cell , row in
cell . backgroundColor = . lightGray
} . cellUpdate { cell , row in
cell . textLabel ? . font = . italicSystemFont ( ofSize : 18.0 )
} 
onchange()
行の値が変更されたときに呼び出されます。ここでいくつかのパラメーターを調整することに興味があるか、他のいくつかの行を表示したり消えたりすることにさえ興味があるかもしれません。
oncellSelection()
ユーザーが行をタップするたびに電話をかけると、選択されます。これは無効な行も呼び出されるので、 guard !row.isDisabled else { return }
cellsetup()
セルが最初に構成されている場合にのみ1回呼び出されます。ここで永続的な設定を設定します。
cellupdate()
セルが画面に表示されるたびに呼び出されます。 CellSetup()に存在しない可能性のある変数を使用して、こちらの外観を変更できます。
oncellhighlighlightchanged()
セルまたはサブビューが最初の応答者になったり辞任したりするたびに呼び出されます。
onrowvalidationChanged()
行に関連付けられた検証エラーが変更されるたびに呼び出されます。
onexpandinlinerow()
インライン列を拡張する前に呼び出されます。 InlineRowTypeプロトコルに適合する行に適用されます。
oncollapseinlinerow()
インライン列を倒す前に呼び出されます。 InlineRowTypeプロトコルに適合する行に適用されます。
onpresent()
別のビューコントローラーを提示する直前に行で呼び出されます。 PresenterRowTypeプロトコルに適合する行に適用されます。それを使用して、提示されたコントローラーをセットアップします。
SectionのヘッダーまたはフッターとしてタイトルStringまたはカスタムViewを設定できます。
Section ( " Title " )
Section ( header : " Title " , footer : " Footer Title " )
Section ( footer : " Footer Title " ) .xibファイルからカスタムビューを使用できます。
Section ( ) { section in
var header = HeaderFooterView < MyHeaderNibFile > ( . nibFile ( name : " MyHeaderNibFile " , bundle : nil ) )
// Will be called every time the header appears on screen
header . onSetupView = { view , _ in
// Commonly used to setup texts inside the view
// Don't change the view hierarchy or size here!
}
section . header = header
}またはプログラムで作成されたカスタムUIView
Section ( ) { section in
var header = HeaderFooterView < MyCustomUIView > ( . class )
header . height = { 100 }
header . onSetupView = { view , _ in
view . backgroundColor = . red
}
section . header = header
}または、コールバックでビューを構築するだけです
Section ( ) { section in
section . header = {
var header = HeaderFooterView < UIView > ( . callback ( {
let view = UIView ( frame : CGRect ( x : 0 , y : 0 , width : 100 , height : 100 ) )
view . backgroundColor = . red
return view
} ) )
header . height = { 100 }
return header
} ( )
}
この場合、セクション全体を隠して表示しています。
これを達成するために、各行には、関数またはNSPredicateを使用して設定できるオプションのタイプConditionのhidden変数があります。
Conditionのfunctionの場合:
Condition . function ( [ String ] , ( Form ) - > Bool )通過するStringの配列には、この行が依存する行のタグを含める必要があります。これらの行のいずれかの値が変更されるたびに、関数は再評価されます。次に、この関数はFormを取得し、行を非表示にするかどうかを示すBoolを返します。これは、何ができるかについて明示的な制限がないため、 hiddenプロパティを設定する最も強力な方法です。
form +++ Section ( )
<<< SwitchRow ( " switchRowTag " ) {
$0 . title = " Show message "
}
<<< LabelRow ( ) {
$0 . hidden = Condition . function ( [ " switchRowTag " ] , { form in
return ! ( ( form . rowBy ( tag : " switchRowTag " ) as? SwitchRow ) ? . value ?? false )
} )
$0 . title = " Switch is on! "
} 
public enum Condition {
case function ( [ String ] , ( Form ) -> Bool )
case predicate ( NSPredicate )
} hidden変数は、nspredicateで設定することもできます。述語文字列では、タグによって他の行の値を参照して、行を非表示または表示するかどうかを判断できます。これは、述語が確認する行の値がnsobjectsである場合にのみ機能します(StringとIntはOBJCのカウンターパートに橋渡しされますが、列挙は機能しません)。それから、述語がより制限されているときに述語を使用することが役立つのはなぜですか?まあ、それらは機能よりもはるかにシンプルで、短く、読みやすいことがあります。この例を見てください:
$0 . hidden = Condition . predicate ( NSPredicate ( format : " $switchTag == false " ) )そして、 Condition ExpressibleByStringLiteralに準拠しているため、さらに短く書くことができます。
$0 . hidden = " $switchTag == false "注:「$ switchtag」の代わりにタグが「スイッチタグ」である行の値を置き換えます
これらすべてが機能するためには、タグがそれらを識別するため、すべての関係する行にタグが必要です。
また、次のことを行うことで行を隠すこともできます。
$0 . hidden = true ConditionがExpressibleByBooleanLiteralに準拠するように。
非hidden変数を設定しないと、行が常に表示されます。
フォームが表示された後に隠された(または無効)状態を手動で設定した場合row.evaluateHidden()を呼び出して、ユーレカに新しい条件を再評価するように強制する必要がある場合があります。詳細については、このFAQセクションを参照してください。
セクションの場合、これは同じように機能します。つまり、[ hiddenプロパティ]を設定して、動的に表示/非表示にすることができます。
行を無効にするために、各行にはdisabled変数があり、これもオプションのConditionタイプのプロパティです。また、この変数はhidden変数と同じように動作するため、行がタグを付ける必要があります。
行を永久に無効にする場合は、 disabled変数をtrueに設定することもできることに注意してください。
オプションのリストを表示するために、EurekaにはSelectableSectionという特別なセクションが含まれています。 1つを作成するときは、オプションとselectionTypeで使用するために行のタイプを渡す必要があります。 selectionType 、 enableDeselectionパラメーターが選択した行を選択できないかどうかを判断するmultipleSelectionまたはsingleSelection(enableDeselection: Bool)のいずれかである可能性がある列挙です。
form +++ SelectableSection < ListCheckRow < String > > ( " Where do you live " , selectionType : . singleSelection ( enableDeselection : true ) )
let continents = [ " Africa " , " Antarctica " , " Asia " , " Australia " , " Europe " , " North America " , " South America " ]
for option in continents {
form . last! <<< ListCheckRow < String > ( option ) { listRow in
listRow . title = option
listRow . selectableValue = option
listRow . value = nil
}
} このようなセクションを作成するには、 SelectableRowTypeプロトコルに準拠する行を作成する必要があります。
public protocol SelectableRowType : RowType {
var selectableValue : Value ? { get set }
}このselectableValueは、行の値が永続的に保存される場所です。 value変数を使用して、行が選択されているかどうかを判断し、選択された場合は「選択可能」であるか、それ以外の場合はゼロです。 Eurekaには、たとえば使用されるListCheckRowが含まれています。 Examplesプロジェクトのカスタム行では、 ImageCheckRowも見つけることができます。
SelectableSectionの選択した行を簡単に取得するには、2つの方法があります。SelectedRow selectedRow()とselectedRows()を呼び出して、選択した行を取得するために、 SingleSelection MultipleSelectionセクションの場合、選択したすべての行です。
さらに、 SelectorViewControllerの次のプロパティを使用して、セクションでグループ化されるオプションのリストをセットアップできます。
sectionKeyForValue特定の行の値に対してキーを返すようにする閉鎖。このキーは、後でセクションごとにオプションを破るために使用されます。
sectionHeaderTitleForKey特定のキーのセクションのヘッダータイトルを返すクロージャー。デフォルトでは、キー自体を返します。
sectionFooterTitleForKey特定のキーのセクションのフッタータイトルを返すクロージャー。
Eurekaは、多価セクションを使用して、特定のフィールド(連絡先の電話番号など)の複数の値をサポートしています。挿入可能で削除可能な並べ替え可能なセクションを簡単に作成できます。

複数のセクションを作成するには、通常のSectionタイプの代わりにMultivaluedSectionタイプを使用する必要があります。 MultivaluedSection Sectionを拡張し、複数のセクションの動作を構成するための追加のプロパティがあります。
コードの例に飛び込みましょう...
form +++
MultivaluedSection ( multivaluedOptions : [ . Reorder , . Insert , . Delete ] ,
header : " Multivalued TextField " ,
footer : " .Insert adds a 'Add Item' (Add New Tag) button row as last cell. " ) {
$0 . addButtonProvider = { section in
return ButtonRow ( ) {
$0 . title = " Add New Tag "
}
}
$0 . multivaluedRowToInsertAt = { index in
return NameRow ( ) {
$0 . placeholder = " Tag Name "
}
}
$0 <<< NameRow ( ) {
$0 . placeholder = " Tag Name "
}
}以前のコードスニペットには、マルチバリューセクションの作成方法が示されています。この場合、MultivaluedOptions引数が示すように、行を挿入、削除、並べ替えます。
addButtonProvider使用すると、タップmultivaluedOptionsれたときに新しい行を挿入するボタン行をカスタマイズできます.Insert
multivaluedRowToInsertAt閉鎖プロパティは、新しい行を挿入する必要があるたびにEurekaによって呼び出されます。複数のセクションに追加する行を提供するには、このプロパティを設定する必要があります。 Eurekaは、閉鎖パラメーターとしてインデックスを渡します。ほとんどの場合、複数のセクションの行が同じタイプであるにもかかわらず、あらゆる種類の行、さらにはカスタム行を返すことができることに注意してください。
Eurekaは、挿入可能なマルチバリューセクションを作成するときにボタン行を自動的に追加します。以前に説明したように、このボタンの行がどのように見えるかをカスタマイズできます。 showInsertIconInAddButtonプロパティは、ボタンの左側にプラスボタン(挿入スタイル)が表示されるかどうかを示します。デフォルトでは真です。
挿入可能なセクションを作成する際には、念頭に置く必要がある考慮事項がいくつかあります。挿入可能なマルチバリューセクションに追加された行は、Eurekaが自動的に追加する行の上に、新しい行を挿入する行を配置する必要があります。これは、セクションの初期イザーの閉鎖(セクションInitializerの最後のパラメーター)の内側からセクションにこれらの追加行を追加することで簡単に実現できます。
デフォルトでは、eurekaは、形式に多バリューションセクションがある場合にのみ、TableViewのisEditing Trueに設定します。これは、フォームが初めて表示されたときにviewWillAppearで行われます。
マルチバリューセクションの使用方法の詳細については、いくつかの使用例を含むEureka Exampleプロジェクトをご覧ください。
ButtonRowではない追加ボタンを使用する場合は、 GenericMultivaluedSection<AddButtonType>を使用できます。AddButtonType AddButtonType 、追加ボタンとして使用する行のタイプです。これは、カスタム行を使用してボタンのUIを変更する場合に便利です。
例:
GenericMultivaluedSection < LabelRow > ( multivaluedOptions : [ . Reorder , . Insert , . Delete ] , {
$0 . addButtonProvider = { section in
return LabelRow ( ) {
$0 . title = " A Label row as add button "
}
}
// ...
}Eureka 2.0.0は、要求された多くの組み込み検証機能を紹介します。
行には、 Rulesのコレクションと、検証ルールをいつ評価する必要があるかを決定する特定の構成があります。
デフォルトで提供されるルールがいくつかありますが、自分で新しいルールを作成することもできます。
提供されたルールは次のとおりです。
検証ルールを設定する方法を見てみましょう。
override func viewDidLoad ( ) {
super . viewDidLoad ( )
form
+++ Section ( header : " Required Rule " , footer : " Options: Validates on change " )
<<< TextRow ( ) {
$0 . title = " Required Rule "
$0 . add ( rule : RuleRequired ( ) )
// This could also have been achieved using a closure that returns nil if valid, or a ValidationError otherwise.
/*
let ruleRequiredViaClosure = RuleClosure<String> { rowValue in
return (rowValue == nil || rowValue!.isEmpty) ? ValidationError(msg: "Field required!") : nil
}
$0.add(rule: ruleRequiredViaClosure)
*/
$0 . validationOptions = . validatesOnChange
}
. cellUpdate { cell , row in
if !row . isValid {
cell . titleLabel ? . textColor = . systemRed
}
}
+++ Section ( header : " Email Rule, Required Rule " , footer : " Options: Validates on change after blurred " )
<<< TextRow ( ) {
$0 . title = " Email Rule "
$0 . add ( rule : RuleRequired ( ) )
$0 . add ( rule : RuleEmail ( ) )
$0 . validationOptions = . validatesOnChangeAfterBlurred
}
. cellUpdate { cell , row in
if !row . isValid {
cell . titleLabel ? . textColor = . systemRed
}
}以前のコードスニペットでわかるように、行のadd(rule:)関数を呼び出すことで、必要な数のルールを連続して設定できます。
rowは、ルールを削除するためにfunc remove(ruleWithIdentifier identifier: String)も提供します。それを使用するには、IDを作成した後、IDをルールに割り当てる必要があります。
行で使用したいルールのコレクションは、他の多くの行で使用したいのと同じである場合があります。この場合、検証ルールのコレクションであるRuleSetを使用して、すべての検証ルールを設定できます。
var rules = RuleSet < String > ( )
rules . add ( rule : RuleRequired ( ) )
rules . add ( rule : RuleEmail ( ) )
let row = TextRow ( ) {
$0 . title = " Email Rule "
$0 . add ( ruleSet : rules )
$0 . validationOptions = . validatesOnChangeAfterBlurred
} eurekaでは、検証ルールを評価する必要がある時期を指定できます。 validationOptions rowのプロパティを設定することでそれを行うことができます。これには、次の値を持つことができます。
.validatesOnChange行の値が変更されるたびに検証します。.validatesOnBlur (デフォルト値)セルが最初の応答者を辞任した直後に検証します。すべての行には適用されません。.validatesOnChangeAfterBlurred初めて辞任した後、行の値が変化するたびに検証します。.validatesOnDemand validate()メソッドを呼び出すことにより、行またはフォームを手動で検証する必要があります。フォーム全体(すべての行)を検証する場合は、Form validate()メソッドを手動で呼び出すことができます。
各行には、すべての検証エラーを取得するために使用できるvalidationErrorsプロパティがあります。このプロパティは、最新の行検証実行の検証エラーリストを保持するだけです。つまり、行の検証ルールを評価しません。
予想どおり、ルールは行と同じタイプを使用する必要があります。使用する行タイプを確認するように特に注意してください。コンパイラエラー( "Callに誤ったアリッガメントラベル( 'ルール:「予想」ルールセット:'を持っている)が表示される場合があります。
スワイプアクションを使用することにより、行ごとに複数のleadingSwipeとtrailingSwipeアクションを定義できます。スワイプアクションがiOSシステム機能に依存するため、 leadingSwipe iOS 11.0+のみで利用できます。
スワイプアクションを定義する方法を見てみましょう。
let row = TextRow ( ) {
let deleteAction = SwipeAction (
style : . destructive ,
title : " Delete " ,
handler : { ( action , row , completionHandler ) in
//add your code here.
//make sure you call the completionHandler once done.
completionHandler ? ( true )
} )
deleteAction . image = UIImage ( named : " icon-trash " )
$0 . trailingSwipe . actions = [ deleteAction ]
$0 . trailingSwipe . performsFirstActionWithFullSwipe = true
//please be aware: `leadingSwipe` is only available on iOS 11+ only
let infoAction = SwipeAction (
style : . normal ,
title : " Info " ,
handler : { ( action , row , completionHandler ) in
//add your code here.
//make sure you call the completionHandler once done.
completionHandler ? ( true )
} )
infoAction . actionBackgroundColor = . blue
infoAction . image = UIImage ( named : " icon-info " )
$0 . leadingSwipe . actions = [ infoAction ]
$0 . leadingSwipe . performsFirstActionWithFullSwipe = true
}スワイプアクションがtableView.isEditing falseに設定する必要があります。 Eurekaは、形式に多面的なセクションがある場合、これをtrueに設定します( viewWillAppear )。複数の値と同じ形式でアクションの両方をスワイプする場合は、ニーズに応じてisEditingを設定する必要があります。
ユーレカに含まれるものとは異なる行が必要なことは非常に一般的です。この場合、独自の行を作成する必要がありますが、これは難しくないはずです。このチュートリアルは、カスタム行を作成して開始する方法について読むことができます。また、ユーレカに追加する準備ができているいくつかの追加の行を含むEurekacomunityをご覧ください。
カスタムの動作と外観を備えた行を作成するには、おそらくRowとCellのサブクラスを作成したいと思うでしょう。
Row eurekaが使用する抽象化であり、 Cellビューを担当する実際のUITableViewCellであることを忘れないでください。 Row Cellが含まれているため、同じ値タイプに対してRowとCellの両方を定義する必要があります。
// Custom Cell with value type: Bool
// The cell is defined using a .xib, so we can set outlets :)
public class CustomCell : Cell < Bool > , CellType {
@ IBOutlet weak var switchControl : UISwitch !
@ IBOutlet weak var label : UILabel !
public override func setup ( ) {
super . setup ( )
switchControl . addTarget ( self , action : #selector ( CustomCell . switchValueChanged ) , for : . valueChanged )
}
func switchValueChanged ( ) {
row . value = switchControl . on
row . updateCell ( ) // Re-draws the cell which calls 'update' bellow
}
public override func update ( ) {
super . update ( )
backgroundColor = ( row . value ?? false ) ? . white : . black
}
}
// The custom Row also has the cell: CustomCell and its correspond value
public final class CustomRow : Row < CustomCell > , RowType {
required public init ( tag : String ? ) {
super . init ( tag : tag )
// We set the cellProvider to load the .xib corresponding to our cell
cellProvider = CellProvider < CustomCell > ( nibName : " CustomCell " )
}
}結果: 
Callbacks CellsetupとCellUpdateと同様に、 Cellはセットアップおよび更新メソッドがあり、カスタマイズできます。
インラインの行は、その下の行を動的に示す特定のタイプの行です。通常、行がタップされるたびに拡張モードと崩壊モードの間のインライン行の変更が変更されます。
したがって、インラインの行を作成するには、2行、「常に」目に見える行、拡張/崩壊する行が必要です。
別の要件は、これら2行の値タイプが同じでなければならないことです。つまり、1つの行がString値を保持している場合、もう1つの行にString値も必要です。
これらの2行があれば、Top ow型のタイプをInlineRowTypeに適合させる必要があります。このプロトコルでは、 InlineRow TypealiasとsetupInlineRow関数を定義する必要があります。 InlineRowタイプは、拡張/崩壊する行のタイプになります。これを例として考えてみましょう:
class PickerInlineRow < T > : Row < PickerInlineCell < T > > where T : Equatable {
public typealias InlineRow = PickerRow < T >
open var options = [ T ] ( )
required public init ( tag : String ? ) {
super . init ( tag : tag )
}
public func setupInlineRow ( _ inlineRow : InlineRow ) {
inlineRow . options = self . options
inlineRow . displayValueFor = self . displayValueFor
inlineRow . cell . height = { UITableViewAutomaticDimension }
}
} InlineRowType 、インラインの列にもいくつかの方法を追加します。
func expandInlineRow ( )
func collapseInlineRow ( )
func toggleInlineRow ( )これらの方法は正常に動作するはずですが、それらをオーバーライドする必要がある場合は、 expandInlineRowとcollapseInlineRowを呼び出さなければならないのはtoggleInlineRowであることに留意してください。
最後に、行customDidSelect選択されているときにtoggleInlineRow()を呼び出す必要があります。
public override func customDidSelect ( ) {
super . customDidSelect ( )
if !isDisabled {
toggleInlineRow ( )
}
}注:プレゼンターの行は、新しいuiviewcontrollerを提示する行です。
カスタムプレゼンターの行を作成するには、 PresenterRowTypeプロトコルに準拠するクラスを作成する必要があります。 Subclass SelectorRowは、そのプロトコルに適合し、他の有用な機能を追加するため、強くお勧めします。
PresenterRowTypeプロトコルは、次のように定義されています。
public protocol PresenterRowType : TypedRowType {
associatedtype PresentedControllerType : UIViewController , TypedRowControllerType
/// Defines how the view controller will be presented, pushed, etc.
var presentationMode : PresentationMode < PresentedControllerType > ? { get set }
/// Will be called before the presentation occurs.
var onPresentCallback : ( ( FormViewController , PresentedControllerType ) -> Void ) ? { get set }
} OnpresentCallbackは、行が別のビューコントローラーを提示しようとしているときに呼び出されます。これはSelectorRowで行われるので、サブクラス化しない場合は自分で呼び出す必要があります。
presentationModeは、コントローラーの表示方法とどのコントローラーが表示されるかを定義するものです。このプレゼンテーションには、Segue Identifier、Segueクラスを使用して、コントローラーをモジュアルに提示するか、特定のビューコントローラーにプッシュすることができます。たとえば、CustomPushrowは次のように定義できます。
例を見てみましょう。
/// Generic row type where a user must select a value among several options.
open class SelectorRow < Cell : CellType > : OptionsRow < Cell > , PresenterRowType where Cell : BaseCell {
/// Defines how the view controller will be presented, pushed, etc.
open var presentationMode : PresentationMode < SelectorViewController < SelectorRow < Cell > > > ?
/// Will be called before the presentation occurs.
open var onPresentCallback : ( ( FormViewController , SelectorViewController < SelectorRow < Cell > > ) -> Void ) ?
required public init ( tag : String ? ) {
super . init ( tag : tag )
}
/**
Extends `didSelect` method
*/
open override func customDidSelect ( ) {
super . customDidSelect ( )
guard let presentationMode = presentationMode , !isDisabled else { return }
if let controller = presentationMode . makeController ( ) {
controller . row = self
controller . title = selectorTitle ?? controller . title
onPresentCallback ? ( cell . formViewController ( ) ! , controller )
presentationMode . present ( controller , row : self , presentingController : self . cell . formViewController ( ) ! )
} else {
presentationMode . present ( nil , row : self , presentingController : self . cell . formViewController ( ) ! )
}
}
/**
Prepares the pushed row setting its title and completion callback.
*/
open override func prepare ( for segue : UIStoryboardSegue ) {
super . prepare ( for : segue )
guard let rowVC = segue . destination as Any as? SelectorViewController < SelectorRow < Cell > > else { return }
rowVC . title = selectorTitle ?? rowVC . title
rowVC . onDismissCallback = presentationMode ? . onDismissCallback ?? rowVC . onDismissCallback
onPresentCallback ? ( cell . formViewController ( ) ! , rowVC )
rowVC . row = self
}
}
// SelectorRow conforms to PresenterRowType
public final class CustomPushRow < T : Equatable > : SelectorRow < PushSelectorCell < T > > , RowType {
public required init ( tag : String ? ) {
super . init ( tag : tag )
presentationMode = . show ( controllerProvider : ControllerProvider . callback {
return SelectorViewController < T > ( ) { _ in }
} , onDismiss : { vc in
_ = vc . navigationController ? . popViewController ( animated : true )
} )
}
}行の1つのUIルックを変更したいが、行のタイプと1つの行に関連付けられたすべてのロジックを変更せずに変更することをお勧めします。現在、NIBファイルからインスタンス化されたセルを使用している場合、これを行う1つの方法があります。現在、Eurekaのコア行のいずれもNIBファイルからインスタンス化されていませんが、Eurekacomunityのカスタム行の一部は、特にそこに移動した郵便配置の段階です。
あなたがしなければならないことは:
cellProvider変数を設定してこのペン先を使用することによって行われます。これは、各コンクリートのインスタンス化またはdefaultRowInitializerを使用して、初期化装置で行う必要があります。例えば: <<< PostalAddressRow ( ) {
$0 . cellProvider = CellProvider < PostalAddressCell > ( nibName : " CustomNib " , bundle : Bundle . main )
}これのための新しい行を作成することもできます。その場合、変更したい行と同じスーパークラスから継承して、その論理を継承します。
あなたがこれを行うときに考慮すべきことがいくつかあります:
Unknown class <YOUR_CLASS_NAME> in Interface Builder fileという点でエラーが発生した場合、コードのどこかに新しいタイプをインスタンス化してランタイムにロードする必要がある可能性があります。 let t = YourClass.selfを呼び出して、私の場合に役立ちました。 ラベルの行![]() | ボタン行![]() | 行を確認してください![]() |
スイッチ行![]() | スライダーの行![]() | ステッパーの列![]() |
テキストエリアの行![]() |
これらの行には、セルの右側にテキストフィールドがあります。それらのそれぞれの違いは、異なる大文字、自動補正、キーボードタイプの構成で構成されています。
![]() | テキストロウ ナメロー urlrow INROW フォネロー PasswordRow emailrow デシマロウ Twitterrow Accountrow zipcoderow |
上記のすべてのFieldRowサブタイプには、その行の値を表示する方法を決定するために設定できるタイプNSFormatterのformatterプロパティがあります。小桁マークの後に2桁の数字のカスタムフォーマッタは、ユーレカ( DecimalFormatter )に含まれています。この例には、ユーザーのロケールに応じて通貨として数値を表示するCurrencyFormatterも含まれています。
デフォルトでは、行のformatterの設定は、編集されていない場合の値の表示方法にのみ影響します。また、行の編集中に値をフォーマットするには、行を初期化するときにuseFormatterDuringInput trueに設定します。編集中に値をフォーマットすると、カーソル位置を更新する必要があり、eurekaは、カーソルの位置を処理するためにフォーマッタが準拠する必要がある次のプロトコルを提供する場合があります。
public protocol FormatterProtocol {
func getNewPosition ( forPosition forPosition : UITextPosition , inTextInput textInput : UITextInput , oldValue : String ? , newValue : String ? ) -> UITextPosition
}さらに、 FieldRowサブタイプには、 useFormatterOnDidBeginEditingプロパティがあります。 10進数を許可し、ユーザーのロケールに準拠するフォーマッタを使用してDecimalRowを使用する場合(例えば、 DecimalFormatter )、 useFormatterDuringInputがfalse場合、編集中の値の小数マークがキーボードの小数マークと一致するように、 useFormatterOnDidBeginEditing trueに設定する必要があります。
日付行は日付を保持し、uidatepickerコントロールを介して新しい値を設定できるようにします。 uidatepickerのモードと、日付ピッカービューの表示方法は、それらの間の変化です。
日付の行![]() キーボードに示されているピッカー。 | 日付の行(インライン) ![]() 行が展開されます。 | 日付の行(ピッカー) ![]() ピッカーは常に表示されます。 |
これらの3つのスタイル(通常、インライン、ピッカー)には、ユーレカには以下が含まれます。
これらは、ユーザーが選択する必要があるオプションのリストがある行です。
<<< ActionSheetRow < String > ( ) {
$0 . title = " ActionSheetRow "
$0 . selectorTitle = " Pick a number "
$0 . options = [ " One " , " Two " , " Three " ]
$0 . value = " Two " // initially selected
}アラート行![]() 選択するオプションでアラートが表示されます。 | アクションシート行![]() 選択するオプションを備えたアクションシートが表示されます。 | 行を押します![]() チェック行を使用してリストされているオプションを選択する場所から新しいコントローラーにプッシュします。 | 複数のセレクターの行![]() Pushrowのように、複数のオプションを選択できます。 |
セグメント化された行![]() | セグメント化された行(タイトル付き)![]() | ピッカーロウ![]() ピッカービューを介して一般的なタイプのオプションを提示する (ピッカーインラインの行もあります) |
それについてお知らせください、私たちはここでそれについて言及してうれしいです。 :)

Cocoapodsは、Cocoaプロジェクトの依存マネージャーです。
EurekaをプロジェクトのPodfileに指定します。
source 'https://github.com/CocoaPods/Specs.git'
platform :ios , '9.0'
use_frameworks!
pod 'Eureka'次に、次のコマンドを実行します。
$ pod installSwift Package Managerは、Swiftコードの配布を管理するためのツールです。
Package.swift Manifestファイルをセットアップした後、eurekaを依存関係として追加することができます。 Package.swiftの依存関係値に追加できます。
依存関係:[.package(url: "https://github.com/xmartlabs/eureka.git"、from: "5.5.0")]]
Carthageは、Cocoaのシンプルで分散依存症の依存マネージャーです。
eurekaをプロジェクトのCartfileに指定します。
github "xmartlabs/Eureka" ~> 5.5
$ git submodule add https://github.com/xmartlabs/Eureka.git以前のgitサブモジュールコマンドによって作成されたeurekaフォルダーを開き、eureka.xcodeprojをアプリケーションのXcodeプロジェクトのプロジェクトナビゲーターにドラッグします。
プロジェクトナビゲーターでeureka.xcodeprojを選択し、アプリケーション展開ターゲットで展開目標マッチを確認します。
Xcodeナビゲーションでプロジェクトを選択し、サイドバーからアプリケーションターゲットを選択します。次に、[一般]タブを選択し、[埋め込まれたバイナリ]セクションの下の +ボタンをクリックします。
Eureka.frameworkを選択すると、完了です!
eureka-forms )。貢献する前に、詳細については、寄付ファイルを確認してください。
あなたのアプリでeurekaを使用する場合、私たちはそれについて聞いてみたいです! Twitterにラインをドロップしてください。
すべての行には次のプロパティがあります。
/// Block variable used to get the String that should be displayed for the value of this row.
public var displayValueFor : ( ( T ? ) -> String ? ) ? = {
return $0 . map { String ( describing : $0 ) }
}表示する文字列値に応じてdisplayValueFor設定できます。
Formクラスによって公開された次の関数のいずれかを呼び出すことで、特定の行を取得できます。
public func rowBy < T : Equatable > ( tag : String ) -> RowOf < T > ?
public func rowBy < Row : RowType > ( tag : String ) -> Row ?
public func rowBy ( tag : String ) -> BaseRow ?例えば:
let dateRow : DateRow ? = form . rowBy ( tag : " dateRowTag " )
let labelRow : LabelRow ? = form . rowBy ( tag : " labelRowTag " )
let dateRow2 : Row < DateCell > ? = form . rowBy ( tag : " dateRowTag " )
let labelRow2 : BaseRow ? = form . rowBy ( tag : " labelRowTag " ) let section : Section ? = form . sectionBy ( tag : " sectionTag " ) setValues(values: [String: Any?]) Formクラスによって公開されます。
例えば:
form . setValues ( [ " IntRowTag " : 8 , " TextRowTag " : " Hello world! " , " PushRowTag " : Company ( name : " Xmartlabs " ) ] ) "IntRowTag" 、 "TextRowTag" 、 "PushRowTag"は行タグ(それぞれが行を一意に識別します)と8 、 "Hello world!"です。 、 Company(name:"Xmartlabs")は、割り当てる対応する行の値です。
行の値タイプは、対応する辞書値の値タイプと一致する必要があります。
フォームが既に表示されている場合、テーブルビューを再ロードすることにより、可視行をリロードする必要がありますtableView.reloadData()または各可視行にupdateCell()を呼び出す必要があります。
条件を設定した後、この条件は自動的に評価されません。すぐにそうしたい場合は.evaluateHidden()または.evaluateDisabled()を呼び出すことができます。
この関数は、行がフォームに追加され、行が変更に依存するときに呼び出されます。行が表示されているときに条件が変更された場合、手動で再評価する必要があります。
この問題を見てください。
section . header = HeaderFooterView ( title : " Header title ( variable ) " ) // use String interpolation
//or
var header = HeaderFooterView < UIView > ( . class ) // most flexible way to set up a header using any view type
header . height = { 60 } // height can be calculated
header . onSetupView = { view , section in // each time the view is about to be displayed onSetupView is invoked.
view . backgroundColor = . orange
}
section . header = headersection . reload ( ) SelectorViewControllerおよびMultipleSelectorViewController選択可能なセルをカスタマイズできるように、 selectableRowSetup 、 selectableRowCellUpdate 、およびselectableRowCellSetupプロパティが提供されます。
let row = PushRow < Emoji > ( ) {
$0 . title = " PushRow "
$0 . options = [ ?? , ? , ?? , ? , ? , ? ]
$0 . value = ??
$0 . selectorTitle = " Choose an Emoji! "
} . onPresent { from , to in
to . dismissOnSelection = false
to . dismissOnChange = false
to . selectableRowSetup = { row in
row . cellProvider = CellProvider < ListCheckCell < Emoji > > ( nibName : " EmojiCell " , bundle : Bundle . main )
}
to . selectableRowCellUpdate = { cell , row in
cell . textLabel ? . text = " Text " + row . selectableValue! // customization
cell . detailTextLabel ? . text = " Detail " + row . selectableValue!
}
} FormとSection種類が、 MutableCollectionとRangeReplaceableCollectionに適合したと述べたように。フォームはセクションのコレクションであり、セクションは行のコレクションです。
RangeReplaceableCollectionプロトコル拡張は、コレクションを変更するための多くの有用な方法を提供します。
extension RangeReplaceableCollection {
public mutating func append ( _ newElement : Self . Element )
public mutating func append < S > ( contentsOf newElements : S ) where S : Sequence , Self . Element == S . Element
public mutating func insert ( _ newElement : Self . Element , at i : Self . Index )
public mutating func insert < S > ( contentsOf newElements : S , at i : Self . Index ) where S : Collection , Self . Element == S . Element
public mutating func remove ( at i : Self . Index ) -> Self . Element
public mutating func removeSubrange ( _ bounds : Range < Self . Index > )
public mutating func removeFirst ( _ n : Int )
public mutating func removeFirst ( ) -> Self . Element
public mutating func removeAll ( keepingCapacity keepCapacity : Bool )
public mutating func reserveCapacity ( _ n : Self . IndexDistance )
}これらの方法は、Bellow:に示すようにカスタム演算子を実装するために内部的に使用されます。
public func +++ ( left : Form , right : Section ) -> Form {
left . append ( right )
return left
}
public func += < C : Collection > ( inout lhs : Form , rhs : C ) where C . Element == Section {
lhs . append ( contentsOf : rhs )
}
public func << < ( left : Section , right : BaseRow ) -> Section {
left . append ( right )
return left
}
public func += < C : Collection > ( inout lhs : Section , rhs : C ) where C . Element == BaseRow {
lhs . append ( contentsOf : rhs )
}ここで、残りのカスタムオペレーターがどのように実装されているかを見ることができます。
Eurekaカスタムオペレーターを使用したいかどうかを判断するのはあなた次第です。
フォームは常にUITableViewに表示されます。ビューコントローラーをストーリーボードにセットアップし、希望するuitableViewを追加して、アウトレットをFormviewControllerのtableView変数に接続できます。これにより、フォームのカスタムフレーム(おそらく制約付き)を定義できます。
これらはすべて、FormViewControllerのtableViewのプログラム的に変更されたフレーム、マージンなどによって実行できます。
ですから、ユーレカをさらに良くすることができます! 
これは、changelog.mdファイルにあります。