Dropdown list in UICollectionview cell - ios

I am developing a TODOList(iOS application) but there is a problem i.e. how can I add dropdown list is uicollectionview cell.
Means when view did load, collection view loaded, there should be a dropdown in every single cell

There's no any inbuilt dropdown functionality in iOS but you can do it by using UITableView or by using 3rd party library.
I suggest you to try this. DropDown
define this globally.
let dropDown = DropDown()
If you want to customise dropDown you can use this.
func customizeDropDown() {
DropDown.appearance().cellHeight = 40
DropDown.appearance().backgroundColor = UIColor.white
DropDown.appearance().selectionBackgroundColor = Colors.purpleColor
DropDown.appearance().cornerRadius = 5
DropDown.appearance().textColor = Colors.NavTitleColor
DropDown.appearance().shadowColor = (UIColor.init(hexString: "1AD691")?.withAlphaComponent(0.0))!
DropDown.appearance().shadowOpacity = 0.9
DropDown.appearance().shadowRadius = 0
DropDown.appearance().animationduration = 0.25
}
In cellForItemAt you need to add action on your dropdown button like this.
cell.btnDropdown.tag = indexPath.item
cell.btnDropdown.addTarget(self, action: #selector(btnDropDownTapped), for: .touchUpInside)
Once you tapped on any button from UICollectionViewCell below method will call where you need to pass anchorView.
#IBAction func btnDropDownTapped(_ sender: UIButton) {
self.dropDown.anchorView = sender // The view to which the drop down will appear on
self.dropDown.bottomOffset = CGPoint(x: 0, y: sender.bounds.height) //Top of drop down will be below the anchorView
self.dropDown.dataSource = ["First", "Last", "Second", "Third"] // Static array you need to change as per your requirement
self.dropDown.selectionAction = { [unowned self] (index, item) in
print(item) // **NOTE: I AM JUST PRINTING DROPDOWN SELECTED VALUE HERE, YOU NEED TO GET `UICollectionViewCell` HERE YOU NEED TO SET VALUE INSIDE CELL LABEL OR YOU CAN SET SELECTED DROPDOWN VALUE IN YOUR MODEL AND RELOAD COLLECTIONVIEW**
self.collectionView.reloadData()
}
self.dropDown.show()
}
If you have UITextField in your UICollectionViewCell then you can try this code inside textFieldShouldBeginEditing delegate.
NOTE: I AM JUST PRINTING DROPDOWN SELECTED VALUE HERE, YOU NEED TO GET UICollectionViewCell HERE YOU NEED TO SET VALUE INSIDE CELL LABEL OR YOU CAN SET SELECTED DROPDOWN VALUE IN YOUR MODEL AND RELOAD COLLECTIONVIEW

iOS doesn't have any native control for drop downs.You can use pickers instead.
See like below :
Here is the code to add pickerView.
let picker: UIPickerView
picker = UIPickerView(frame: CGRectMake(0, 200, view.frame.width, 300))
picker.backgroundColor = .whiteColor()
picker.showsSelectionIndicator = true
picker.delegate = self
picker.dataSource = self
let 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.Plain, target: self, action: "donePicker")
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action: "donePicker")
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.userInteractionEnabled = true
textField1.inputView = picker
textField1.inputAccessoryView = toolBar
There are lots of libraries added to github for cool picker controls:
Actionsheet PickerView
Selectionmenu

Please follow steps to perform your operation
Add UITableView in UICollectionViewCell.
Make the hidden property of UITableView to true
collectionViewCell.dropDownTableView.isHidden=true
When the user select option to display dropdown, reload UITableView data and set hidden property of UITableView to false.
How to add UITableView to UICollectionViewCell

Related

Toolbar with "Previous" and "Next" for keyboard

