Adding Done/Next to numberPad - ios

I have read the post on how to create these buttons but they use a tag system to identify the textFields. I am using a prototype cell to create my textFields
func addDoneButtonOnKeyboard(_ hasNextBtn: Bool = false) -> UIView {
let doneToolbar: UIToolbar = UIToolbar(frame: CGRect(x: 0, y: 163, width: 106, height: 53))
doneToolbar.barStyle = UIBarStyle.default
let flexSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let done: UIBarButtonItem = UIBarButtonItem(title: "Done",
style: UIBarButtonItemStyle.done,
target: self,
action: #selector(doneAction))
let next: UIBarButtonItem = UIBarButtonItem(title: "Next",
style: .plain,
target: self,
action: #selector(nextAction))
var items = [UIBarButtonItem]()
items.append(flexSpace)
if hasNextBtn {
items.append(next)
} else {
items.append(done)
}
doneToolbar.items = items
doneToolbar.sizeToFit()
return doneToolbar
}
#objc func doneAction() {
self.view.endEditing(true)
}
#objc func nextAction(_ textField: UITextField) -> Bool {
let indexPath = IndexPath(row: index, section: 2)
// if textField.returnKeyType == .next {
if textField.inputAccessoryView == next as! UIView? {
guard let table = tableView, let ip = indexPath,
let cell = table.cellForRow(at: IndexPath(row: ip.row + 1, section: ip.section)) as? FormFieldTableViewCell
else { return true }
return cell.becomeFirstResponder()
}
return true
}

You can change Change button Type on Keyboard as follows,
// Assign in your cellForRowAtIndexPath method
yourTextField.returnKeyType = .Next
txtField.returnKeyType = .Done
txtField.returnKeyType = .Go
And Many more from below,
case Default
case Go
case Google
case Join
case Next
case Route
case Search
case Send
case Yahoo
case Done
case EmergencyCall
You can after handle action as desire in UITextFieldDelegate.

Related

How to implement the 'datepicker' correctly using swift when adding the multiple entries to server?

