Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HW-52171 Implement phone input type #11

Merged
merged 6 commits into from
May 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions HyperwalletUISDK.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
078B457E2273895C005B0248 /* SelectTransferMethodTypePresenterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078B45722273895C005B0248 /* SelectTransferMethodTypePresenterTests.swift */; };
078B457F2273895C005B0248 /* AddTransferMethodPresenterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078B45732273895C005B0248 /* AddTransferMethodPresenterTests.swift */; };
078B45812273A441005B0248 /* HyperwalletUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078B45802273A441005B0248 /* HyperwalletUI.swift */; };
4A12653C2280B02900C0F59E /* DateWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A12653B2280B02900C0F59E /* DateWidget.swift */; };
4A12653E2280B12F00C0F59E /* PhoneWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A12653D2280B12F00C0F59E /* PhoneWidget.swift */; };
9807B762226442C60028A280 /* AuthenticationTokenResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = DBFB61512261E84C00C4A8AA /* AuthenticationTokenResponse.json */; };
9807B763226442C60028A280 /* BankAccountInvalidRoutingResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = DBFB61472261E84C00C4A8AA /* BankAccountInvalidRoutingResponse.json */; };
9807B764226442C60028A280 /* BankCardDuplicateResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = DBFB614A2261E84C00C4A8AA /* BankCardDuplicateResponse.json */; };
Expand All @@ -33,6 +35,7 @@
9807B76C226442C60028A280 /* TransferMethodConfigurationBankCardResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = DBFB614F2261E84C00C4A8AA /* TransferMethodConfigurationBankCardResponse.json */; };
9807B76D226442C60028A280 /* UnexpectedErrorResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = DBFB61492261E84C00C4A8AA /* UnexpectedErrorResponse.json */; };
98220B8C2265793700055E18 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 98220B8B2265793700055E18 /* README.md */; };
9826056822822E8A000CCA2D /* UIToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826056722822E8A000CCA2D /* UIToolbar.swift */; };
98541F152273D72C007D4238 /* CHANGELOG.md in Resources */ = {isa = PBXBuildFile; fileRef = 98541F142273D72C007D4238 /* CHANGELOG.md */; };
C358A9A52272644000E5AE47 /* AddTransferMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = C358A9A22272644000E5AE47 /* AddTransferMethod.swift */; };
C358A9A62272644000E5AE47 /* ListTransferMethods.swift in Sources */ = {isa = PBXBuildFile; fileRef = C358A9A32272644000E5AE47 /* ListTransferMethods.swift */; };
Expand Down Expand Up @@ -115,8 +118,7 @@
DBCA388B225E8BAA00CD4137 /* WidgetFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCA3853225E8BAA00CD4137 /* WidgetFactory.swift */; };
DBCA388C225E8BAA00CD4137 /* TextWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCA3854225E8BAA00CD4137 /* TextWidget.swift */; };
DBCA388E225E8BAA00CD4137 /* AbstractWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCA3857225E8BAA00CD4137 /* AbstractWidget.swift */; };
DBCA388F225E8BAA00CD4137 /* PickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCA3859225E8BAA00CD4137 /* PickerView.swift */; };
DBCA3890225E8BAA00CD4137 /* MonthYearPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCA385A225E8BAA00CD4137 /* MonthYearPicker.swift */; };
DBCA3890225E8BAA00CD4137 /* ExpiryDatePickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCA385A225E8BAA00CD4137 /* ExpiryDatePickerView.swift */; };
DBCA3891225E8BAA00CD4137 /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCA385C225E8BAA00CD4137 /* ErrorView.swift */; };
DBF89CB8227C072400AF4344 /* UserIndividualCountryCanadaResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = DBF89CB7227C072400AF4344 /* UserIndividualCountryCanadaResponse.json */; };
DBFB61462261E44C00C4A8AA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DBFB61452261E44C00C4A8AA /* Assets.xcassets */; };
Expand Down Expand Up @@ -181,7 +183,10 @@
078B45722273895C005B0248 /* SelectTransferMethodTypePresenterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectTransferMethodTypePresenterTests.swift; sourceTree = "<group>"; };
078B45732273895C005B0248 /* AddTransferMethodPresenterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddTransferMethodPresenterTests.swift; sourceTree = "<group>"; };
078B45802273A441005B0248 /* HyperwalletUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HyperwalletUI.swift; sourceTree = "<group>"; };
4A12653B2280B02900C0F59E /* DateWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateWidget.swift; sourceTree = "<group>"; };
4A12653D2280B12F00C0F59E /* PhoneWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhoneWidget.swift; sourceTree = "<group>"; };
98220B8B2265793700055E18 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
9826056722822E8A000CCA2D /* UIToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIToolbar.swift; sourceTree = "<group>"; };
98541F142273D72C007D4238 /* CHANGELOG.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = "<group>"; };
C358A9A22272644000E5AE47 /* AddTransferMethod.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddTransferMethod.swift; sourceTree = "<group>"; };
C358A9A32272644000E5AE47 /* ListTransferMethods.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTransferMethods.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -271,8 +276,7 @@
DBCA3853225E8BAA00CD4137 /* WidgetFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WidgetFactory.swift; sourceTree = "<group>"; };
DBCA3854225E8BAA00CD4137 /* TextWidget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextWidget.swift; sourceTree = "<group>"; };
DBCA3857225E8BAA00CD4137 /* AbstractWidget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AbstractWidget.swift; sourceTree = "<group>"; };
DBCA3859225E8BAA00CD4137 /* PickerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PickerView.swift; sourceTree = "<group>"; };
DBCA385A225E8BAA00CD4137 /* MonthYearPicker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MonthYearPicker.swift; sourceTree = "<group>"; };
DBCA385A225E8BAA00CD4137 /* ExpiryDatePickerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExpiryDatePickerView.swift; sourceTree = "<group>"; };
DBCA385C225E8BAA00CD4137 /* ErrorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorView.swift; sourceTree = "<group>"; };
DBD266802261A611002973C3 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
DBD266812261A611002973C3 /* Cartfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Cartfile; sourceTree = "<group>"; };
Expand Down Expand Up @@ -574,6 +578,7 @@
DBCA383B225E8BA900CD4137 /* UINavigationController.swift */,
DBCA3831225E8BA900CD4137 /* UIView.swift */,
DBCA383A225E8BA900CD4137 /* UIViewController.swift */,
9826056722822E8A000CCA2D /* UIToolbar.swift */,
);
path = Extensions;
sourceTree = "<group>";
Expand Down Expand Up @@ -612,7 +617,6 @@
isa = PBXGroup;
children = (
DBCA385B225E8BAA00CD4137 /* Error */,
DBCA3858225E8BAA00CD4137 /* Picker */,
DBCA384A225E8BAA00CD4137 /* ProcessingView */,
DBCA384E225E8BAA00CD4137 /* Widget */,
DBCA384D225E8BAA00CD4137 /* IconView.swift */,
Expand All @@ -633,8 +637,11 @@
isa = PBXGroup;
children = (
DBCA3857225E8BAA00CD4137 /* AbstractWidget.swift */,
4A12653B2280B02900C0F59E /* DateWidget.swift */,
DBCA3851225E8BAA00CD4137 /* ExpiryDateWidget.swift */,
DBCA385A225E8BAA00CD4137 /* ExpiryDatePickerView.swift */,
DBCA3850225E8BAA00CD4137 /* NumberWidget.swift */,
4A12653D2280B12F00C0F59E /* PhoneWidget.swift */,
DBCA3852225E8BAA00CD4137 /* SelectionWidget.swift */,
DBCA384F225E8BAA00CD4137 /* SelectionWidgetCell.swift */,
DBCA3854225E8BAA00CD4137 /* TextWidget.swift */,
Expand All @@ -643,15 +650,6 @@
path = Widget;
sourceTree = "<group>";
};
DBCA3858225E8BAA00CD4137 /* Picker */ = {
isa = PBXGroup;
children = (
DBCA385A225E8BAA00CD4137 /* MonthYearPicker.swift */,
DBCA3859225E8BAA00CD4137 /* PickerView.swift */,
);
path = Picker;
sourceTree = "<group>";
};
DBCA385B225E8BAA00CD4137 /* Error */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -961,10 +959,10 @@
DBCA3861225E8BAA00CD4137 /* AddTransferMethodViewController.swift in Sources */,
DBCA3888225E8BAA00CD4137 /* NumberWidget.swift in Sources */,
DBCA3863225E8BAA00CD4137 /* AddTransferMethodPresenter.swift in Sources */,
4A12653E2280B12F00C0F59E /* PhoneWidget.swift in Sources */,
DB4679C3226113D100E1AF49 /* HyperwalletBundle.swift in Sources */,
DBCA3887225E8BAA00CD4137 /* SelectionWidgetCell.swift in Sources */,
DBCA3885225E8BAA00CD4137 /* ProcessingView.swift in Sources */,
DBCA388F225E8BAA00CD4137 /* PickerView.swift in Sources */,
DBCA387E225E8BAA00CD4137 /* GenericCell.swift in Sources */,
DBCA386A225E8BAA00CD4137 /* SelectTransferMethodTypeCell.swift in Sources */,
DBCA388E225E8BAA00CD4137 /* AbstractWidget.swift in Sources */,
Expand All @@ -991,8 +989,10 @@
DBCA3889225E8BAA00CD4137 /* ExpiryDateWidget.swift in Sources */,
DBCA3883225E8BAA00CD4137 /* Theme.swift in Sources */,
DBCA385D225E8BAA00CD4137 /* SelectTransferMethodTypeViewController.swift in Sources */,
DBCA3890225E8BAA00CD4137 /* MonthYearPicker.swift in Sources */,
4A12653C2280B02900C0F59E /* DateWidget.swift in Sources */,
DBCA3890225E8BAA00CD4137 /* ExpiryDatePickerView.swift in Sources */,
DBCA3886225E8BAA00CD4137 /* IconView.swift in Sources */,
9826056822822E8A000CCA2D /* UIToolbar.swift in Sources */,
DBCA3879225E8BAA00CD4137 /* UIImage.swift in Sources */,
DBCA3872225E8BAA00CD4137 /* UIBarButtonItem.swift in Sources */,
DBCA388A225E8BAA00CD4137 /* SelectionWidget.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,47 +18,24 @@

import UIKit

protocol ToolbarPickerViewDelegate: class {
func didTapDone(_ handler: (_ textField: UITextField) -> Void)
}

class PickerView: UIPickerView {
public private(set) var toolbar: UIToolbar!
public weak var toolBarDelegate: ToolbarPickerViewDelegate?
var tapDoneHandler: ((_ textField: UITextField) -> Void)!

override init(frame: CGRect) {
super.init(frame: frame)
setUpToolBar()
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setUpToolBar()
}

/// Add a tool bar containing a done button on top of the picker
private func setUpToolBar() {
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = Theme.themeColor
toolBar.sizeToFit()
extension UIToolbar {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jsaini-hw Do we really need to extend all the toolbars across the app instead of customization for our particular needs?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oleksii-lubianyi-epam We are not extending any existing method but giving an opportunity to extend all the toolbars if required using this method

func setupToolBar(target: UIView, action: Selector?) {
let toolbar = self
toolbar.barStyle = UIBarStyle.default
toolbar.isTranslucent = true
toolbar.tintColor = Theme.themeColor
toolbar.sizeToFit()

let doneButton = UIBarButtonItem(title: "done_button_label".localized(),
style: .plain,
target: self,
action: #selector(self.doneTapped))
target: target,
action: action)
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)

toolBar.setItems([spaceButton, doneButton], animated: true)
toolBar.isUserInteractionEnabled = true
toolBar.accessibilityIdentifier = "Toolbar"
self.toolbar = toolBar
}
toolbar.setItems([spaceButton, doneButton], animated: true)
toolbar.isUserInteractionEnabled = true

@objc
func doneTapped() {
toolBarDelegate?.didTapDone(tapDoneHandler)
doneButton.accessibilityIdentifier = "DoneButtonAccessibilityIdentifier"
toolbar.accessibilityIdentifier = "ToolbarAccessibilityIdentifier"
}
}
4 changes: 4 additions & 0 deletions Sources/Localization/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
"information_header"="Transfer method information";
"account_information_title" = "Account Information";

// expiry date format - arguments order is %1$-month, %2$-year(two last digits)
"expiry_date_format" = "%1$02d/%2$02d";
"date_format" = "yyyy-MM-dd";

// Account types
"CHECKING" = "Checking";
"SAVINGS" = "Savings";
Expand Down
70 changes: 70 additions & 0 deletions Sources/View/Widget/DateWidget.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//
// Copyright 2018 - Present Hyperwallet
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge, publish, distribute,
// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

import HyperwalletSDK

/// Represents the date input widget.
final class DateWidget: TextWidget {
var toolbar = UIToolbar()
private var datePicker: UIDatePicker!

private static var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "date_format".localized()
return formatter
}()

override func setupLayout(field: HyperwalletField) {
super.setupLayout(field: field)
setupDatePicker()
toolbar.setupToolBar(target: self, action: #selector(self.doneButtonTapped))
setupTextField()
}

private func setupDatePicker() {
datePicker = UIDatePicker(frame: .zero)
datePicker.datePickerMode = .date
datePicker.accessibilityIdentifier = "DateWidgetPickerAccessibilityIdentifier"
}

private func setupTextField() {
textField.inputView = datePicker
textField.inputAccessoryView = toolbar
textField.delegate = self
}

@objc
private func updateTextField() {
textField.text = DateWidget.dateFormatter.string(from: datePicker.date)
}

@objc
private func doneButtonTapped() {
updateTextField()
textField.resignFirstResponder()
}

override func textFieldDidBeginEditing(_ textField: UITextField) {
super.textFieldDidBeginEditing(textField)
if let dateFromText = DateWidget.dateFormatter.date(from: value()) {
datePicker.date = dateFromText
} else {
datePicker.date = Date()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,54 +18,44 @@

import UIKit

class MonthYearPickerView: PickerView, UIPickerViewDelegate, UIPickerViewDataSource {
static let loop = 5
final class ExpiryDatePickerView: UIPickerView, UIPickerViewDelegate, UIPickerViewDataSource {
var month: Int!
var year: Int!

ymoskovko-epam marked this conversation as resolved.
Show resolved Hide resolved
var month = Calendar.current.component(.month, from: Date())
var year = Calendar.current.component(.year, from: Date())

var months = [String]()
var years = [Int]()

var dateSelectedHandler: ((_ month: Int, _ year: Int) -> Void)?
private var months = [String]()
private var years = [Int]()

override init(frame: CGRect) {
super.init(frame: frame)
self.setUp()
self.setup()
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setUp()
self.setup()
}

func setUp() {
setUpMonth()
setUpYear(add: 10)
private func setup() {
let currentDate = Date()
let currentCalendar = Calendar.current
month = currentCalendar.component(.month, from: currentDate)
year = currentCalendar.component(.year, from: currentDate)

setupMonths()
setupYears(add: 10)

self.tapDoneHandler = setUpTapHandler()
self.delegate = self
self.dataSource = self

// pick current month as default month for the picker and place the selected month in the center of picker
self.selectRow((MonthYearPickerView.loop / 2) * months.count + month - 1, inComponent: 0, animated: false)
}

private func setUpTapHandler() -> (_ textField: UITextField) -> Void {
return {
(textField) in
let month = self.month
let year = String(describing: self.year).suffix(startAt: 2)

textField.text = String(format: "%02d/%@", month, year) // Sample format 03/21
}
self.selectRow(month - 1, inComponent: 0, animated: false)
}

private func setUpMonth() {
private func setupMonths() {
months = DateFormatter().monthSymbols.map({ $0.capitalized })
}

private func setUpYear(add: Int) {
private func setupYears(add: Int) {
years = Array(year...year + add)
}

Expand All @@ -91,7 +81,7 @@ class MonthYearPickerView: PickerView, UIPickerViewDelegate, UIPickerViewDataSou
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
switch component {
case 0:
return months.count * MonthYearPickerView.loop
return months.count

case 1:
return years.count
Expand All @@ -102,7 +92,7 @@ class MonthYearPickerView: PickerView, UIPickerViewDelegate, UIPickerViewDataSou
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
month = selectedRow(inComponent: 0) % months.count + 1
month = selectedRow(inComponent: 0) + 1
year = years[selectedRow(inComponent: 1)]
}
}
Loading