Skip to content

Commit

Permalink
#1 Changed PnPID view controller
Browse files Browse the repository at this point in the history
  • Loading branch information
carlos21 committed Jun 28, 2018
1 parent 3062053 commit 9163e95
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 109 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,17 @@
import UIKit
import Bluetooth

final class PnPIDCharacteristicViewController: UIViewController, CharacteristicViewController, InstantiableViewController {
final class PnPIDCharacteristicViewController: UITableViewController, CharacteristicViewController, InstantiableViewController {

typealias VendorIDSource = GATTPnPID.VendorIDSource

// MARK: - IB Outlets
// MARK: - Properties

@IBOutlet weak var vendorIDSourceTextField: UITextField!
@IBOutlet weak var vendorIDTextField: UITextField!
@IBOutlet weak var productIDTextField: UITextField!
@IBOutlet weak var productVersionTextField: UITextField!
private let cellIdentifier = "InputTextViewCell"

// MARK: - Properties
private var fields = [Field]()

var value = GATTPnPID(vendorIdSource: VendorIDSource(rawValue: 0x01)!, vendorId: 0, productId: 0, productVersion: 0)
var value = GATTPnPID(vendorIdSource: .fromAssignedNumbersDocument, vendorId: 0, productId: 0, productVersion: 0)

var valueDidChange: ((GATTPnPID) -> ())?

Expand All @@ -31,29 +28,139 @@ final class PnPIDCharacteristicViewController: UIViewController, CharacteristicV
override func viewDidLoad() {
super.viewDidLoad()

configureView()
fields = [.vendorIdSource("\(value.vendorIdSource)"),
.vendorId("\(value.vendorId)"),
.productId("\(value.productId)"),
.productVersionId("\(value.productVersion)"),]

tableView.register(UINib(nibName: cellIdentifier, bundle: nil), forCellReuseIdentifier: cellIdentifier)
tableView.separatorStyle = .none
}

// MARK: - Methods
// MARK: - UITableViewController

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return fields.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let field = fields[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! InputTextViewCell
cell.selectionStyle = .none

configure(cell, field: field)

return cell
}

func configureView() {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

guard isViewLoaded else { return }
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! InputTextViewCell
cell.inputTextView.textField.becomeFirstResponder()
}

// MARK: - Methods

func configure(_ cell: InputTextViewCell, field: Field) {

updateText()
cell.inputTextView.value = field.bluetoothValue
cell.inputTextView.posibleInputValues = field.posibleValues
cell.inputTextView.isEnabled = valueDidChange != nil
cell.inputTextView.keyboardType = field.keyboardType
cell.inputTextView.fieldLabelText = field.title
cell.inputTextView.placeholder = field.title
cell.inputTextView.validator = { value in

guard value.trim() != ""
else { return .none }

switch field {
case .vendorId(let value):

guard let _ = UInt16(value)
else { return .error("Maximum value is 0xFFFF)") }

case .productId(let value):

guard let _ = UInt16(value)
else { return .error("Maximum value is 0xFFFF)") }

case .productVersionId(let value):

guard let _ = UInt16(value)
else { return .error("Maximum value is 0xFFFF)") }

default:
break
}

return .none
}
}
}

extension PnPIDCharacteristicViewController {

private func updateText() {
enum Field {

case vendorIdSource(String)
case vendorId(String)
case productId(String)
case productVersionId(String)

var title: String {

switch self {
case .vendorIdSource:
return "Vendor ID Source"

case .vendorId:
return "Vendor ID"

case .productId:
return "Product ID"

case .productVersionId:
return "Product Version ID"
}
}

var bluetoothValue: String {
switch self {
case .vendorIdSource(let value):
return value

case .vendorId(let value):
return value

case .productId(let value):
return value

case .productVersionId(let value):
return value
}
}

let enabled = valueDidChange != nil
vendorIDSourceTextField.isEnabled = enabled
vendorIDTextField.isEnabled = enabled
productIDTextField.isEnabled = enabled
productVersionTextField.isEnabled = enabled
var posibleValues: [String] {
switch self {
case .vendorIdSource:
return [VendorIDSource.fromAssignedNumbersDocument.rawValue.description,
VendorIDSource.fromVendorIDValue.rawValue.description]

default:
return []
}
}

vendorIDSourceTextField.text = "\(value.vendorIdSource.rawValue)"
vendorIDTextField.text = "\(value.vendorId)"
productIDTextField.text = "\(value.productId)"
productVersionTextField.text = "\(value.productVersion)"
var keyboardType: UIKeyboardType {
switch self {
case .vendorIdSource:
return .default

default:
return.numberPad
}
}
}
}
97 changes: 12 additions & 85 deletions BluetoothExplorer/PnPIDCharacteristic.storyboard
Original file line number Diff line number Diff line change
@@ -1,104 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="lOT-7T-ouj">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--PnP ID-->
<scene sceneID="Xip-Sx-1UG">
<scene sceneID="8VT-95-AUV">
<objects>
<viewController storyboardIdentifier="PnPIDCharacteristicViewController" title="System ID" id="p3U-do-pXC" userLabel="PnP ID" customClass="PnPIDCharacteristicViewController" customModule="BluetoothExplorer" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="KoM-u3-hpO"/>
<viewControllerLayoutGuide type="bottom" id="aku-he-5yT"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="bIQ-ZR-rA4">
<tableViewController storyboardIdentifier="PnPIDCharacteristicViewController" title="PnP ID" id="lOT-7T-ouj" customClass="PnPIDCharacteristicViewController" customModule="BluetoothExplorer" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="BEG-hs-DJk">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="18s-im-kHK">
<rect key="frame" x="16" y="241" width="343" height="185"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Vendor ID Source" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="W7m-wn-yjF" userLabel="Manufacturer Name Text field">
<rect key="frame" x="0.0" y="0.0" width="343" height="35"/>
<constraints>
<constraint firstAttribute="height" constant="35" id="JiV-jV-L9I"/>
</constraints>
<nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
</textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Vendor ID" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="J95-eo-S9N" userLabel="Organizational Identifier Text field">
<rect key="frame" x="0.0" y="50" width="343" height="35"/>
<constraints>
<constraint firstAttribute="height" constant="35" id="Ywa-FK-mZA"/>
</constraints>
<nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
</textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Product Version" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="kjn-Ac-wbs" userLabel="Organizational Identifier Text field">
<rect key="frame" x="0.0" y="150" width="343" height="35"/>
<constraints>
<constraint firstAttribute="height" constant="35" id="rOD-wg-FkW"/>
</constraints>
<nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
</textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Product ID" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="BGA-bL-WJe" userLabel="Organizational Identifier Text field">
<rect key="frame" x="0.0" y="100" width="343" height="35"/>
<constraints>
<constraint firstAttribute="height" constant="35" id="j2Y-4u-sIx"/>
</constraints>
<nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
</textField>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="W7m-wn-yjF" firstAttribute="leading" secondItem="18s-im-kHK" secondAttribute="leading" id="6Ts-O0-2if"/>
<constraint firstItem="W7m-wn-yjF" firstAttribute="leading" secondItem="J95-eo-S9N" secondAttribute="leading" id="Hyf-6J-c7s"/>
<constraint firstItem="BGA-bL-WJe" firstAttribute="top" secondItem="J95-eo-S9N" secondAttribute="bottom" constant="15" id="IEC-Q0-mKf"/>
<constraint firstAttribute="bottom" secondItem="kjn-Ac-wbs" secondAttribute="bottom" id="Ol7-KC-dLk"/>
<constraint firstItem="W7m-wn-yjF" firstAttribute="top" secondItem="18s-im-kHK" secondAttribute="top" id="RcF-SS-G84"/>
<constraint firstItem="J95-eo-S9N" firstAttribute="top" secondItem="W7m-wn-yjF" secondAttribute="bottom" constant="15" id="Uve-MW-Hni"/>
<constraint firstItem="W7m-wn-yjF" firstAttribute="trailing" secondItem="J95-eo-S9N" secondAttribute="trailing" id="eiM-rd-CFg"/>
<constraint firstItem="kjn-Ac-wbs" firstAttribute="top" secondItem="BGA-bL-WJe" secondAttribute="bottom" constant="15" id="f86-FK-Odt"/>
<constraint firstItem="BGA-bL-WJe" firstAttribute="trailing" secondItem="J95-eo-S9N" secondAttribute="trailing" id="kNv-ng-5y8"/>
<constraint firstItem="BGA-bL-WJe" firstAttribute="leading" secondItem="J95-eo-S9N" secondAttribute="leading" id="skM-Oc-d5p"/>
<constraint firstItem="kjn-Ac-wbs" firstAttribute="trailing" secondItem="BGA-bL-WJe" secondAttribute="trailing" id="xGN-92-FJ0"/>
<constraint firstItem="kjn-Ac-wbs" firstAttribute="leading" secondItem="BGA-bL-WJe" secondAttribute="leading" id="xRY-ej-HZ7"/>
<constraint firstAttribute="trailing" secondItem="W7m-wn-yjF" secondAttribute="trailing" id="y9N-VQ-kN1"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="18s-im-kHK" firstAttribute="leading" secondItem="bIQ-ZR-rA4" secondAttribute="leadingMargin" id="Wk2-Az-Nni"/>
<constraint firstItem="18s-im-kHK" firstAttribute="centerY" secondItem="bIQ-ZR-rA4" secondAttribute="centerY" id="kEJ-uW-YYW"/>
<constraint firstItem="18s-im-kHK" firstAttribute="trailing" secondItem="bIQ-ZR-rA4" secondAttribute="trailingMargin" id="zBI-Xa-7hI"/>
</constraints>
</view>
<navigationItem key="navigationItem" title="PnP ID" id="qc4-YI-BDQ"/>
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
<connections>
<outlet property="productIDTextField" destination="BGA-bL-WJe" id="KuH-vh-izx"/>
<outlet property="productVersionTextField" destination="kjn-Ac-wbs" id="W07-sj-JlG"/>
<outlet property="vendorIDSourceTextField" destination="W7m-wn-yjF" id="MXy-ix-B60"/>
<outlet property="vendorIDTextField" destination="J95-eo-S9N" id="3Z1-4R-PWa"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="vn1-MQ-ltx" userLabel="First Responder" sceneMemberID="firstResponder"/>
<connections>
<outlet property="dataSource" destination="lOT-7T-ouj" id="rNZ-gJ-kE1"/>
<outlet property="delegate" destination="lOT-7T-ouj" id="MKt-VL-T8f"/>
</connections>
</tableView>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="p1c-lM-rtX" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="90.400000000000006" y="61.619190404797607"/>
<point key="canvasLocation" x="785" y="62"/>
</scene>
</scenes>
</document>
48 changes: 47 additions & 1 deletion BluetoothExplorer/View/InputTextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ import UIKit

class InputTextField: UITextField {

// MARK: - Properties

var posibleValues = [String]() {
didSet {
inputView = (posibleValues.count == 0) ? nil : pickerView
}
}

private lazy var pickerView: UIPickerView = {
let picker = UIPickerView()
picker.delegate = self
return picker
}()

// MARK: - Initializers

override init(frame: CGRect) {
super.init(frame: frame)
addToolbar()
Expand All @@ -21,7 +37,9 @@ class InputTextField: UITextField {
addToolbar()
}

func addToolbar() {
// MARK: - Methods

private func addToolbar() {

let toolbar = UIToolbar()
toolbar.isTranslucent = true
Expand All @@ -41,3 +59,31 @@ class InputTextField: UITextField {
}

}

extension InputTextField: UIPickerViewDataSource {

func numberOfComponents(in pickerView: UIPickerView) -> Int {

return 1
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {

return posibleValues.count
}

}

extension InputTextField: UIPickerViewDelegate {

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {

return posibleValues[row]
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

text = posibleValues[row]
}

}
6 changes: 6 additions & 0 deletions BluetoothExplorer/View/InputTextView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ class InputTextView: NibDesignableView {
set { textField.isEnabled = newValue }
}

public var posibleInputValues: [String] {

get { return textField.posibleValues }
set { textField.posibleValues = newValue; }
}

private var validation: Validation = .none {
didSet { updateView() }
}
Expand Down

0 comments on commit 9163e95

Please sign in to comment.