I've been trying to implement this toolbar, where only the 'Next' button is enabled when the top textField is the firstResponder and only the 'Previous' button is enabled when the bottom textField is the firstResponder.
It kind of works, but i need to execute my own code by accessing previous, next and done buttons action methods in other classes(like delegates)
Thanks in advance for your suggestions..
extension UIViewController {
func addInputAccessoryForTextFields(textFields: [UITextField], dismissable: Bool = true, previousNextable: Bool = false) {
for (index, textField) in textFields.enumerated() {
let toolbar: UIToolbar = UIToolbar()
toolbar.sizeToFit()
var items = [UIBarButtonItem]()
if previousNextable {
let previousButton = UIBarButtonItem(image: UIImage(named: "Backward Arrow"), style: .plain, target: nil, action: nil)
previousButton.width = 30
if textField == textFields.first {
previousButton.isEnabled = false
} else {
previousButton.target = textFields[index - 1]
previousButton.action = #selector(UITextField.becomeFirstResponder)
}
let nextButton = UIBarButtonItem(image: UIImage(named: "Forward Arrow"), style: .plain, target: nil, action: nil)
nextButton.width = 30
if textField == textFields.last {
nextButton.isEnabled = false
} else {
nextButton.target = textFields[index + 1]
nextButton.action = #selector(UITextField.becomeFirstResponder)
}
items.append(contentsOf: [previousButton, nextButton])
}
let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: view, action: #selector(UIView.endEditing))
items.append(contentsOf: [spacer, doneButton])
toolbar.setItems(items, animated: false)
textField.inputAccessoryView = toolbar
}
}
}
I am calling this from other class as :
let field1 = UITextField()
let field2 = UITextField()
addInputAccessoryForTextFields([field1, field2], dismissable: true, previousNextable: true)
Although I'm not 100% convinced I understand your question, here goes:
From other classes, you want to call the actions of your buttons, but your actions are set to UITextField.becomeFirstResponder and UIView.endEditing.
Rather than call these methods directly, create your own methods the actions should call, and put these calls into those methods.
In addInputAccessoryForTextFields(...) change the previousButton's target and action to:
previousButton.target = self
previousButton.action = #selector(handlePreviousButton)
Now add the new method:
#objc func handlePreviousButton()
{
// you'll need to associate the previous button to a specific text field
// and hang onto that association in your class, such as in a property named textFieldRelatedToPreviousButton.
self.textFieldRelatedToPreviousButton.becomeFirstResponder()
}
Now you can call handlePreviousButton() directly from elsewhere in your class, if you wish, or even from other classes.
Update
I just noticed you're extending UIViewController. So you can't add storage by adding a property. You can add storage via objc_setAssociatedObject and then get it via objc_getAssociatedObject, however, to get around this. See this SO or this SO for details on that. So you can, for example, "attach" the textField to your previousButton so that you can access it via the handlePreviousButton() method you add to your extension. And you can pass in the previousButton as a parameter (the sender) to handlePreviousButton() too.
Update 2
Another approach to consider is to use the button's tag property to store the tag value of the related textField. (i.e. each button and its related textField would have the same tag value). So in handlePreviousButton(sender:UIBarButtonItem) you loop through all the UITextField children of your self.view and locate the one whose tag matches sender.tag . Then you can do what you need to that UITextField.

iOS: Eureka forms. How to change tint on Picker from PickerInputRow

Scope
iOS: 10.0
Eureka: 3.0
How to configure properties of the presented view on eg: MultipleSelectorRow<T>?
Code
From the Example project, here's one MultipleSelectorRow
<<< MultipleSelectorRow<Emoji>() {
$0.title = "MultipleSelectorRow"
$0.options = [💁🏻, 🍐, 👦🏼, 🐗, 🐼, 🐻]
$0.value = [👦🏼, 🍐, 🐗]
}.onPresent { from, to in
to.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: from, action: #selector(RowsExampleViewController.multipleSelectorDone(_:)))
}.cellSetup { cell, row in
cell.tintColor = .orange
}
This code produces a selector view where the tint is default, rather than whatever the tint can be setup for the Row's cell itself (in this case, .orange):
The solution is to configure the presented VC in the onPresent callback. There are more things that can be configured, just need to dive in to the classes.
Configuration
Simply define selectableRowCellSetup in a similar way to [cellSetup][1]
...
.onPresent { from, to in
to.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: from, action: #selector(RowsExampleViewController.multipleSelectorDone(_:)))
to.selectableRowCellSetup = { cell, row in
cell.tintColor = .red
}
}
...
Result

