Search Bar and Barcode Scan

  • Fiori style UISearchBar.

    Developer can add a FUIBarcodeScanner to this FUISearchBar by setting the isBarcodeScannerEnabled property of the FUISearchBar to true. A barcode scanner icon will be displayed at the bookmark icon location of the search bar.

    A barcode scanner view will be displayed when the barcode scanner icon is tapped.

    Please refer to FUISearchController about how to use this FUISearchBar.

    Attention

    The delegate object with type UISearchBarDelegate is declared as a weak reference. So on deallocation it will be automatically set to nil. To keep it alive as expected, developer should retain the delegate object during its whole execution scope.

    See more

    Declaration

    Swift

    public class FUISearchBar : UISearchBar
  • Fiori style UISearchController. The only difference between FUISearchController and regular UISearchController is the searchBar. FUISearchController‘s searchBar is FUISearchBar.

    Developer can add a FUIBarcodeScanner to this FUISearchBar by setting the isBarcodeScannerEnabled property of the FUISearchBar to true. A barcode scanner icon will be displayed at the bookmark icon location of the search bar.

    A barcode scanner view will be displayed when the barcode scanner icon is tapped.

    For iOS 11, it is recommended to set the FUISearchController to navigationItem, instead of the table view header for iOS 10.

    Here is a sample code snippet.

    // Instantiate an FUISearchController and configure its properties
    searchController = FUISearchController(searchResultsController: nil)
    searchController.searchResultsUpdater = self
    searchController.hidesNavigationBarDuringPresentation = true
    searchController.searchBar.placeholderText = "Search The List"
    
    // Adding barcode scanner to this search bar
    searchController.searchBar.isBarcodeScannerEnabled = true
    searchController.searchBar.barcodeScanner?.scanMode = .EAN_UPC
    searchController.searchBar.barcodeScanner?.scanResultTransformer = { (scanString) -> String in
    return scanString.uppercased()
    }
    
    if #available(iOS 11, *) {
    navigationItem.searchController = searchController
    navigationItem.hidesSearchBarWhenScrolling = false
    } else {
    tableView.tableHeaderView = searchController?.searchBar
    }
    
    
    

    Theming

    
    fdlFUISearchController_searchBar {
    bar-tint-color: @line;
    background-color: @primary1_darkBackground;
    background-tint-color: @tintColorDark;
    }
    
    
    See more

    Declaration

    Swift

    open class FUISearchController : UISearchController, FUIBarcodeScanViewControllerDelegate
    extension FUISearchController: UISearchBarDelegate
    extension FUISearchController: UIBarPositioningDelegate
    extension FUISearchController: UISearchResultsUpdating
  • This UIViewController is to be used for user to scan for 1D and 2D codes using the device’s camera.

    Developer may use segue in their storyboard to access this FUIBarcodeScanViewController in FUIBarcodeScanViewController.storyboard. The delegate property of the FUIBarcodeScanViewController and the properties of the FUIBarcodeScanner may be set in the prepare for segue function as follows:

    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let destination = segue.destination as! UINavigationController
    let vc = destination.viewControllers[0]
    if vc is FUIBarcodeScanViewController {
    let scanViewController = vc as! FUIBarcodeScanViewController
    switch segue.identifier! {
    case "CustomScanSegue":
    scanViewController.barcodeScanner.scanMode = .qr
    scanViewController.barcodeScanner.indicatorBorderColor = UIColor.red.cgColor
    scanViewController.barcodeScanner.indicatorBorderWidth = 20
    scanViewController.barcodeScanner.promptMessage = "Scan A QR Code"
    scanViewController.barcodeScanner.scanResultTransformer = { s in
    return s + "-transformed"
    }
    scanViewController.delegate = self
    default:
    break
    }
    }
    }
    
    
    

    Or, developer may use codes to instantiate this controller as follows:

    
    func customScanFromCode(_ sender: Any) {
    let scanViewController = FUIBarcodeScanViewController.createInstanceFromStoryboard()
    scanViewController.barcodeScanner.scanMode = .qr
    scanViewController.barcodeScanner.indicatorBorderColor = UIColor.red.cgColor
    scanViewController.barcodeScanner.indicatorBorderWidth = 20
    scanViewController.barcodeScanner.promptMessage = "Scan A QR Code"
    scanViewController.barcodeScanner.scanResultTransformer = { s in
    return "transformed"
    }
    scanViewController.delegate = self
    
    let navController = UINavigationController(rootViewController: scanViewController)
    self.navigationController?.present(navController, animated: true, completion: nil)
    }
    
    

    Also, developer needs to implement the FUIBarcodeScanViewControllerDelegate protocol to be notified with a scan result:

    
    func barcodeScanViewController(_ barcodeScanViewController: FUIBarcodeScanViewController, didReceiveScanResult scanResult: FUIBarcodeScanResult?) {
    print("scan result: \(String(describing: scanResult?.scanResultString))")
    if scanResult?.scanResultString != "success" {
    alertInvalidQRCode()
    } else {
    barcodeScanViewController.dismiss(animated: true, completion: nil)
    }
    }
    
    

    Attention

    The delegate object with type FUIBarcodeScanViewControllerDelegate is declared as a weak reference. So on deallocation it will be automatically set to nil. To keep it alive as expected, developer should retain the delegate object during the whole execution scope.

    See more

    Declaration

    Swift

    public class FUIBarcodeScanViewController : UIViewController, FUIBarcodeScannerDelegate
  • The delegate protocol for the FUIBarcodeScanViewController.

    See more

    Declaration

    Swift

    public protocol FUIBarcodeScanViewControllerDelegate : AnyObject
  • Declaration

    Swift

    public class FUIBarcodeScanView : UIView
  • Protocol to interact with a Barcode Scanner. The FUIBarcodeScanner protocol provides properties to configure the barcode scanner. A barcode scanner can automatically scan for 1D and 2D codes using the device’s camera.

    You can retrieve a Scanner instance through the UIViewController that host the barcode scanner. Currently, there are two scanner controller in SAPFiori:

    See more

    Declaration

    Swift

    public protocol FUIBarcodeScanner
  • The ScanMode enum defines a set of predefined modes to scan codes with the Scanner. Each mode contains a set of different codes including 1D and 2D codes.

    See more

    Declaration

    Swift

    @objc
    public enum FUIBarcodeScanMode : Int
  • Represents the decoded result of a code scanning operation.

    See more

    Declaration

    Swift

    public struct FUIBarcodeScanResult
  • Enum which covers all errors occurring in the barcode scanner framework.

    See more

    Declaration

    Swift

    public enum FUIBarcodeScannerError : Error, Equatable
    extension FUIBarcodeScannerError: CustomStringConvertible
  • A view representation of FUISearchTag.

    See more

    Declaration

    Swift

    open class FUISearchTagView : UIView
    extension FUISearchTagView: UIKeyInput
    extension FUISearchTagView: UITextInputTraits
  • A UIScrollView shows a set of tags and a text field which allows user to input text.

    Usage

    Initialization

    You can position tags field either setting the frame or constraints.

    let tagsField = FUISearchTagsField()
    

    Configuration

    tagsField.tintColor = UIColor.preferredFioriColor(forStyle: .tintColorDark) // cursor color
    tagsField.backgroundColor = UIColor.preferredFioriColor(forStyle: .primary9)
    tagsField.contentInset = UIEdgeInsetsMake(9, 0, 9, 0)
    tagsField.spaceBetweenTags = 5.0
    tagsField.font = UIFont.systemFont(ofSize: 16)
    tagsField.textColor = UIColor.preferredFioriColor(forStyle: .tintColorDark)
    tagsField.fieldTextColor = UIColor.preferredFioriColor(forStyle: .tintColorDark)
    tagsField.selectedColor = UIColor.preferredFioriColor(forStyle: .tintColorDark)
    tagsField.selectedTextColor = UIColor.preferredFioriColor(forStyle: .primary1, background: .darkBackground)
    tagsField.displayDelimiter = true
    tagsField.delimiter = ","
    tagsField.placeholder = "Search for Assignee"
    tagsField.placeholderColor = UIColor.preferredFioriColor(forStyle: .primary3)
    tagsField.numberOfLines = 2
    

    Register a event handler

    tagsField.onDidChangeText = { [weak self] (sender, text) in
    // do something in response to text change.
    }
    

    Add or remove tags

    tagsField.addTag("str")
    tagsField.removeTag("str")
    

    Theming

    Supported class paths:

    fdlFUITagsField {}

    Supported TagsField attributes:

    tint-color (Color) background-color (Color) content-insets (Box) font-color { -placeholder } (Color) font-name (FontName) font-style (UIFontTextStyle) font-size (Number) text-line-clamp (Integer) line-spacing (Float) tag-spacing (Float) tag-delimiter (String)

    Supported Tag attributes:

    tag-font-color { -selected } (Color) tag-background-color { -selected } (Color) tag-content-insets (Box)

    Supported ImageView attributes:

    search-icon-image (Image) search-icon-image-tint-color (Color)

    See more

    Declaration

    Swift

    open class FUISearchTagsField : UIScrollView
    extension FUISearchTagsField: UITextFieldDelegate
    extension FUISearchTagsField: UIScrollViewDelegate
  • A UIView contains a tag field and table view.

    Components

    • tagsField: A WSTagsField shows some tags and an input text field.
    • tableView: A UITableView shows a list of items.

    Usage

    Initialization

    You can position tags field either setting the frame or constraints.

    let searchToSelectView = FUISearchToSelectView()
    

    Configuration

    You can configure tags field by access tagsField property.

    self.tagsField.backgroundColor = UIColor.blue
    

    Theming

    Supported class paths:

    fdlFUISearchToSelectView {}
    fdlFUISearchToSelectView_tableView {}
    fdlFUISearchToSelectView_tagsField {}
    

    Supported TagsField attributes:

    tint-color (Color)
    background-color (Color)
    content-insets (Box)
    font-color { -placeholder } (Color)
    font-name (FontName)
    font-style (UIFontTextStyle)
    font-size (Number)
    text-line-clamp (Integer)
    line-spacing (Float)
    tag-spacing (Float)
    tag-delimiter (String)
    

    Supported Tag attributes:

    tag-font-color { -selected } (Color)
    tag-background-color { -selected } (Color)
    tag-content-insets (Box)
    

    Supported ImageView attributes:

    search-icon-image (Image)
    search-icon-image-tint-color (Color)
    
    See more

    Declaration

    Swift

    open class FUISearchToSelectView : UIView
  • The delegate of FUISearchToSelectView manages uuids of cells and corresponding tag titles.

    See more

    Declaration

    Swift

    public protocol FUISearchToSelectViewDelegate : AnyObject
  • A view controller which specializes in managing a tags field and a table view. Selected table view cell will appear in tags field with a designated tag. You can also deselect a table view cell by deleting its designated tag in tags field. In order to make this work, your subclass must implement FUISearchToSelectViewDelegate delegate.

    Components

    • searchToSelectView
    • tagsField
    • tableView

    Usage

    Subclassing and conforms to delegate. It conforms to UITableViewDataSource and UITableViewDelegate by default.

    class MyController: FUISearchToSelectViewController, FUiSearchToSelectViewDelegate {}
    

    Override viewDidLoad and do some setup here

    override func viewDidLoad() {
        super.viewDidLoad()
        self.tableView.register(FUIObjectTableViewCell.self, forCellReuseIdentifier: FUIObjectTableViewCell.reuseIdentifier)
        self.tableView.register(FUITableViewHeaderFooterView.self, forHeaderFooterViewReuseIdentifier: FUITableViewHeaderFooterView.reuseIdentifier)
        #if swift(>=4.2)
            self.tableView.rowHeight = UITableView.automaticDimension
        #else
            self.tableView.rowHeight = UITableViewAutomaticDimension
        #endif
        self.tableView.estimatedRowHeight = 50
        // ...
    }
    

    Implement dataSource and delegate methods

    
    // Define data model.
    var objects: [ModelObj] = []
    
    // UITableView dataSource and delegate methods
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return objects.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: FUIObjectTableViewCell.reuseIdentifier, for: indexPath) as! FUIObjectTableViewCell
        let model = objects[indexPath.row]
    
        cell.isMomentarySelection = false
        cell.selectionStyle = .none
        cell.detailImage = model.image
        cell.detailImageView.isCircular = true
        cell.headlineText = model.headline
        cell.subheadlineText = model.subheadline
        cell.footnoteText = model.footnote
    
        return cell
    }
    
    // FUISearchtoSelectViewControllerDelegate delegate
    func searchToSelectView(_ searchToSelectView: FUISearchToSelectView, uuidForItemAt indexPath: IndexPath) -> String? {
        let obj = objects[indexPath.row]
        return obj.uuid
    }
    
    func searchToSelectView(_ searchToSelectView: FUISearchToSelectView, tagTitleFor itemUUID: String) -> String? {
        if let obj = objects.filter ({ $0.uuid == itemUUID }).first {
            return obj.headline
        }
        return nil
    }
    
    

    Note

    Developer is responsible for updating selectedUUIDs after data changes to make sure all selected UUIDs are still valid.

    Theming

    Supported class paths:

    fdlFUISearchToSelectViewController_searchToSelectView {}
    fdlFUISearchToSelectViewController_tableView {}
    fdlFUISearchToSelectViewController_tagsField {}
    

    Supported TagsField attributes:

    tint-color (Color)
    background-color (Color)
    content-insets (Box)
    font-color { -placeholder } (Color)
    font-name (FontName)
    font-style (UIFontTextStyle)
    font-size (Number)
    text-line-clamp (Integer)
    line-spacing (Float)
    tag-spacing (Float)
    tag-delimiter (String)
    

    Supported Tag attributes:

    tag-font-color { -selected } (Color)
    tag-background-color { -selected } (Color)
    tag-content-insets (Box)
    

    Supported ImageView attributes:

    search-icon-image (Image)
    search-icon-image-tint-color (Color)
    
    See more

    Declaration

    Swift

    open class FUISearchToSelectViewController : UIViewController, UITableViewDataSource, UITableViewDelegate
  • A struct holds the infomation for a tag which presents in a FUISearchTagsField.

    See more

    Declaration

    Swift

    public struct FUISearchTag : Hashable