**Aim: ** To show latest apple calendar type of date picker(inline) in app when user wants to select the date.How it should look
Scenario:**
The user can input multiple entries (maximum 3) the exercise(suryanamaskar). These multiple entries has two functions
1.date-picker and
2.number entry(number of 'suryanamaskar')
When user clicks on the date-picker button. the date picker shows up (.inline). Each entry fetches the post API call that saves the 'suryanamaskar' count entry on server.
What is the issue: I tried to implement the date-picker using and few UI frames : .inline
I replaced the date-picker completely and implemented ".wheels" that works fine.
The datepicker is show up correctly first time. But when the user tried to add other entry or press the date entry buttton . The datepicker gets cut and is not properly visible. This is how it looks when user clicks on datepicker button second time.
What my code looks like:
import UIKit
import SwiftyJSON
import Alamofire
struct surynamaskarStruct {
var date: String
var count: String
}
class AddSuryaNamskarCountVC: UIViewController, UITextFieldDelegate {
var surynamaskarData: [surynamaskarStruct] = [
surynamaskarStruct(date: "Date", count: "0"),
surynamaskarStruct(date: "Date", count: "0"),
surynamaskarStruct(date: "Date", count: "0")
]
#IBOutlet var tableView: UITableView!
#IBOutlet weak var lblMember: UILabel!
#IBOutlet weak var btnMember: UIButton!
#IBOutlet weak var familyMemberHeightConstraint: NSLayoutConstraint!
var viewPicker : UIView!
let datePicker = UIDatePicker()
var btnIndex : Int!
var strMemberId : String!
var dicMember = [[String:Any]]()
lazy var loader : UIActivityIndicatorView = {
let indicator = UIActivityIndicatorView(style: .large)
indicator.hidesWhenStopped = true
return indicator
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if self.dicMember.count > 0 {
self.strMemberId = self.dicMember[0]["id"] as? String
self.lblMember.text = self.dicMember[0]["name"] as? String
self.familyMemberHeightConstraint.constant = 90
} else {
self.familyMemberHeightConstraint.constant = 0
}
view.addSubview(loader)
loader.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
loader.centerXAnchor.constraint(equalTo: view.centerXAnchor),
loader.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
override func viewWillAppear(_ animated: Bool) {
navigationBarDesign(txt_title: "Record Suryanamskar", showbtn: "back")
}
#IBAction func onMemberClick(_ sender: UIButton) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "PickerTableViewWithSearchViewController") as! PickerTableViewWithSearchViewController
vc.selectedItemCompletion = {dict in
self.lblMember.text = dict["name"] as? String
self.strMemberId = dict["id"] as? String
}
vc.dataSource = dicMember
vc.strNavigationTitle = "Family Member"
vc.modalPresentationStyle = UIModalPresentationStyle.fullScreen
self.present(vc, animated: true, completion: nil)
}
#IBAction func onCancelClick(_ sender: UIButton) {
self.dismiss(animated: true)
}
#IBAction func onSaveClick(_ sender: UIButton) {
var arrData = [[String:Any]]()
for arr in surynamaskarData {
if arr.date != "Date" && arr.count != "0" {
var dict = [String : Any]()
dict["date"] = arr.date
dict["count"] = arr.count
arrData.append(dict)
}
}
if arrData.count > 0 {
self.saveSuryaNamskarCountDataAPI(arrData)
////static controller to directly update the suryanamaskar chart instead of going back and then getting updated suryanamaskar
let alertController = UIAlertController(title:APP.title, message: "Suryanamaskar has been saved successfully!", preferredStyle:.alert)
let Action = UIAlertAction.init(title: "Ok", style: .default) { (UIAlertAction) in
// Write Your code Here
let vc = self.storyboard?.instantiateViewController(withIdentifier: "SuryaNamskarVC") as! SuryaNamskarVC
vc.modalPresentationStyle = UIModalPresentationStyle.fullScreen
// vc.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
self.present(vc, animated: true, completion: nil)
}
alertController.addAction(Action)
self.present(alertController, animated: true, completion: nil)
//// Till here for alert controller. if not implemented, updated suryanamaskar will happen only once user goes back and comes back to suryanamaskarVC
}
// else {
// showAlert(title: APP.title, message: "Please select date and count before Save")
// }
}
// MARK: - DatePicker functions
func showDatePicker(){
viewPicker = UIView(frame: CGRect(x: 0.0, y: self.view.frame.height - 380, width: self.view.frame.width, height: 380))
viewPicker.backgroundColor = UIColor.white
viewPicker.clipsToBounds = true
// Posiiton date picket within a view
datePicker.frame = CGRect(x: 10, y: 50, width: self.view.frame.width, height: 200)
datePicker.datePickerMode = .date
datePicker.minimumDate = Calendar.current.date(byAdding: .month, value: -2, to: Date())
datePicker.maximumDate = Calendar.current.date(byAdding: .year, value: 0, to: Date())
datePicker.backgroundColor = UIColor.white
if #available(iOS 14.0, *) {
datePicker.preferredDatePickerStyle = .inline
} else {
if #available(iOS 13.4, *) {
datePicker.preferredDatePickerStyle = .wheels
} else {
// Fallback on earlier versions
}
// Fallback on earlier versions
}
// Add an event to call onDidChangeDate function when value is changed.
datePicker.addTarget(self, action: #selector(AddMemberStep1VC.datePickerValueChanged(_:)), for: .valueChanged)
datePicker.center.x = self.view.center.x
//ToolBar
var toolbar = UIToolbar();
toolbar.sizeToFit()
toolbar = UIToolbar(frame: CGRect(x: 0.0, y: 0.0, width: self.view.frame.width, height: 50))
let doneButton = UIBarButtonItem(title: "done".localized, style: .plain, target: self, action: #selector(donedatePicker));
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "cancel".localized, style: .plain, target: self, action: #selector(cancelDatePicker));
toolbar.setItems([doneButton,spaceButton,cancelButton], animated: false)
// txtDate.inputAccessoryView = toolbar
// txtDate.inputView = datePicker
self.viewPicker.addSubview(toolbar)
self.viewPicker.addSubview(datePicker)
self.viewPicker.clipsToBounds = true
self.view.addSubview(self.viewPicker)
}
#objc func datePickerValueChanged(_ sender: UIDatePicker){
// Create date formatter
let dateFormatter: DateFormatter = DateFormatter()
// Set date format
dateFormatter.dateFormat = "dd/MM/yyyy"
// Apply date format
let _: String = dateFormatter.string(from: sender.date)
// print("Selected value \(selectedDate)")
}
#objc func donedatePicker(){
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
let strDate = formatter.string(from: datePicker.date)
surynamaskarData[btnIndex].date = strDate
DispatchQueue.main.async {
self.tableView.reloadData()
}
self.viewPicker.isHidden = true
}
#objc func cancelDatePicker(){
self.viewPicker.isHidden = true
}
#objc func onAddMoreClicked() {
print("AddMore Button Pressed")
for i in surynamaskarData {
if i.date == "Date" || i.count == "0" || i.count == "" {
showAlert(title: APP.title, message: "Please select date and count before AddMore")
return
}
}
surynamaskarData.append(surynamaskarStruct(date: "Date", count: "0"))
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
#objc func onDateClick(_ sender: UIButton) {
btnIndex = sender.tag
view.endEditing(true)
if self.viewPicker == nil {
self.showDatePicker()
} else {
if self.viewPicker.isHidden == true {
self.showDatePicker()
} else {
self.viewPicker.isHidden = true
}
}
}
#objc func onDeleteClick(_ sender: UIButton) {
surynamaskarData.remove(at: sender.tag)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
func textFieldDidBeginEditing(_ textField: UITextField) {
if self.viewPicker != nil {
if self.viewPicker.isHidden == false {
self.viewPicker.isHidden = false
}
}
}
func textFieldDidEndEditing(_ textField: UITextField) {
if textField.text == "" {
textField.text = "0"
}
surynamaskarData[textField.tag].count = textField.text ?? "0"
}
func json(from object:Any) -> String? {
guard let data = try? JSONSerialization.data(withJSONObject: object, options: []) else {
return nil
}
return String(data: data, encoding: String.Encoding.utf8)
}
func saveSuryaNamskarCountDataAPI(_ data : [[String:Any]]) {
var parameters: [String: Any] = [:]
parameters["surynamaskar"] = self.json(from: data)
parameters["member_id"] = self.strMemberId // _appDelegator.dicDataProfile![0]["member_id"] as? String
print(parameters)
// APIUrl.save_suryanamaskar
//live API only
//"https://myhss.org.uk/api/v1/suryanamaskar/save_suryanamaskar_count"
loader.startAnimating()
let url = URL(string: APIUrl.save_suryanamaskar)!
AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default)
.validate()
.responseJSON { response in
self.loader.stopAnimating()
switch response.result {
case .success(let response):
print(response)
let jsonData = JSON(response)
if let status = jsonData["status"].int
{
if status == 1
{
let strMessage : String = jsonData["message"].rawValue as! String
print(strMessage)
// create the alert
let alert = UIAlertController(title: APP.title, message: strMessage, preferredStyle: UIAlertController.Style.alert)
// add an action (button)
let ok = UIAlertAction(title: "Ok".localized, style: .default, handler: { action in
DispatchQueue.main.async {
self.dismiss(animated: true)
}
})
alert.addAction(ok)
// show the alert
self.present(alert, animated: true, completion: nil)
} else {
if let strError = jsonData["message"].string {
showAlert(title: APP.title, message: strError)
}
}
}
case .failure(let error):
print(error.localizedDescription)
showAlert(title: APP.title, message: error.localizedDescription)
}
}
}
}
extension AddSuryaNamskarCountVC : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return surynamaskarData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: AddSuryaNamskarCountTVCell.cellIdentifier) as! AddSuryaNamskarCountTVCell
cell.btnDate.tag = indexPath.row
cell.btnDate.addTarget(self, action: #selector(self.onDateClick(_:)), for: .touchUpInside)
cell.btnCancel.tag = indexPath.row
cell.btnCancel.addTarget(self, action: #selector(self.onDeleteClick(_:)), for: .touchUpInside)
cell.lblDate.text = surynamaskarData[indexPath.row].date
cell.txtCount.text = surynamaskarData[indexPath.row].count
cell.txtCount.tag = indexPath.row
cell.txtCount.delegate = self
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 60.0
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let viewFooter = UIView()
viewFooter.backgroundColor = UIColor.systemGray5
let size = tableView.frame.size
let addMoreButton = UIButton()
addMoreButton.setTitle("+ Add More", for: .normal)
addMoreButton.setTitleColor(Colors.txtAppDarkColor, for: .normal)
addMoreButton.frame = CGRect(x: 0, y: 0, width: size.width, height: 50)
addMoreButton.addTarget(self, action: #selector(onAddMoreClicked), for: .touchUpInside)
viewFooter.addSubview(addMoreButton)
return viewFooter
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 50
}
}
Changing the Co-ordinates works:
Following co-orinates fixes the calender view for this issue.
func showDatePicker(){
viewPicker = UIView(frame: CGRect(x: 0.0, y: self.view.frame.height - 500, width: self.view.frame.width, height: 500))
viewPicker.backgroundColor = UIColor.white
viewPicker.clipsToBounds = true
// Posiiton date picket within a view
datePicker.frame = CGRect(x: 10, y: 50, width: self.view.frame.width, height: 500)
datePicker.datePickerMode = .date
datePicker.minimumDate = Calendar.current.date(byAdding: .month, value: -2, to: Date())
datePicker.maximumDate = Calendar.current.date(byAdding: .year, value: 0, to: Date())
datePicker.backgroundColor = UIColor.white
if #available(iOS 14.0, *) {
datePicker.preferredDatePickerStyle = .inline
} else {
if #available(iOS 13.4, *) {
datePicker.preferredDatePickerStyle = .wheels
} else {
// Fallback on earlier versions
}
// Fallback on earlier versions
}
// Add an event to call onDidChangeDate function when value is changed.
datePicker.addTarget(self, action: #selector(AddMemberStep1VC.datePickerValueChanged(_:)), for: .valueChanged)
datePicker.center.x = self.view.center.x
//ToolBar
var toolbar = UIToolbar();
toolbar.sizeToFit()
toolbar = UIToolbar(frame: CGRect(x: 0.0, y: 0.0, width: self.view.frame.width, height: 50))
let doneButton = UIBarButtonItem(title: "done".localized, style: .plain, target: self, action: #selector(donedatePicker));
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "cancel".localized, style: .plain, target: self, action: #selector(cancelDatePicker));
toolbar.setItems([doneButton,spaceButton,cancelButton], animated: false)
self.viewPicker.addSubview(toolbar)
self.viewPicker.addSubview(datePicker)
self.viewPicker.clipsToBounds = true
self.view.addSubview(self.viewPicker)
}

Why is the toolbar not showing when I tap on the textfield?

I would like to implement a done toolbar above the numpad keyboard when the textfield is tapped however the toolbar is not showing up for some reason.
The following code sample has been used:
extension UITextField{
#IBInspectable var doneAccessory: Bool{
get{
return self.doneAccessory
}
set (hasDone) {
if hasDone{
addDoneButtonOnKeyboard()
}
}
}
func addDoneButtonOnKeyboard()
{
let doneToolbar: UIToolbar = UIToolbar(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
doneToolbar.barStyle = .default
let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(self.doneButtonAction))
let items = [flexSpace, done]
doneToolbar.items = items
doneToolbar.sizeToFit()
self.inputAccessoryView = doneToolbar
}
#objc func doneButtonAction()
{
self.resignFirstResponder()
}
}
Make sure in your storyboard, TextField's property inspector doneAccessory property is set to ON
and O/P looks like