Swift strange back button text in iphone plus

Please take a look at my screenshot, the blue "Back" text always show on iphone plus (6s plus, 7 plus for both simulator and real device) . It does not show on smaller screen iphone. I tried lot of way to hide/change it from present/previous controller but no luck.
So why does it work on smaller iphone but not the plus one ?
Can anyone help me:(. Thanks.
Here is the code:
#IBAction func filter(_ sender: Any) {
let view:FilterViewController = self.storyboard?.instantiateViewController(withIdentifier: "FilterViewController") as! FilterViewController
view.superVC = self
view.currentFilter = currentFilter
self.setLeftCloseNavigation()
self.navigationController?.pushViewController(view, animated: true)
}
func setLeftCloseNavigation(){
self.navigationController?.navigationBar.backgroundColor = UIColor.clear
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.layer.mask = nil
self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: "icon_close")?.withRenderingMode(.alwaysOriginal)
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "icon_close")?.withRenderingMode(.alwaysOriginal)
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
And here is the viewDidLoad in pushed controller:
override func viewDidLoad() {
super.viewDidLoad()
statusBar = UIColor.black
setResetNavigation() }
func setResetNavigation(){
navigationItem.hidesBackButton = false
let skipButton = UIButton(frame: CGRect(x: 0, y: 0, width: 70, height: 30))
skipButton.setTitle("Reset all".localized(), for: .normal)
skipButton.setTitleColor(UIColor.black, for: .normal)
skipButton.titleLabel?.font = UIFont(name: "HJGothamMedium", size: 16)
skipButton.addTarget(self, action: #selector(resetAllClicked), for: .touchUpInside)
let skip = UIBarButtonItem(customView: skipButton)
navigationItem.rightBarButtonItem = skip
}
This is the view hierarchy
Add this function :
override func viewDidAppear(_ animated: Bool) {
setResetNavigation()
self.navigationController?.navigationBar.backItem?.title = ""
}
try this
self.navigationItem.hidesBackButton = true
Or Check your storyboard it will remain
Use the below line to remove the text
navigationController?.navigationBar.topItem?.title = ""
You can inspect your UI hierarchy and if found related view then remove that view :
You can also invoke the view debugger by choosing View UI Hierarchy from the process view options menu in the debug navigator, or by choosing Debug > View Debugging > Capture View Hierarchy.
To hide the back text you need to set navigation item title to space character on the view controller that pushes the presented view controller:
self.navigationItem.title = " "
Be aware you have to set it on the previous view controller and not on top most one. Also you have to set a space character and not an empty string !!!
Also you can do this directly on storyboard
From below code you can set backButton text colour to any colour you want.You can simply set backButton to clear textColor. So, It won't be visible when it presents.
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UINavigationBar.classForCoder() as! UIAppearanceContainer.Type]).setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.clear], for: .normal)
Update: If you want to go for a different approach.Check this post How to customize the navigation back symbol and navigation back text? and accepted answer.

Previous and Next keyboard buttons using UITextfields on Static UITableView

