Create and Filter patterns
The FormKit API includes a set of UITableViewCells that should be used in the Fiori Design Language to construct table views for creating or editing business objects, or to build filter controls. Each cell implements the FUIFormCell protocol and invokes an optional onChangeHandler closure to handle value changes.
FormKit cells are used in Filter and Create Floorplans.
Image
Interface
All cells in FormKit implement the FUIFormCell protocol. FUIFormCell is generic for its value property, and has an associatedtype: ValueType, that allows the value to be accessed with type safety.
FUITitleFormCell - displays the title of the form. The cell can be marked as editable to allow user editing of the title (for example, the Work Request
cell in the above image):
let cell = tableView.dequeueReusableCell(withIdentifier: FUITitleFormCell.reuseIdentifier, for: indexPath) as! FUITitleFormCell
cell.value = "Work Request"
cell.isEditable = false
return cell
FUINoteFormCell - the user can enter notes in the cell (for example, the cell between Work Request
and Location
in the above image):
let cell = tableView.dequeueReusableCell(withIdentifier: FUINoteFormCell.reuseIdentifier, for: indexPath) as! FUINoteFormCell
cell.delegate = self
cell.placeholder = "Please type something"
cell.responderDelegate = self
cell.cellHeight = 80
return cell
FUIKeyValueFormCell - the user can enter text in the cell:
let cell = tableView.dequeueReusableCell(withIdentifier: FUIKeyValueFormCell.reuseIdentifier, for: indexPath) as! FUIKeyValueFormCell
cell.keyName = "Note"
cell.placeholderText = "Description"
cell.value = myObject.descriptionText1
cell.isAutoFitting = true
cell.isTrackingLiveChanges = true
cell.isEditable = false
return cell
FUISimplePropertyFormCell - provides a key/value pair that displays the key and value of the cell. The value of the cell cannot be modified (for example, the Request ID
cell in the above image):
// An un-editable property cell
let cell = tableView.dequeueReusableCell(withIdentifier: FUISimplePropertyFormCell.reuseIdentifier, for: indexPath) as! FUISimplePropertyFormCell
cell.key = "Request ID"
cell.value = "#201611-001234"
cell.delegate = self
return cell
FUIListPickerFormCell - provides a key/value pair that displays the key and value of the cell. For single selection, set its allowsMultipleSelection property to false:
// A property cell with list picker
let cell = tableView.dequeueReusableCell(withIdentifier: FUIListPickerFormCell.reuseIdentifier, for: indexPath) as! FUIListPickerFormCell
cell.keyName = "Work Group"
cell.value = [0]
cell.delegate = self
cell.valueOptions = ["Construction", "Repair", "Engineering", "Vendor"]
cell.allowsMultipleSelection = false
cell.valueTextField.text = descriptionForSelectedStrings(cell.valueOptions, at: propValue3)
return cell
When this cell is selected, a table view displays the available options for the user to choose:
FUIFilterFormCell - allow users to select one or mutiple values from a value set:
let cell = tableView.dequeueReusableCell(withIdentifier: FUIFilterFormCell.reuseIdentifier, for: indexPath) as! FUIFilterFormCell
cell.valueOptions = buttonTitles.flatMap { $0.map { $0.value }}
cell.keyName = "Sort By"
cell.value = [1]
cell.allowsMultipleSelection = true
cell.allowsEmptySelection = false
return cell
Image
A FUIListPickerFormCell can also be set as multiple selectable in the app by setting its allowsMultipleSelection property to true, as follows in the UITableViewController:
let valueOptions12 = [One
, Two
, Three
, Four
, Five
, Six
, Seven
]
var propValue12 = [1, 3, 6]
//…
// A property cell with list picker
let cell = tableView.dequeueReusableCell(withIdentifier: FUIListPickerFormCell.reuseIdentifier, for: indexPath) as! FUIListPickerFormCell
cell.keyName = "Choose Multiple"
cell.value = propValue12
cell.valueOptions = valueOptions12
// Developer is responsible for setting the text for the valueTextField of the FUIListPickerFormCell.
// Here, function descriptionForSelectedStrings just returns the
// comma separated selected string.
cell.valueTextField.text = descriptionForSelectedStrings(valueOptions12, at: propValue12)
cell.allowsMultipleSelection = true
cell.listPicker.prompt = "Please select multiple items"
cell.delegate = self
return cell
Image
When the cell is tapped, a multiple select table with specified optional values is displayed: Image
A developer could customize the cells displayed in the selection table by setting the dataSource property of the listPicker property of the FUIListPickerFormCell, as described below:
let propKey11 = List Picker with Object Cells
var propValue11: [Int] = []
// ObjectCellListPickerDataSource implements ListPickerDataSource and ListPickerSearchResultsUpdating let listPickerDataSource11 = ObjectCellListPickerDataSource(40)
// …
// A FUIListPickerFormCell with FUIObjectTableViewCell let cell = tableView.dequeueReusableCell(withIdentifier: FUIListPickerFormCell.reuseIdentifier, for: indexPath) as! FUIListPickerFormCell
cell.keyName = propKey11
cell.value = propValue11
cell.valueTextField.text = listPickerDataSource11.descriptionForSelectedItems(at: propValue11)
cell.listPicker.dataSource = listPickerDataSource11
cell.listPicker.searchResultsUpdating = listPickerDataSource11
cell.listPicker.prompt = "Please select multiple items"
cell.listPicker.register(FUIObjectTableViewCell.self, forCellReuseIdentifier: FUIObjectTableViewCell.reuseIdentifier)
cell.allowsMultipleSelection = true
cell.allowsEmptySelection = true
cell.delegate = self
cell.delegate = self
return cell
Image
When the cell is tapped, a multiple select table with FUIObjectTableViewCell is displayed: Image
A search bar could be added to the FUIListPickerFormCell in the selection table view by setting isSearchEnabled, dataSource and listPickerResultsUpdating. Optionally, a barcode scanner could be added to the search bar by setting the isBarcodeScannerEnabled property of the searchBar property, as follows:
let propKey7 = Choose Multiple
var propValue7: [Int] = []
let listPickerDataSource7 = StringListPickerDataSource(options: [One
, Two
, Three
, Four
, Five
, Six
, Seven
, Eight
, Nine
, Ten
, Eleven
, Twelve
, Thirteen
, Fourteen
, Fifteen
, Sixteen
, Seventeen
, Eighteen
, Nineteen
])
// …
let cell = tableView.dequeueReusableCell(withIdentifier: FUIListPickerFormCell.reuseIdentifier, for: indexPath) as! FUIListPickerFormCell
cell.keyName = propKey7
cell.value = propValue7
cell.allowsMultipleSelection = true
cell.allowsEmptySelection = false
cell.valueTextField.text = descriptionForSelectedStrings(cell.valueOptions, at: propValue7)
cell.listPicker.dataSource = listPickerDataSource7
cell.listPicker.searchResultsUpdating = listPickerDataSource7
cell.listPicker.prompt = "Please select multiple items"
cell.listPicker.isSearchEnabled = true
cell.delegate = self
cell.listPicker.searchBar?.isBarcodeScannerEnabled = true
cell.listPicker.searchBar?.barcodeScanner?.scanMode = .EAN_UPC
cell.listPicker.searchBar?.barcodeScanner?.scanResultTransformer = { (scanString) -> String in
return self.transformStringToSearchBar(scanResultString: scanString)
}
return cell
Image
When the cell is tapped, the multiple selection table is shown with a search bar under the navigation bar.
Image
When the user starts typing in the search bar, the displayed list is filtered.
Image
When the barcode scanner icon is tapped, the barcode scan view is displayed. Note that the barcode scanner icon is not displayed when the device does not support a camera, for example, when it’s running on a simulator. Also, the icon is not displayed when the search bar is active.
Image
FUIDatePickerFormCell - provides a key/value pair that displays a key and a date as the property value. When this cell is selected, a UIDatePicker displays to allow the user to select a date. The app can provide a DateFormatter to customize how the date displays (for example, the Appointment Date
cell in the above image):
Image
let cell = tableView.dequeueReusableCell(withIdentifier: FUIDatePickerFormCell.reuseIdentifier, for: indexPath) as! FUIDatePickerFormCell
cell.key = "Appointment Date"
cell.date = Date()
// if the date property is not provided, the default value is now.
cell.delegate = self
return cell
FUIDurationPickerFormCell - provides a key/value pair that displays a key and a TimeInterval as the property value. When this cell is selected, a UIDatePicker displays to allow the user to select a duration. The app can provide a text formatter to customize how the duration displays (for example, the formatter by default is %d Hrs %d Min
):
let cell = tableView.dequeueReusableCell(withIdentifier: FUIDurationPickerFormCell.reuseIdentifier, for: indexPath) as! FUIDurationPickerFormCell
cell.keyName = "Duration"
cell.value = 3600 //In seconds
cell.delegate = self
return cell
FUIValuePickerFormCell - provides a key/value pair that displays a key and a String as the property value. When this cell is selected, a UIPickerView displays to allow the user to select a value:
Image
let cell = tableView.dequeueReusableCell(withIdentifier: FUIValuePickerFormCell.reuseIdentifier, for: indexPath) as! FUIValuePickerFormCell
cell.keyName = "Maximum Price"
cell.valueOptions = ["5", "10", "15", "20", "25"]
cell.value = 0
// MARK: implement an onChangeHandler
cell.onChangeHandler = { [unowned self] newValue in
self.myObject.price = self.priceTitles[newValue].first!.key
}
return cell
FUISwitchFormCell - the property for this cell is a boolean value that uses a standard UISwitch to display the value. The user can change the value by tapping the switch (for example, the Confirmed
cell in the above image):
// A FUISwitchFormCell
let cell = tableView.dequeueReusableCell(withIdentifier: FUISwitchFormCell.reuseIdentifier, for: indexPath) as! FUISwitchFormCell
cell.key = "Confirmed"
cell.value = true
cell.delegate = self
return cell
FUISliderFormCell - the property for this cell is a float value. Users select a value from a continuous range using the slider. Also set a unit if needed (default unit is mi
):
Image
let cell = tableView.dequeueReusableCell(withIdentifier: FUISliderFormCell.reuseIdentifier, for: indexPath) as! FUISliderFormCell
cell.keyName = "Distance"
cell.minimumValue = 0
cell.maximumValue = 30
cell.value = myObject.distance
// MARK: implement an onChangeHandler
cell.onChangeHandler = { newValue in
self.myObject.distance = newValue
}
return cell
AttachmentFormCell - a cell to which photos or selected files from the photo library can be added as attachments:
let cell = tableView.dequeueReusableCell(withIdentifier: AttachmentFormCell.reuseIdentifier, for: indexPath) as! AttachmentFormCell
cell.attachmentDelegate = attachmentDelegate
return cell
The application needs to add the following to its info.plist in order to access the camera and photo library:
<key>NSCameraUsageDescription</key>
<string>Please permit access to camera</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Please permit access to photo library</string>
Each UITableViewController is allowed to have only one AttachmentFormCell. FUISegmentedControlFormCell - A type of FUIPropertyFormCell, representing a key/value pair of the cell. The user can select a value by clicking the button. The cell is editable by default and can be set to isEditable to disable user interaction.
Usage
Implement a UITableViewController that hosts the cells and constructs a Create Window view similar to the one in the example above:
The UITableViewController must subclass FUIFormTableViewController.
class MyFormTableViewController: FormTableViewController {
...
}
Register the reuse identifiers of all needed FUIFormCells, and enable auto-dimension row height calculation.
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.register(FUITitleFormCell.self, forCellReuseIdentifier: FUITitleFormCell.reuseIdentifier)
...
self.tableView.estimatedRowHeight = 200
self.tableView.rowHeight = UITableViewAutomaticDimension
}
Reuse the registered cells in tableView(_:cellForRowAt:), and bind the form data to the cell views:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// An simple key-value property cell
let cell = tableView.dequeueReusableCell(withIdentifier: FUISimplePropertyFormCell.reuseIdentifier, for: indexPath) as! FUISimplePropertyFormCell
cell.key = "Location"
cell.value = "127 Higgins Drive, Palo Alto"
// MARK: Implement `onChangeHandler` closure to process the new value entered by the user
cell.onChangeHandler = { newValue in
myObject.value = newValue
}
return cell
}
For AttachmentFormCell, set the cell delegate property to DefaultAttachmentFormCellDelegate, or implement the didAddAttachment(attachment:) and didDeleteAttachment(attachmentNumber:) functions of AttachmentFormCellDelegate protocol, to receive notifications when attachments are added or deleted by the user:
public class DefaultAttachmentFormCellDelegate: AttachmentFormCellDelegate {
/**
The list of attachments.
*/
public var attachmentList: [AttachmentData] = [AttachmentData]()
public init() {}
}
public func didAddAttachment(attachment: AttachmentData) {
attachmentList.append(attachment)
}
public func didDeleteAttachment(attachmentNumber: Int) {
var index = -1
for i in 0..<attachmentList.count {
if attachmentList[i].attachmentNumber == attachmentNumber {
index = i
break
}
}
if index != -1 {
attachmentList.remove(at: index)
}
}
-
This protocol is to be implemented by all the form cells except
FUIAttachmentsFormCell
, including:- FUIDatePickerFormCell
- FUIDurationPickerFormCell
- FUIFilterFormCell
- FUIKeyValueFormCell
- FUIListPickerFormCell
- FUINoteFormCell
- FUISegmentedControlFormCell
- FUISimplePropertyFormCell
- FUISliderFormCell
- FUIValuePickerFormCell
- FUISwitchFormCell
FUITitleFormCell
Note
All
FUIFormCell
implemtations listed above have theselectionStyle
properties set to.none
. Therefore, developers whill not be able to set highlighted on these cells.Declaration
Swift
public protocol FUIFormCell : AnyObject, FUIInlineValidation
-
When
FUIFormCell
s are to be used in an application, application’s implementation ofUITableViewController
that hosts theseFUIFormCell
s must be a subclass of thisFUIFormTableViewController
.FUIFormTableViewController
hides all the complications and interactions for handling all different types ofFUIFormCell
s.Application’s implementation of the
UITableViewController
needs to only implement the following functions:class FormCellTestTVC: FUIFormTableViewController { override func viewDidLoad() { // MUST: Call viewDidLoad function of super class. super.viewDidLoad() // Register FUIFormCells that will be used self.tableView.register(FUITitleFormCell.self, forCellReuseIdentifier: FUITitleFormCell.reuseIdentifier) ... } override func numberOfSections(in tableView: UITableView) -> Int { // Return how many section in the table return ... } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // Return number of rows in each section ... } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // Return the cell to be used at the IndexPath specified let cell = tableView.dequeueReusableCell(withIdentifier: FUITitleFormCell.reuseIdentifier, for: indexPath) as! FUITitleFormCell cell.value = "Work Request" cell.isEditable = true // MARK: implement onChangeHandler cell.onChangeHandler = { newValue in myObject.title = newValue } return cell }
In addition, if there are some other actions on the table view, it is required that the action functions should also call function
endEditing
of the table view with theforce
parameter totrue
so that all editing cells have its onChangeHandler called. For example, the function didSaveTapped below is the action when theSave
button tapped:
See more@IBAction func didSaveTapped(_ sender: AnyObject) { self.tableView.endEditing(true) // save object ... }
Declaration
Swift
open class FUIFormTableViewController : UITableViewController, FUIFormCellResponderDelegate, FUIFormCellNavigationDelegate
-
The reusable UI component implemented as an
UITableViewCell
to allow user to enter a value, using aUITextField
.The developer should set the following properties on the cell, in their implementation of
UITableViewDataSource
cellForRow(at:)
function:value
: The value of the property, asString
And an
onChangeHandler
:onChangeHandler
: a handler closure, which is invoked on changes to the value
Optionally, the developer may provide:
isEditable
: Indicates if the cell’s value may be modified. Defaults totrue
.
Color settings:
Setting tintColor for
valueTextField
for a state using setTintColor(_:for:) api. Currentlydisabled
andnormal
are supported.cell.setTintColor(UIColor.red, for: .normal)
Remark
Thefont-color
attribute will be overridden bytint-color-disabled
attribute when cell is switched todisabled
state. DO NOT settextColor
forvalueTextField
when cell is indisabled
state!The following is an example of usage in an application
UITableViewController
:override func viewDidLoad() { super.viewDidLoad() self.tableView.register(FUITitleFormCell.self, forCellReuseIdentifier: FUITitleFormCell.reuseIdentifier) // ... } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: FUITitleFormCell.reuseIdentifier, for: indexPath) as! FUITitleFormCell cell.value = myObject.title cell.isEditable = true // MARK: implement onChangeHandler cell.onChangeHandler = { newValue in myObject.title = newValue } return cell }
## Theming Supported style classes
See morefdlFUITitleFormCell fdlFUITitleFormCell_valueTextField
Declaration
Swift
open class FUITitleFormCell : FUIInlineValidationTableViewCell, FUIFormCell, UITextFieldDelegate
-
The reusable UI component implemented as an
UITableViewCell
to display or edit a key-value pair property.The developer should set the following properties on the cell, in their implementation of
UITableViewDataSource
cellForRow(at:)
function:keyName
: The key name of the property.value
: The value of the property.
And an
onChangeHandler
:onChangeHandler
: a handler closure, which is invoked on changes to the value
Optionally, the developer may provide
isEditable
: Indicates if the cell’s value may be modified. Defaults totrue
.
When the cell is editable, the key and value are arranged vertically in a stack, otherwise they are arranged horizontally.
Color settings:
Setting tintColor for add button for a state using setTintColor(_:for:) api. Currently
disabled
andnormal
are supported.cell.setTintColor(UIColor.red, for: .normal)
Remark
Thefont-color
attribute will be overridden bytint-color-disabled
attribute when cell is switched todisabled
state. DO NOT settextColor
forvalueTextView
when cell is indisabled
state! Use thesetTintColor(UIColor(), for: .disabled)
to set the color.The following is an example of usage in an application
UITableViewController
:override func viewDidLoad() { super.viewDidLoad() self.tableView.register(FUITextFieldFormCell.self, forCellReuseIdentifier: FUITextFieldFormCell.reuseIdentifier) } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: FUITextFieldFormCell.reuseIdentifier, for: indexPath) as! FUITextFieldFormCell cell.keyName = "Editable" cell.value = myObject.productName // MARK: implement onChangeHandler cell.onChangeHandler = { newValue in myObject.productName = newValue } return cell }
## Theming
nuiClass
:fdlFUITextFieldFormCell {}
Supported
TEXT
class paths:fdlFUITextFieldFormCell_keyLabel {} fdlFUITextFieldFormCell_valueTextField {}
Supported
TEXT
properties:
See morefont-color: Color; placeholder-color: Color; font-style: UIFontTextStyle;
Declaration
Swift
@IBDesignable open class FUITextFieldFormCell : FUIInlineValidationTableViewCell, FUIPropertyFormCell
-
The reusable UI component implemented as an
UITableViewCell
to allow user enter notes.Optionally, the developer may provide:
value
: The default text in the note.placeholderText
: The placeholder string to be put on the text area before user typed anything.isAutoFitting
: If this is true, the scroll will be disabled and the height of the cell will grow and shrink as needed. There is a minimum height that the cell will maintain.isEditable
: Indicates if the note text could be modified or not. The default is true.onChangeHandler
: a handler closure, which is invoked on changes to the value
Color setting:
Setting text color of
valueTextView
for a state using setTintColor(_:for:) api. Currently.disabled
and.normal
are supported.cell.setTintColor(UIColor.red, for: .normal)
Remark
Thefont-color
attribute will be overridden bytint-color-disabled
attribute when cell is switched todisabled
state. DO NOT settextColor
forvalueTextView
when cell is indisabled
state!The following is an example of usage in an application
UITableViewController
:override func viewDidLoad() { super.viewDidLoad() self.tableView.register(FUINoteFormCell.self, forCellReuseIdentifier: FUINoteFormCell.reuseIdentifier) // ... } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: FUINoteFormCell.reuseIdentifier, for: indexPath) as! FUINoteFormCell // If a value already exists, set it to the `value` property cell.value = myObject.note // Specify an optional placeholder text cell.placeholderText = "Description" // MARK: implement onChangeHandler cell.onChangeHandler = { newValue in myObject.note = newValue } return cell }
## Theming Supported style classes
See morefdlFUINoteFormCell fdlFUINoteFormCell_valueTextView
Declaration
Swift
@IBDesignable open class FUINoteFormCell : FUIInlineValidationTableViewCell, FUIFormCell, UITextViewDelegate
-
A customized
UITableViewCell
, which contains aUILabel
and aUITextView
. It takes text as input.The developer should set the following properties on the cell, in their implementation of
UITableViewDataSource
cellForRow(at:)
function:keyName
: The key name of the property.placeholderText
: The placeholder of the property.value
: The value of the property, asString
.
And an
onChangeHandler
:onChangeHandler
: a handler closure, which is invoked on changes to the value.
Optionally, the developer may set
isAutoFitting
: Indicate if the cell height will adjust based on its content text. Default value is false.isTrackingLiveChanges
: Indicate howonChangeHandler
is invoked. If true,onChangeHandler
will be invoked every time a letter is entered or deleted; if false,onChangeHandler
will only be invoked when cell resigns first reponder.- ‘isEditable’: If the cell is editable or not. Default value is true. Date detector works only if this property is set to false.
Color setting:
Setting text color of filter buttons for a state using setTintColor(_:for:) api. Currently
.disabled
and.normal
are supported.cell.setTintColor(UIColor.red, for: .normal)
The following is an example of usage in an application
UITableViewController
:override func viewDidLoad() { super.viewDidLoad() self.tableView.register(FUIKeyValueFormCell, forCellReuseIdentifier: FUIKeyValueFormCell.reuseIdentifier) // ... } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: FUIKeyValueFormCell.reuseIdentifier, for: indexPath) as! FUIKeyValueFormCell cell.keyName = "Note" cell.placeholderText = "Description" cell.value = myObject.descriptionText1 cell.isAutoFitting = true cell.isTrackingLiveChanges = true cell.isEditable = false cell.onChangeHandler = { newValue in self.myObject.descriptionText1 = newValue } return cell }
Theming
Supported style classes
See morefdlFUIKeyValueFormCell fdlFUIKeyValueFormCell_keyLabel fdlFUIKeyValueFormCell_valueTextView
Declaration
Swift
@IBDesignable open class FUIKeyValueFormCell : FUINoteFormCell, FUIPropertyFormCell
-
The reusable UI component implemented as an
UITableViewCell
to allow user to choose a boolean value using a switch for a property.The developer should set the following properties on the cell, in their implementation of
UITableViewDataSource
cellForRow(at:)
function:keyName
: The key name of the propertyvalue
: The value of the property, asBool
isEditable
: Indicates if the cell’s value may be modified. Defaults totrue
.
And, an
onChangeHandler
:onChangeHandler
: a handler closure, which is invoked on changes to the value
Color settings:
Setting tintColor for add button for a state using setTintColor(_:for:) api. Currently
disabled
,normal
,selected
are supported.selected
means switch is turned on.cell.setTintColor(UIColor.red, for: .normal)
The following is an example of usage in an application
UITableViewController
:override func viewDidLoad() { super.viewDidLoad() self.tableView.register(FUISwitchFormCell.self, forCellReuseIdentifier: FUISwitchFormCell.reuseIdentifier) // ... } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // ... let cell = tableView.dequeueReusableCell(withIdentifier: FUISwitchFormCell.reuseIdentifier, for: indexPath) as! FUISwitchFormCell cell.keyName = "Confirmed" cell.value = myObject.isConfirmed // MARK: implement onChangeHandler cell.onChangeHandler = { newValue in myObject.isConfirmed = newValue } return cell }
## Theming Supported style classes
See morefdlFUISwitchFormCell fdlFUISwitchFormCell_keyLabel fdlFUISwitchFormCell_switchView
Declaration
Swift
@IBDesignable open class FUISwitchFormCell : FUIInlineValidationTableViewCell, FUIPropertyFormCell
-
A customized
UITableViewCell
, which contains aUILabel
, aUITextField
and aUISlider
. It allows users to select a single value from a continuous range of values.The developer should set the following properties on the cell, in their implementation of
UITableViewDataSource
cellForRow(at:)
function:keyName
: The key name of the propertyvalue
: The value of the property, asFloat
minimumValue
: The minimum value of the selection range.maximumValue
: The maximum value of the selection range.
And an
onChangeHandler
:onChangeHandler
: a handler closure, which is invoked on changes to the value.
Optionally, the developer may set:
unit
: The unit of value. Default ismi
.isEditable
: Indicates if the cell’s value may be modified. Defaults totrue
.
Color setting:
Setting text color of filter buttons for a state using setTintColor(_:for:) api. Currently
.disabled
and.normal
are supported.cell.setTintColor(UIColor.red, for: .normal)
The following is an example of usage in an application
UITableViewController
:override func viewDidLoad() { super.viewDidLoad() self.tableView.register(FUISliderFormCell, forCellReuseIdentifier: FUISliderFormCell.reuseIdentifier) // ... } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: FUISliderFormCell.reuseIdentifier, for: indexPath) as! FUISliderFormCell cell.keyName = "Distance" cell.minimumValue = 0 cell.maximumValue = 30 cell.value = myObject.distance // MARK: implement an onChangeHandler cell.onChangeHandler = { [weak self] newValue in self.myObject.distance = newValue } return cell }
Theming
Supported style classes
See morefdlFUISliderFormCell fdlFUISliderFormCell_keyLabel fdlFUISliderFormCell_valueTextField
Declaration
Swift
@IBDesignable open class FUISliderFormCell : FUIInlineValidationTableViewCell, FUIPropertyFormCell
-
A
UITableViewCell
subclass, which allows a user to view or select from a list of strings, using a Fiori-styled segmented control.The
value
property of the cell is equal to theselectedSegmentIndex
in the segmented control.Specifying the height for segments by setting
segmentHeight
api. By default it is set to nil which means segment will adjust its height to fit content.Color setting:
Setting text color of buttons in the cell for a state using setTintColor(_:for:) api. Currently
disabled
,normal
andselected
are supported.cell.setTintColor(UIColor.red, for: .selected)
Code usage:
// Optionally, create an array of value option to localized string mappings let buttonTitles: [[String: String]] = [["LO": "Low"], ["MED": "Medium"], ["HI": "High"]] // Register FUISegmentedControlFormCell in viewDidLoad() method in the controller. override func viewDidLoad() { super.viewDidLoad() self.tableView.register(FUISegmentedControlFormCell.self, forCellReuseIdentifier: FUISegmentedControlFormCell.reuseIdentifier) } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: FUISegmentedControlFormCell.reuseIdentifier, for: indexPath) as! FUISegmentedControlFormCell cell.valueOptions = buttonTitles.flatMap { $0.map { $0.value } } cell.keyName = "Priority" cell.value = myObject.priority // String value in the valid options set: ["LO", "MED", "HI"] // MARK: implement onChangeHandler cell.onChangeHandler = { newValue in myObject.priority = buttonTitles[newValue].first!.key // lookup valid String value, from the buttonTitles array } return cell }
Theming
Supported style classes
See morefdlFUISegmentedControlFormCell fdlFUISegmentedControlFormCell_keyLabel
Declaration
Swift
@IBDesignable open class FUISegmentedControlFormCell : FUIInlineValidationTableViewCell, FUIPropertyFormCell
-
A
UITableViewCell
subclass, which allows a user to read or enter a set of values, using a grid of buttons. Commonly used for composing filters.The developer should set the following properties on the cell, in their implementation of
UITableViewDataSource
cellForRow(at:)
function:keyName
: The key name of the property.value
: An array of the selected indexes in the control. Uses the same index as thevalueOptions
array.- `valueOptions: A String array, of titles for the buttons in the control
And an
onChangeHandler
:onChangeHandler
: a handler closure, which is invoked on changes to the value
Optionally, the developer may provide
allowsMultipleSelection
: Indicates if multiple buttons may be selected simultaneously (true
). Iffalse
, the control behaves inradio
mode. Defaults totrue
.allowsEmptySelection
: Indicates if the control allows zero items to be selected (true
). If false, then once a value has been selected by the developer or user, taps by the user on the last selected item will be ignored, instead of de-selecting the item. Defaults totrue
.isEditable
: Indicates if the cell’s value may be modified. Defaults totrue
.
Color setting:
Setting text color of filter buttons for a state using setTintColor(_:for:) api. Currently
disabled
,normal
andselected
are supported.cell.setTintColor(UIColor.red, for: .normal)
The following is an example of usage in an application
UITableViewController
:// optionally, create an array of value option to localized string mappings let buttonTitles: [[String: String]] = [["radius": "Distance"], ["price": "Price"], ["rating": "Ratings"], ["avail": "Availability"]] // Register FUIFilterFormCell in viewDidLoad() method in the controller. override func viewDidLoad() { super.viewDidLoad() self.tableView.register(FUIFilterFormCell.self, forCellReuseIdentifier: FUIFilterFormCell.reuseIdentifier) } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: FUIFilterFormCell.reuseIdentifier, for: indexPath) as! FUIFilterFormCell cell.valueOptions = buttonTitles.flatMap { $0.map { $0.value }} cell.keyName = "Sort By" cell.value = [1] cell.allowsMultipleSelection = true cell.allowsEmptySelection = false // MARK: implement onChangeHandler cell.onChangeHandler = { [weak self] newValue in self.applyFilter(forDimensions: newValue) // here, the cell input is set to a filter function } return cell }
## Theming Supported style classes
See morefdlFUIFilterFormCell fdlFUIFilterFormCell_keyLabel fdlFUIFilterFormCell_item_contentView fdlFUIFilterFormCell_item_titleLabel fdlFUIFilterFormCell_item_contentView_selected fdlFUIFilterFormCell_item_titleLabel_selected
Declaration
Swift
open class FUIFilterFormCell : FUIInlineValidationTableViewCell, FUIPickerFormCell, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
-
A
UITableViewCell
subclass, which allows a user to read or enter a value, using a date picker.The developer should set the following properties on the cell, in their implementation of
UITableViewDataSource
cellForRow(at:)
function:keyName
: The key name of the property.value
: The value of the property, asDate
And an
onChangeHandler
:onChangeHandler
: a handler closure, which is invoked on changes to the value
Optionally, UITableViewController could provide
dateFormatter
: A developer-definedUIDateFormatter
, for transposing betweenDate
type andString
.datePickerMode
: TheUIDatePickerMode
for the date picker. Default is.dateAndTime
. Note that.countDownTimer
mode is not supported. Use theFUIDurationPickerFormCell
for duration values.isEditable
: Indicates if the cell’s value may be modified. Defaults totrue
.
Color setting:
Setting text color of filter buttons for a state using setTintColor(_:for:) api. Currently
.disabled
,.normal
andselected
are supported.cell.setTintColor(UIColor.red, for: .normal)
The following is an example of usage in an application
UITableViewController
:let dateFormatter = DateFormatter() override func viewDidLoad() { super.viewDidLoad() dateFormatter.dateFormat = "dd-MM-yyyy" self.tableView.register(FUIDatePickerFormCell.self, forCellReuseIdentifier: FUIDatePickerFormCell.reuseIdentifier) // ... } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: FUIDatePickerFormCell.reuseIdentifier, for: indexPath) as! FUIDatePickerFormCell cell.keyName = "End Date" cell.dateFormatter = dateFormatter cell.datePickerMode = .date cell.value = cell.dateFormatter.date(from: myObject.endDate) // "02-17-2017" // MARK: implement onChangeHandler cell.onChangeHandler = { newValue in myObject.endDate = cell.dateFormatter.string(from: newValue) } return cell }
## Theming Supported style classes
See morefdlFUIDatePickerFormCell fdlFUIDatePickerFormCell_keyLabel fdlFUIDatePickerFormCell_valueTextField fdlFUIDatePickerFormCell_selectedBackgroundView fdlFUIDatePickerFormCell_valueTextField_selected
Declaration
Swift
@IBDesignable public class FUIDatePickerFormCell : FUIInlineValidationTableViewCell, FUIPropertyFormCell
-
A
UITableViewCell
subclass, which allows a user to read or enter a value, using a duration picker.The developer should set the following properties on the cell, in their implementation of
UITableViewDataSource
cellForRow(at:)
function:keyName
: The key name of the propertyvalue
: The value of the property, asTimeInterval
And an
onChangeHandler
:onChangeHandler
: a handler closure, which is invoked on changes to the value
Optionally, the developer may provide
minInterval
: The minute interval to be used in the picker.isEditable
: Indicates if the cell’s value may be modified. Defaults totrue
.
Color configuration:
Call setTintColor(_:for:) to configure tint color for disabled, normal, selected
UIControlState
. SettingtintColor
is equivalent to call setTintColor(color, for: UIControlState.normal).- disabled: Color to be used when control is disabled.
- normal: Color to be used when control is enabled.
- selected: Color to be used when control is selected.
The following is an example of usage in an application
UITableViewController
:override func viewDidLoad() { super.viewDidLoad() self.tableView.register(FUIDurationPickerFormCell, forCellReuseIdentifier: FUIDurationPickerFormCell.reuseIdentifier) // ... } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: FUIDurationPickerFormCell.reuseIdentifier, for: indexPath) as! FUIDurationPickerFormCell cell.keyName = "Duration" cell.value = myObject.eventDuration // in seconds // MARK: implement an onChangeHandler cell.onChangeHandler = { newValue in myObject.eventDuration = newValue } return cell }
## Theming Supported style classes
See morefdlFUIDurationPickerFormCell fdlFUIDurationPickerFormCell_keyLabel fdlFUIDurationPickerFormCell_valueTextField fdlFUIDurationPickerFormCell_valueTextField_selected
Declaration
Swift
@IBDesignable public class FUIDurationPickerFormCell : FUIInlineValidationTableViewCell, FUIPropertyFormCell
-
A customized
UITableViewCell
, which contains aUILabel
, aUITextField
and aUIPickerView
. It allows users to select a single value from a set of options using a spinning wheel.The developer should set the following properties on the cell, in their implementation of
UITableViewDataSource
cellForRow(at:)
function:keyName
: The key name of the propertyvalueOptions
: A set of options that users can chose from.value
: The value of the property, asInt
And an
onChangeHandler
:onChangeHandler
: a handler closure, which is invoked on changes to the value.
Optionally, the developer may set
isEditable
: Indicates if the cell’s value may be modified. Defaults totrue
.
Color setting:
Setting text color of filter buttons for a state using setTintColor(_:for:) api. Currently
.disabled
,.normal
andselected
are supported.cell.setTintColor(UIColor.red, for: .normal)
The following is an example of usage in an application
UITableViewController
:override func viewDidLoad() { super.viewDidLoad() self.tableView.register(FUIValuePickerFormCell, forCellReuseIdentifier: FUIValuePickerFormCell.reuseIdentifier) // ... } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: FUIValuePickerFormCell.reuseIdentifier, for: indexPath) as! FUIValuePickerFormCell cell.keyName = "Maximum Price" cell.valueOptions = ["5", "10", "15", "20", "25"] cell.value = 0 // MARK: implement an onChangeHandler cell.onChangeHandler = { [weak self] newValue in self.myObject.price = self.priceTitles[newValue].first!.key } return cell }
Theming
Supported style classes
See morefdlFUIValuePickerFormCell fdlFUIValuePickerFormCell_keyLabel fdlFUIValuePickerFormCell_valueTextField fdlFUIValuePickerFormCell_valueTextField_selected
Declaration
Swift
@IBDesignable open class FUIValuePickerFormCell : FUIInlineValidationTableViewCell, FUIPropertyFormCell, UIPickerViewDataSource, UIPickerViewDelegate
-
The reusable UI component implemented as an
UITableViewCell
to display a key-value pair property, which is integrated with aFUIListPicker
controller for displaying a list of values.### Single-line version
### Multi-line version
The developer should set the following properties on the cell, in their implementation of
UITableViewDataSource
cellForRow(at:)
function:keyName
: The key name of the property.value
: The default selections.valueOptions
: The list of optional values user may choose from.allowsMultipleSelection
: Indicates if user can select multiple values. Default is true, meaning by default user may select multiple values.isEditable
: If the selection(s) could be modified or not. The default is true.listPicker
: TheFUIListPicker
for thisFUIListPickerFormCell
.
Color settings:
Setting tintColor for add button for a state using setTintColor(_:for:) api. Currently
disabled
andnormal
are supported.cell.setTintColor(UIColor.red, for: .normal)
Note that the display of the selections in the
valueTextField
is the responsibility of the developer if thedataSource
property of thelistPicker
is set. Developer is to set the text of thevalueTextField
to reflect the selections. Otherwise, if developer setsvalueOptions
and leavesdataSource
oflistPicker
to nil, then the text invalueTextField
will be set internally.Here are the code snippets in app’s
UITableViewController
implementation: (The app’sUITableViewController
needs to be a subclass ofFUIFormTableViewController
.)var propValue7: [Int] = [1, 3, 6] var valueOptions7 = ["One", "Two", "Three", "Four", "Five", "Six", "Seven"] var listPickerDataSource7 = StringListPickerDataSource(options: valueOptions7) override func viewDidLoad() { super.viewDidLoad() self.tableView.register(FUIListPickerFormCell.self, forCellReuseIdentifier: FUIListPickerFormCell.reuseIdentifier) // ... } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // ... let cell = tableView.dequeueReusableCell(withIdentifier: FUIListPickerFormCell.reuseIdentifier, for: indexPath) as! FUIListPickerFormCell cell.keyName = "Choose Multiple" cell.value = propValue7 cell.allowsMultipleSelection = true cell.valueTextField.text = descriptionForSelectedStrings(valueOptions7, at: propValue7) // See below cell.listPicker.dataSource = listPickerDataSource7 cell.listPicker.searchResultsUpdating = listPickerDataSource7 cell.listPicker.isSearchEnabled = true cell.listPicker.prompt = "Please select multiple items" cell.listPicker.searchBar?.isBarcodeScannerEnabled = true cell.listPicker.searchBar?.barcodeScanner?.scanMode = .EAN_UPC cell.listPicker.searchBar?.barcodeScanner?.scanResultTransformer = { (scanString) -> String in return self.transformStringToSearchBar(scanResultString: scanString) } // MARK: implement onChangeHandler cell.onChangeHandler = { [weak self] newValue in self.propValue3 = newValue } return cell // ... } func descriptionForSelectedStrings(_ options: [String], at indexes: [Int]) -> String { return options.enumerated().filter({ (index, element) -> Bool in return indexes.contains(index) }).reduce ("") { string, element in return string.isEmpty ? element.1 : "\(string), \(element.1)" } }
## Theming Supported style classes
See morefdlFUIListPickerFormCell fdlFUIListPickerFormCell_keyLabel fdlFUIListPickerFormCell_valueTextField fdlFUIListPickerFormCell_selectedBackgroundView
Declaration
Swift
open class FUIListPickerFormCell : FUIInlineValidationTableViewCell, FUIPickerFormCell
-
An object that adopts the FUIListPickerDataSource protocol is responsible for providing the data and views required to display the list of options available in
FUIListPickerFormCell
orFUIListPickerTableViewController
.The data source could be sectioned by implementing the following function:
func numberOfSections(in listPicker: FUIListPicker) -> Int
Important
Only data source using unique identifier could be sectioned. i.e., the propertyisDataSourceRequiringUniqueIdentifiers
of theFUIListPicker
is true.Implementation Note:
The list picker will not show any item if any of the required functions is not implemented.
The following optional functions are required to be implemented for data source not using unique identifier:
func numberOfRows(in listPickerTableView: UITableView) -> Int func listPickerTableView(_ tableView: UITableView, cellForRowAt index: Int, isFiltered: Bool) -> UITableViewCell
The following optional functions are required to be implemented for data source using unique identifier but not sectioned:
func numberOfRows(in listPickerTableView: UITableView) -> Int func listPickerTableView(_ tableView: UITableView, cellForRowAt index: Int, isFiltered: Bool) -> UITableViewCell func listPickerTableView(_ tableView: UITableView, cellForItemWithUniqueIdentifier uniqueIdentifier: String) -> UITableViewCell func listPickerTableView(_ tableView: UITableView, uniqueIdentifierForItemAt index: Int) -> String func listPickerTableView(_ tableView: UITableView, indexForUniqueIdentifier uniqueIdentifier: String) -> Int
The following optional functions are required to be implemented for data source using unique identifier and sectioned:
See morefunc numberOfSections(in listPicker: FUIListPicker) -> Int func listPickerTableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int func listPickerTableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath, isFiltered: Bool) -> UITableViewCell func listPickerTableView(_ tableView: UITableView, uniqueIdentifierForItemAtIndexPath indexPath: IndexPath) -> String func listPickerTableView(_ tableView: UITableView, cellForItemWithUniqueIdentifier uniqueIdentifier: String) -> UITableViewCell func listPickerTableView(_ tableView: UITableView, indexPathForUniqueIdentifier uniqueIdentifier: String) -> IndexPath?
Declaration
Swift
@objc public protocol FUIListPickerDataSource : AnyObject
-
An implementation of
FUIListPickerSearchResultsUpdating
protocol is responsible to maintain a filtered list of options, based on the search string specified, for the correspondingFUIListPickerDataSource
implementation.Implementation Note:
Depending on the
FUIListPickerDataSource
, different optional functions in the correspondingFUIListPickerSearchResultsUpdating
are required to be implemented. The list picker will not show any item if any of the required functions is not implemented.The following optional functions are required to be implemented for data source not using unique identifier:
func listPicker(_ listPicker: FUIListPicker, filteredDataSourceContainsItemAt unfilteredIndex: Int) -> Bool func listPicker(_ listPicker: FUIListPicker, unfilteredDataSourceIndexOfItemAt filteredIndex: Int) -> Int
The following optional functions are required to be implemented for data source using unique identifier but not sectioned:
func listPicker(_ listPicker: FUIListPicker, filteredDataSourceContainsItemWithUniqueIdentifier uniqueIdentifier: String) -> Bool
The following optional functions are required to be implemented for data source using unique identifier and sectioned:
See morefunc listPicker(_ listPicker: FUIListPicker, filteredDataSourceContainsItemWithUniqueIdentifier uniqueIdentifier: String) -> Boo
Declaration
Swift
@objc public protocol FUIListPickerSearchResultsUpdating : AnyObject
-
The protocol defines the properties and functions for listing the options in an
See moreUITableView
for the correspondingListPickerFormCell
.Declaration
Swift
@objc public protocol FUIListPicker
-
This
FUIListPickerTableViewController
is to show a list of table view cells to let user select one of the cell. Developer needs to provide implementation ofFUIListPickerDataSource
, andFUIListPickerSearchResultsUpdating
if search is enabled, in order to useFUIListPickerTableViewController
.If the
isDismissedOnSelection
property is set to true, and theallowsMultipleSelection
property is set to false, then when user selected one cell by tapping the displayed cell, theonSelectionHandler
property will be invoked to notify the user selection. The table view will then be dismissed.There will be a
Done
button shown in the navigation bar if theisDismissedOnSelection
property is set to false or theallowsMultipleSelection
property is set to true. TheonSelectionHandler
property will be invoked after user tapped theDone
button if theallowsMultipleSelection
property is set to false, or theonMultipleSelectionHandler
property will be invoked if theallowsMultipleSelection
property is set to true. Then the table view will be dismissed.There will be a
Select All
button in theAll
section header, if multiple selections is allowed and not all items are selected. All items are selected when theSelect All
button is tapped. Once all items are selected, the button title will change toDeselect All
. All items are de-selected whenDeselect All
button is tapped.Also, a
Deselect All
button will be in theSelected
section header when multiple selections is allowed. TheSelected
section will appear if the items in the list could not be displayed in one screen, and there are one or more items selected. All selected items will be de-selected whenDeselect All
button is tapped.Here is a code snippet of a typical usage:
let bundle = Bundle(for: FUIListPickerTableViewController.self) let listPickerTableViewController = bundle.loadNibNamed("FUIListPickerTableViewController", owner: nil, options: nil)?.first as! FUIListPickerTableViewController var listPicker = listPickerTableViewController.listPicker listPicker.title = "Magic School" listPicker.register(FUIObjectTableViewCell.self, forCellReuseIdentifier: FUIObjectTableViewCell.reuseIdentifier) listPicker.dataSource = self.objectCellListPickerDataSource listPicker.prompt = "Select One" listPicker.estimatedRowHeight = 98 listPicker.isSearchEnabled = true listPicker.searchResultsUpdating = self.objectCellListPickerDataSource listPicker.isBarcodeScannerEnabled = true listPicker.barcodeScanMode = .all listPicker.barcodeScanResultTransformer = { (scanString) -> String in return "S" } listPickerTableViewController.onSelectionHandler = { self.select1Result.text = self.objectCellListPickerDataSource.descriptionForSelectedItems(at: [$0]) } listPickerTableViewController.showsCancelButton = true listPickerTableViewController.isDismissedOnSelection = false // Select item at index 4 as default, which is the 5th item. listPickerTableViewController.selectItem(4) let navController = UINavigationController(rootViewController: listPickerTableViewController) self.present(navController, animated: true, completion: nil)
Theming
Supported style classes
See morefdlFUIListPickerTableViewController fdlFUIListPickerTVC_cancelItem fdlFUIListPickerTVC_sectionHeaderTitleLabel fdlFUIListPickerTVC_listTextLabel
Declaration
Swift
open class FUIListPickerTableViewController : UITableViewController, UISearchResultsUpdating, UISearchBarDelegate, FUIBarcodeScanViewControllerDelegate
-
- The reusable UI component implemented as an UITableViewCell to manage selecting attachments.
FUIAttachmentsFormCell
uses aFUIAttachmentsViewController
to display the title of the cell and a collection of icons to represent the attachments. The attachment icon size may change, depends on the system font size settings. The controller arranges the attachment icons in such a manner that as many icons to be fitted in a row, and as many rows to display all the attachment icons. It will also try to make the row spacing equal to the spacing between icons. However, the row spacing is limited to 20 pixels maximum.Developers should use the property
attachmentsController
to provide attachment information; thedelegate
, thedataSource
and the list ofFUIAttachmentAction
implementations for the desired type of attachments. The app can use the built-in types or implement additional types as desired.Color settings:
Setting tintColor for add button for a state using setTintColor(_:for:) api. Currently
normal
and.selected
are supported.cell.setTintColor(UIColor.red, for: .normal)
There are three built-in
FUIAttachmentAction
:FUIAddPhotoAttachmentAction
: Choose photo from the photo library.FUITakePhotoAttachmentAction
: Take photo using the camera.FUIDocumentPickerAttachmentAction
: Select file using standardUIDocumentPickerViewController
.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: FUIAttachmentsFormCell.reuseIdentifier, for: indexPath) as! FUIAttachmentsFormCell cell.attachmentsController.delegate = self cell.attachmentsController.dataSource = self let addPhotoAction = FUIAddPhotoAttachmentAction() addPhotoAction.delegate = self cell.attachmentsController.addAttachmentAction(addPhotoAction) let takePhotoAction = FUITakePhotoAttachmentAction() takePhotoAction.delegate = self cell.attachmentsController.addAttachmentAction(takePhotoAction) let filePickerAction = FUIDocumentPickerAttachmentAction() filePickerAction.delegate = self cell.attachmentsController.addAttachmentAction(filePickerAction) return cell } var attachmentURLs: [URL] = [URL]() // MARK: FUIAttachmentsViewControllerDataSource methods func attachmentsViewController(_ attachmentsViewController: FUIAttachmentsViewController, iconForAttachmentAtIndex index: Int) -> (image: UIImage, contentMode: UIViewContentMode)? { let urlString = self.attachmentURLs[index].absoluteString guard let image = self.attachmentThumbnails[urlString] else { return nil } return (image!, .scaleAspectFill) } func numberOfAttachments(in attachmentsViewController: FUIAttachmentsViewController) -> Int { return attachmentURLs.count } func attachmentsViewController(_ attachmentsViewController: FUIAttachmentsViewController, urlForAttachmentAtIndex index: Int) -> URL? { return attachmentURLs[index] } // MARK: FUIAttachmentsViewControllerDelegateMethods func attachmentsViewController(_ attachmentsViewController: FUIAttachmentsViewController, couldNotPresentAttachmentAtIndex index: Int) { } func attachmentsViewController(_ attachmentsViewController: FUIAttachmentsViewController, didPressDeleteAtIndex index: Int) { self.attachmentURLs.remove(at: index) self.tableView.reloadSections(IndexSet(integer:attachmentSection), with: .automatic) } //MARK: FUIAddPhotoAttachmentActionDelegate func addPhotoAttachmentAction(_ action: FUIAddPhotoAttachmentAction, didSelectPhotoAt url: URL) { self.addAttachmentURL(url) } //MARK: FUITakePhotoAttachmentActionDelegate func takePhotoAttachmentAction(_ action: FUITakePhotoAttachmentAction, didTakePhotoAt url: URL) { self.addAttachmentURL(url) } func addAttachmentURL(_ url: URL) { self.attachmentURLs.append(url) DispatchQueue.main.async { self.tableView.reloadSections(IndexSet(integer:self.attachmentSection), with: .automatic) self.tableView.scrollToRow(at: IndexPath(row: 0, section: self.attachmentSection) , at: .middle, animated: true) } } //MARK: FUIDocumentPickerAttachmentActionDelegate { var documentPicker: UIDocumentPickerViewController { return UIDocumentPickerViewController(documentTypes: ["public.data"], in: .import) } func documentPickerAttachmentAction(_ action: FUIDocumentPickerAttachmentAction, didPickFileAt url: URL) { if let savedUrl = saveFileToTempFolder(url) { self.addAttachmentURL(savedUrl) } self.tableView.reloadSections(IndexSet(integer:self.attachmentSection), with: .automatic) }
## Theming
Supported
TEXT
class paths:fdlFUIAttachmentsFormView_attachmentTitleLabel {} fdlFUIAttachmentsViewController_alertActionTitle {} fdlFUIFileThumbnailCollectionItemView_titleLabel {}
Supported
TEXT
properties:font-color: Color; font-style: UIFontTextStyle;
Supported
IMAGE
class paths:fdlFUIFileThumbnailCollectionItemView_detailImageView {}
Supported
IMAGE
properties:tint-color: Color;
Supported
BUTTON
class paths:fdlFUIAddButtonCell_addButton {}
Supported
BUTTON
properties:image: Image; tint-color: Color;
Supported
CELL
class paths:fdlFUIAttachmentsFormCell_thumbnailCell {} fdlFUIAttachmentsFormCell_addButtonCell {}
Supported
CELL
properties:border-color: Color; border-width: Integer; corner-radius: Integer;
Supported style classes
See moreDeclaration
Swift
@IBDesignable open class FUIAttachmentsFormCell : NibDesignableFUIBaseTableViewCell
-
Simple
UITableViewCell
subclass, containing aUIButton
instance which can be aligned to 3FUIHorizontalAlignment
positions:.left
,.center
,.right
.Color settings:
Setting tintColor for button for a state using setTintColor(_:for:) api. Currently
disabled
,normal
andselected
are supported.cell.setTintColor(UIColor.red, for: .normal)
## Usage: Implement the action handler for the
UIButton
instance, to respond toUIControl
events.## Theming Supported style classes
See morefdlFUIButtonFormCell fdlFUIButtonFormCell_button
Declaration
Swift
@IBDesignable open class FUIButtonFormCell : NibDesignableFUIBaseTableViewCell
-
FUIInlineValidationView is a
UIView
contains aUILabel
. It is used byFUIInlineValidationTableViewCell
as a validation view appearing at the bottom to show the validation message.Theming
Supported style classes
See morefdlFUIInlineValidationView fdlFUIInlineValidationView_titleLabel fdlFUIInlineValidationView_separatorView fdlFUIInlineValidationView_backgroundView
Declaration
Swift
open class FUIInlineValidationView : NibDesignable
-
FUIInlineValidationTableViewCell
is a base class forFUIFormCell
s that need to support validation handling. The validation view will appear at the bottom of cell if validation message is set.Code usage:
- Custom class should subclass FUIInlineValidationTableViewCell to enable validation handling. Create a bottom constraint on main view and contentView and assign to
validationViewHeight
property.
public class FUITitleFormCell: FUIInlineValidationTableViewCell, FUIFormCell, UITextFieldDelegate { public override init(style: UITableViewCellStyle, reuseIdentifier: String?) { //Any setup code self.validationViewHeight = self.stackViewBottom } }
- Set validationMessage on the cell.
See moreoverride func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: FUITitleFormCell.reuseIdentifier, for: indexPath) as! FUITitleFormCell //Configure your cell cell.validationMessage = "Validation msg" }
Declaration
Swift
open class FUIInlineValidationTableViewCell : NibDesignableFUIBaseTableViewCell, FUIInlineValidation, FUIAccessoryViewDelegate
- Custom class should subclass FUIInlineValidationTableViewCell to enable validation handling. Create a bottom constraint on main view and contentView and assign to
-
FUIFilterFeedbackControl
provides an easy way for programmers to represent a list of applied filters. ThisFUIFilterFeedbackControl
usually appears at the top of the screen above a UITableView. Although you can set this view to any height, it is recommended to set the height of this cell toCGFloat(44)
. And set its height constraint to the same value.Developers can use in Interface Builder by adding a UIView to their storyboard or XIB, then setting its class to
FUIFilterFeedbackControl
. Then set thefilterGroups
, andfilterResultsUpdater
properties.@IBOutlet var filterFeedbackControl: FUIFilterFeedbackControl! // ... var sortGroup = FUIFilterGroup() var mileGroup = FUIFilterGroup() var nearGroup = FUIFilterGroup() override func viewDidLoad() { super.viewDidLoad() let sortDistanceItem = FUIFilterItem("Sort: Distance", isFavorite: false, isActive: true) let sortPriceItem = FUIFilterItem("Sort: Price", isFavorite: false, isActive: false) let sortRatingsItem = FUIFilterItem("Sort: Ratings", isFavorite: false, isActive: false) let sortAvailabilityItem = FUIFilterItem("Sort: Availability", isFavorite: false, isActive: false) let mile1Item = FUIFilterItem("0.1 mi", isFavorite: true, isActive: false) let mile2Item = FUIFilterItem("0.2 mi", isFavorite: true, isActive: false) let mile3Item = FUIFilterItem("0.3 mi", isFavorite: true, isActive: false) let mile4Item = FUIFilterItem("0.4 mi", isFavorite: true, isActive: true) sortGroup.items = [sortDistanceItem, sortPriceItem, sortRatingsItem, sortAvailabilityItem] sortGroup.allowsEmptySelection = false sortGroup.isMutuallyExclusive = true mileGroup.items = [mile1Item, mile2Item, mile3Item, mile4Item] mileGroup.allowsEmptySelection = true mileGroup.isMutuallyExclusive = true let nearGasItem = FUIFilterItem("Nearby Gas", isFavorite: true, isActive: false) let nearCoffeeItem = FUIFilterItem("Nearby Coffee", isFavorite: true, isActive: false) let nearRestaurantsItem = FUIFilterItem("Nearby Restaurants", isFavorite: true, isActive: false) nearGroup.items = [nearGasItem, nearCoffeeItem, nearRestaurantsItem] nearGroup.allowsEmptySelection = true nearGroup.isMutuallyExclusive = false filterFeedbackControl.filterGroups = [sortGroup, mileGroup, nearGroup] filterFeedbackControl.filterResultsUpdater = self // ... } func updateFilterResults(for filterFeedbackControl: FUIFilterFeedbackControl) { let effectiveItems = filterFeedbackControl.filterItems // ... }
Theming
FUIFilterFeedbackControl
is using a list ofFUISegmentedControl
componentes. Therefore, theming ofFUIFilterFeedbackControl
should be using theFUISegmentedControl
theming elements.fdlFioriSegmentedControl_item_contentView { border-color: @primary4; } fdlFioriSegmentedControl_item_titleLabel { font-color: @primary2; } fdlFioriSegmentedControl_item_contentView_selected { border-color: @tintColorDark; } fdlFioriSegmentedControl_item_titleLabel_selected { font-color: @tintColorDark; }
Theming
Supported style classes
See morefdlFUIFilterFeedbackControl fdlFUIFilterFeedbackControl_lineView
Declaration
Swift
open class FUIFilterFeedbackControl : UIView
-
This protocol is to be used in
See moreFUIFilterFeedbackControl
for updateing the results based on the changes in filters.Declaration
Swift
public protocol FUIFilterResultsUpdating : AnyObject
-
A
See moreFUIFilterGroup
represents a group of relatedFUIFilterItem
objects.Declaration
Swift
open class FUIFilterGroup
-
A
See moreFUIFilterItem
represent oneFilter
item to be displayed on theFUIFilterFeedbackControl
view.Declaration
Swift
public class FUIFilterItem : Equatable