How to edit accessory view of keyboard shown from WKWebView?

I am using a WKWebView in my Swift app to present some textfields.
I set some appearance properties to match a specific design, in this case its background has to be blue.
But when the keyboard is triggered by the WKWebView, it does something with the appearance properties and shows the keyboard toolbar in a pale light appearance of my color, do you know why?
The only appearance manipulation on UIToolBar that somewhat worked is this one:
UIToolbar.appearance().backgroundColor = .blue
This is my problem:
This is my goal:
Found a way, ended up to swizzle UIToolbars. Hopefully everything is there, but you would get an idea. Swift 4:
class YourController: UIViewController {
#IBOutlet weak var webView: PWebView!
var toolbar : UIToolbar?
func viewDidLoad() {
webView.addInputAccessoryView(toolbar: self.getToolbar(height: 44))
}
func getToolbar(height: Int) -> UIToolbar? {
let toolBar = UIToolbar()
toolBar.frame = CGRect(x: 0, y: 50, width: 320, height: height)
toolBar.barStyle = .black
toolBar.tintColor = .white
toolBar.barTintColor = UIColor.blue
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(onToolbarDoneClick(sender:)) )
let flexibleSpaceItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil )
toolBar.setItems([flexibleSpaceItem, doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
toolBar.sizeToFit()
return toolBar
}
#objc func onToolbarDoneClick(sender: UIBarButtonItem) {
webView?.resignFirstResponder()
}
}
var ToolbarHandle: UInt8 = 0
extension WKWebView {
func addInputAccessoryView(toolbar: UIView?) {
guard let toolbar = toolbar else {return}
objc_setAssociatedObject(self, &ToolbarHandle, toolbar, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
var candidateView: UIView? = nil
for view in self.scrollView.subviews {
let description : String = String(describing: type(of: view))
if description.hasPrefix("WKContent") {
candidateView = view
break
}
}
guard let targetView = candidateView else {return}
let newClass: AnyClass? = classWithCustomAccessoryView(targetView: targetView)
guard let targetNewClass = newClass else {return}
object_setClass(targetView, targetNewClass)
}
func classWithCustomAccessoryView(targetView: UIView) -> AnyClass? {
guard let _ = targetView.superclass else {return nil}
let customInputAccesoryViewClassName = "_CustomInputAccessoryView"
var newClass: AnyClass? = NSClassFromString(customInputAccesoryViewClassName)
if newClass == nil {
newClass = objc_allocateClassPair(object_getClass(targetView), customInputAccesoryViewClassName, 0)
} else {
return newClass
}
let newMethod = class_getInstanceMethod(WKWebView.self, #selector(WKWebView.getCustomInputAccessoryView))
class_addMethod(newClass.self, #selector(getter: WKWebView.inputAccessoryView), method_getImplementation(newMethod!), method_getTypeEncoding(newMethod!))
objc_registerClassPair(newClass!)
return newClass
}
#objc func getCustomInputAccessoryView() -> UIView? {
var superWebView: UIView? = self
while (superWebView != nil) && !(superWebView is WKWebView) {
superWebView = superWebView?.superview
}
guard let webView = superWebView else {return nil}
let customInputAccessory = objc_getAssociatedObject(webView, &ToolbarHandle)
return customInputAccessory as? UIView
}
}
private var keyBordView: UIView?
override func viewDidLoad() {
super.viewDidLoad()
let webView = WKWebView.init(frame: view.bounds)
webView.loadHTMLString("<html><body><div contenteditable='true'></div></body></html>", baseURL: nil)
view.addSubview(webView)
for subview in webView.scrollView.subviews {
if subview.classForCoder.description() == "WKContentView" {
keyBordView = subview
}
}
NotificationCenter.default.addObserver(self, selector: #selector(keyboardShow), name: .UIKeyboardDidShow, object: nil)
// Do any additional setup after loading the view.
}
#objc private func keyboardShow() {
let keyboardToolbar = UIToolbar()
keyboardToolbar.backgroundColor = UIColor.blue
keyboardToolbar.sizeToFit()
let flexBarButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneBarButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.dismissKeyBord))
keyboardToolbar.items = [flexBarButton, doneBarButton]
keyBordView = keyboardToolbar
}