I am using a UITableView with static cells to show a form with several UITextFields (each with a unique ordered tag from 9000 to 9015).
When i select a UITextField, the keyboard shows up with a UIToolbar that has 2 buttons, previous and next. The buttons work fine as long as the previous or next UITextField is drawn on screen, otherwise i can not select it because viewWithTag can't find the Field.
DEMO: http://s15.postimg.org/5xjsoiupl/ezgif_com_video_to_gif.gif
EDIT: I tryed using IQKeyboardManagerbut it has the same bug. If the cells are not visible then they are not detected so the next or previous arrow is disabled...
UITextFields
let numberToolbar = UIToolbar(frame: CGRectMake(0, 0, self.view.frame.size.width, 50))
numberToolbar.barStyle = UIBarStyle.Default
numberToolbar.tintColor = color_green
prev_keyboard_button = UIBarButtonItem(title: "Previous", style: UIBarButtonItemStyle.Plain, target: self, action: "keyboardPrevButtonTapped:")
next_keyboard_button = UIBarButtonItem(title: "Next", style: UIBarButtonItemStyle.Plain, target: self, action: "keyboardNextButtonTapped:")
numberToolbar.items = [
prev_keyboard_button,
next_keyboard_button,
UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil),
UIBarButtonItem(title: "OK", style: UIBarButtonItemStyle.Plain, target: self, action: "keyboardOKButtonTapped:")]
numberToolbar.sizeToFit()
// bind vars
var_input_name.inputAccessoryView = numberToolbar
var_input_name.delegate = self
var_input_name.tag = 9000 // 9000 + index (0,1,2,3,..)
...
Previous and next code:
func textFieldDidBeginEditing(textField: UITextField) {
// current tag
current_input_tag = textField.tag
// check if it is the first
prev_keyboard_button.enabled = !(textField.tag == 9000)
// check if it is the last
next_keyboard_button.enabled = !(textField.tag == 9015)
}
func keyboardPrevButtonTapped(sender: UIBarButtonItem) {
if current_input_tag > 9000 {
// find next input
if let input = self.view.viewWithTag(current_input_tag - 1) as? UITextField {
input.becomeFirstResponder()
}
}
}
func keyboardNextButtonTapped(sender: UIBarButtonItem) {
if current_input_tag < 9015 {
// find next input
if let input = self.view.viewWithTag(current_input_tag + 1) as? UITextField {
input.becomeFirstResponder()
}
}
}
Is there a way to always draw the static cells or should i be implementing this differently?
if the sell is out of the screen it will be released. It's no matter if you use static or dynamic cells. Probably views you try to find is not exists at this moment

How to dissmiss keyboard in text view in SWIFT

I am trying to dismiss keyboard in text view using accessory views with done button but keyboard is not showing done button in it.Actually i have writen my code in textViewDidBeginEditing using inputAccessoryView.Here is my code.
func textViewDidBeginEditing(textView: UITextView) {
currentTextView = textView //This is to tell the current position in text view
var indexPath:NSIndexPath = NSIndexPath(forRow: 0, inSection: 2)
let cell:EventTableTableViewCell = EventTableview.cellForRowAtIndexPath(indexPath) as! EventTableTableViewCell
cell.messageTextView.autocorrectionType = UITextAutocorrectionType.No
let keyboardDoneButton = UIToolbar()
keyboardDoneButton.sizeToFit()
let item = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("doneButton"))
var toolbarButtons = [item]
//Put the buttons into the ToolBar and display the tool bar
keyboardDoneButton.setItems(toolbarButtons, animated: false)
keyboardDoneButton.userInteractionEnabled = true
//cell.messageTextView.inputAccessoryView = keyboardDoneButton
textView.inputAccessoryView = keyboardDoneButton
}
}
func doneButton()
{
UIApplication.sharedApplication().sendAction("resignFirstResponder", to:nil, from:nil, forEvent:nil)
}
_textView.returnKeyType = UIReturnKeyType.Done
Did you set the keyboard in IB?
Storyboard > Textfield > Attributes Inspector > Return Key > Done
Implement the delegate method:
- textfieldShouldReturn:
Found here: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextFieldDelegate_Protocol/#//apple_ref/occ/intfm/UITextFieldDelegate/textFieldShouldReturn:

Resources