How to do number keypad with done button in Swift 2.0?

I've tried lots of numeric keyboard with done button, it's not found a correct answer in SWIFT 2.0.
You can add done button above keyboard using toolbar
override func viewDidLoad() {
super.viewDidLoad()
let tooBar: UIToolbar = UIToolbar()
tooBar.barStyle = UIBarStyle.BlackTranslucent
tooBar.items=[
UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil),
UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: "donePressed")]
tooBar.sizeToFit()
yourTextFeild.inputAccessoryView = tooBar
}
func donePressed () {
yourTextFeild.resignFirstResponder()
}
It will look like this
Without toolbar, I'd added the done button in the Return key place itself by the following steps,
Create a custom Return button as below
let mobilePadNextButton = UIButton(type: UIButtonType.custom)
In viewdidload, design it. Here I'm designing Next button as I need Next instead of Done.
mobilePadNextButton.setTitle("Next", for: UIControlState())//Set Done here
mobilePadNextButton.setTitleColor(UIColor.black, for: UIControlState())
mobilePadNextButton.frame = CGRect(x: 0, y: 163, width: 106, height: 53)
mobilePadNextButton.adjustsImageWhenHighlighted = false
mobilePadNextButton.addTarget(self, action: #selector(self.mobilePadNextAction(_:)), for: UIControlEvents.touchUpInside)
Add Keyboad notification
func textFieldDidBeginEditing(_ textField: UITextField) {
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
}
func keyboardWillShow(notification:NSNotification){
if mobileNoTxtFld.isFirstResponder
{
DispatchQueue.main.async { () -> Void in
self.mobilePadNextButton.isHidden = false
let keyBoardWindow = UIApplication.shared.windows.last
self.mobilePadNextButton.frame = CGRect(x: 0, y: (keyBoardWindow?.frame.size.height)!-53, width: 106, height: 53)
keyBoardWindow?.addSubview(self.mobilePadNextButton)
keyBoardWindow?.bringSubview(toFront: self.mobilePadNextButton)
UIView.animate(withDuration: (((notification.userInfo! as NSDictionary).object(forKey: UIKeyboardAnimationCurveUserInfoKey) as AnyObject).doubleValue)!, delay: 0, options: UIViewAnimationOptions.curveEaseIn, animations: { () -> Void in
self.view.frame = self.view.frame.offsetBy(dx: 0, dy: 0)
}, completion: { (complete) -> Void in
print("Complete")
})
}
}
else
{
self.mobilePadNextButton.isHidden = true
}
}
Here, you can do the done actions
func mobilePadNextAction(_ sender : UIButton){
//Click action
}
The UI will looks like below,
I referred this Git Code

Add buttons to UIPickerView - Swift 1.2

I would like to add two UIButtons in the UIPickerView (on top of it). Please take a look at the Cancel and Done buttons in this image:
How can I do it?
I have solved this, answer in Swift:
var pickerView = UIPickerView(frame: CGRectMake(0, 200, view.frame.width, 300))
pickerView.backgroundColor = .whiteColor()
pickerView.showsSelectionIndicator = true
var toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.Default
toolBar.translucent = true
toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Bordered, target: self, action: "donePicker")
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Bordered, target: self, action: "canclePicker")
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.userInteractionEnabled = true
textField.inputView = pickerView
textField.inputAccessoryView = toolBar
See Mine. I have Collection View and UIPicker to select photo Folders.
//MARK:- SHOW PHOTO FOLDER BUTTON METHOD
#IBAction func photoFolderListButtonClicked(sender: UIButton) {
self.navigationItem.setHidesBackButton(true, animated: true)
//Making PickerView of Competitors
let DEVICE_SCREEN_WIDTH = UIScreen.mainScreen().bounds.size.width
photoFolderListPicker.frame = CGRectMake(0.0, 44.0, DEVICE_SCREEN_WIDTH, 260)
photoFolderListPicker.dataSource = self
photoFolderListPicker.delegate = self
photoFolderListPicker.showsSelectionIndicator = true;
photoFolderListPicker.backgroundColor = UIColor.whiteColor()
let pickerDateToolbar = UIToolbar(frame: CGRectMake(0, 0, DEVICE_SCREEN_WIDTH, 44))
pickerDateToolbar.barStyle = UIBarStyle.Black
pickerDateToolbar.barTintColor = UIColor.blackColor()
pickerDateToolbar.translucent = true
//Cancel button on photoFolderListPicker
let barItems = NSMutableArray()
let labelCancel = UILabel()
labelCancel.text = " Cancel"
let titleCancel = UIBarButtonItem(title: labelCancel.text, style: UIBarButtonItemStyle.Plain, target: self, action: Selector("cancelPickerSelectionButtonClicked:"))
titleCancel.tintColor = UIColor.whiteColor()
barItems.addObject(titleCancel)
var flexSpace: UIBarButtonItem
flexSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil)
barItems.addObject(flexSpace)
//Done Button on photoFolderListPicker
let doneBtn = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Done, target: self, action: Selector("photoFolderSelectionDone:"))
barItems.addObject(doneBtn)
doneBtn.tintColor = UIColor.whiteColor()
pickerDateToolbar.setItems(barItems as [AnyObject] as? [UIBarButtonItem], animated: true)
actionView.addSubview(pickerDateToolbar)
actionView.addSubview(photoFolderListPicker)
if (window != nil) {
window!.addSubview(actionView)
}
else {
self.view.addSubview(actionView)
}
UIView.animateWithDuration(0.2, animations: {
self.actionView.frame = CGRectMake(0, UIScreen.mainScreen().bounds.size.height - 250.0, UIScreen.mainScreen().bounds.size.width, 250)
})
}
//MARK:- PICKERVIEW DELEGATE METHODS
func pickerView(_pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return model.documentFolders.count
}
func numberOfComponentsInPickerView(_pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return model.documentFolders[row].value
}
//MARK:- PICKERVIEW BUTTON METHODS
func cancelPickerSelectionButtonClicked(sender: UIBarButtonItem) {
self.navigationItem.setHidesBackButton(false, animated: true)
UIView.animateWithDuration(0.2, animations: {
self.actionView.frame = CGRectMake(0, UIScreen.mainScreen().bounds.size.height, UIScreen.mainScreen().bounds.size.width, 210.0)
}, completion: { _ in
for obj: AnyObject in self.actionView.subviews {
if let view = obj as? UIView
{
view.removeFromSuperview()
}
}
})
photoFolderListButton.setTitle(" "+"Select Folder", forState: UIControlState.Normal)
}
func photoFolderSelectionDone(sender: UIBarButtonItem) {
uploadedPhotoFolderName?.isEmpty
loadedFromPageSection = "fromPhotoFolderSelectionDone"
self.disableScoutDetailUserInterfaceElementsDutingApiCall()
//setting selectedPhotoFolderItem and selectedPhotoFolderItemId
let myRow = photoFolderListPicker.selectedRowInComponent(0)
selectedPhotoFolderItem = model.documentFolders[myRow].value!
selectedPhotoFolderItemId = Int(model.documentFolders[myRow].key!)
UIView.animateWithDuration(0.2, animations: {
self.actionView.frame = CGRectMake(0, UIScreen.mainScreen().bounds.size.height, UIScreen.mainScreen().bounds.size.width, 260.0)
}, completion: { _ in
for obj: AnyObject in self.actionView.subviews {
if let view = obj as? UIView
{
view.removeFromSuperview()
}
}
})
photoFolderListButton.setTitle(" "+(selectedPhotoFolderItem as? String)!, forState: UIControlState.Normal)
self.view.makeToastActivityWithMessage(message: "Fetching")
//Delegate is added to class after popViewControllerAnimated(true) called
model.delegate = self
//API CALL - Fetching Photos
AppController().fetchPropertyPhotosGallery(hbId, propertyId: scoutPropertyId, fileTypeId: selectedPhotoFolderItemId)
}
Here is how I do it in ObjC to add a picker popup with buttons to a text field. Should be simple enough to translate into swift. Basically you create the picker and assign it to the text inputView. Then you create a toolbar which you assign to the text inputAccessoryView which sits on top of the inputView when it pops up.
self.manufacturerPicker = [[UIPickerView alloc] initWithFrame:CGRectZero];
self.manufacturerPicker.delegate = self;
self.manufacturerPicker.dataSource = self;
[self.manufacturerPicker setShowsSelectionIndicator:YES];
self.filterByManufacturerTextField.inputView = self.manufacturerPicker;
UIToolbar *manufacturerPickerToolbar=[[UIToolbar alloc] init];
manufacturerPickerToolbar.barStyle = UIBarStyleBlack;
manufacturerPickerToolbar.translucent = YES;
manufacturerPickerToolbar.tintColor = nil;
[manufacturerPickerToolbar sizeToFit];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleBordered target:self
action:#selector(manufacturerPickerDoneClicked:)];
UIBarButtonItem *spacerButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:#"Cancel"
style:UIBarButtonItemStyleBordered target:self
action:#selector(manufacturerPickerCancelClicked:)];
[manufacturerPickerToolbar setItems:#[cancelButton,spacerButton,doneButton]];
self.filterByManufacturerTextField.inputAccessoryView = manufacturerPickerToolbar;
Updated for when you have no UITextField as the start point:
If you want to launch a picker from a cell as if it was a text field picker, I believe you have to make your UITableViewCell implement the process of becoming the first responder.
To do this I think the process is to implement the UIResponder protocol in your cell.
1) override canBecomeFirstResponder and return YES.
2) override inputView property getter. In this code return your UIPickerView.
ยง3) override inputAccessoryView property getter. In this code return your UIToolbar.
Now in your cell when you select the cell, make the cell become the first responder by calling [self becomeFirstResponder];.
This should then bring the picker and toolbar up properly I think. There may be more to this.
When cancel or done, drop it using [self resignFirstResponder];
Not done this before, but I think this is the general process.
Option 2 (Cheat):
Sometimes cheating is easier. Add a hidden UITextField at the back of your cell or add one which is 0 width. Set its inputView and inputAccessoryView as per the original suggestion.
Then when you select the cell simply make the UITextField the first responder using [self.<your text field property> becomeFirstResponder];
This should give you the same result via the back door.

Resources