I want to change the TableView data according to Textfield. when a user taps on Textfield and starts editing it will change the TableView data accordingly. I saw a lot of examples on but mainly I found about search bar any help would be appreciated. Please note that this is textfield not seacrhbar
You can try
var searchActive : Bool = false
var data = ["San Francisco","New York","San Jose","Chicago","Los Angeles","Austin","Seattle"]
var filtered:[String] = []
textField.addTarget(self, action: #selector(ViewController.textFieldDidChange(_:)),
for: UIControlEvents.editingChanged)
and handle method:
#objc func textFieldDidChange(_ textField: UITextField) {
// filter tableViewData with textField.text
let searchText = textField.text
filtered = data.filter({ (text) -> Bool in
let tmp: NSString = text as NSString
let range = tmp.range(of: searchText, options: NSString.CompareOptions.caseInsensitive)
return range.location != NSNotFound
})
if(filtered.count == 0){
searchActive = false;
} else {
searchActive = true;
}
self.tableView.reloadData()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:CellIdentifier1) as! generalTableViewCell
if(searchActive){
cell.titlelb.text = filtered[indexPath.row]
} else {
cell.titlelb.text = data[indexPath.row];
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(searchActive){
return filtered.count
} else {
return data.count
}
}
You can implement textFieldDelegate in the view controller and then in the delegate method textFieldDidChange you can change the tableview datasource according to your use and reload the tableview after that.
Related
currently I am trying to implement my search bar, but something is wrong and I can't figure it out what it is. Here is the code, and explanation.
//global variable for empty array, its type of Any cause I am getting data from network call
var filteredData: [Any]!
//these are my models, which I am using to display them on screen after mapping in network function
var bookedTrips: [BookedTripsForView]?
func viewDidLoad() {
super.viewDidLoad()
filteredData = bookedTrips
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchBar.becomeFirstResponder()
filteredData = []
if searchText == "" {
filteredData = bookedTrips
}else {
for trip in (bookedTrips)! {
if trip.tripName.lowercased().contains(searchText.lowercased()){
filteredData.append(trip)
//if I type, lets say Barcelona, in console its printed correct result,
//but its displaying only first trip in my array, which is Berlin
print("filteredDataArray after appending print: \(String(describing: filteredData))")
}
}
}
self.tableView.reloadData()
}
I hope that my explanation is ok, if something's not clear, I will refactor my question. Thanks in advance.
Here is picture of my screen and console
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let filter = filteredData {
return filter.count
} else if let data = bookedTrips {
return data.count
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: Cells.tripInfo) as! TripsListDetailCell
if let trips = bookedTrips?[indexPath.row] {
cell.configure(trips: trips)
}
return cell
}
Short and simple (One line filter)
var filteredData = [BookedTripsForView]()
var bookedTrips = [BookedTripsForView]()
override func viewDidLoad() {
super.viewDidLoad()
bookedTrips = fetchFromAPIorDB()
filteredData = bookedTrips
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.filteredData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: Cells.tripInfo) as! TripsListDetailCell
cell.configure(trips: filteredData[indexPath.row])
return cell
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText.isEmpty {
filteredData = bookedTrips
}
else {
filteredData = bookedTrips.filter({ $0.tripName.lowercased().contains(searchText.lowercased()) })
}
self.tableView.reloadData()
}
var isSearching: Bool = false // As global variable
var bookedTrips: [BookedTripsForView]? = []
var filteredData: [BookedTripsForView]? = []
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchBar.becomeFirstResponder()
filteredData = []
if searchText == "" {
isSearching = false
}else {
isSearching = true
filteredData = bookedTrips.filter { (trip) -> Bool in
if trip.tripName.lowercased().contains(searchText.lowercased()){
return true
}
return false
}
}
self.tableView.reloadData()
}
//Tableview delegate
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isSearching {
return self.filteredData.count
}
return bookedTrips.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: Cells.tripInfo) as! TripsListDetailCell
if isSearching {
cell.configure(trips: filteredData[indexPath.row])
}
else {
cell.configure(trips: bookedTrips[indexPath.row])
}
return cell
}
create enum for page mood like this for readable code:
enum PageMood {
case normal
case search
}
and create variable
var pageMode: PageMood = .normal
set normal for first first if search and change pageMode to search like this:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchBar.becomeFirstResponder()
if searchText == "" {
pageMode = .normal
}else {
pageMode = .search
filteredData = bookedTrips?.filter({ item -> Bool in
return (item.tripName?.lowercased().contains(searchText.lowercased()) ?? false)
})
}
self.tableView.reloadData()
}
change define datasource like this:
var bookedTrips: [BookedTripsForView]?
var filteredData: [BookedTripsForView]?
and inside set numberOfItem:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if pageMode == .search {
return filteredData.count ?? 0
} else {
return bookedTrips.count ?? 0
}
}
if only one item findŲ Maybe your data has only one item similar to the search text.
And now, since I changed my variables to this :
var filteredData = [BookedTripsForView]()
var bookedTrips = [BookedTripsForView]()
I have one more problem in sections, added comment inside
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cell = tableView.dequeueReusableHeaderFooterView(withIdentifier: Cells.sectionTitle) as! TripsListHeaderCell
if isSearching {
cell.configure(trips: filteredData[section])
}
else {
cell.configure(trips: bookedTrips[section])
}
return cell
}
How should I implement function viewForHeaderInSection? In response inside every trip I get status of trip (current, upcoming, previous). I would like to sort them by status. If I put this inside viewForHeaderInSection :
if isSearching {
cell.configure(trips: filteredData[section])
} else {
cell.configure(trips:bookedTrips[section])
}
return cell
I get index out of range on bookedTrips[section] If i comment that line, it works until I make mistake in search bar, lets say instead of Barcelona I type Bars, it throws error on filteredData[section] index out of range
In my response, every trip have trip status property which has type string, can I even sort them by that property?
I have a popup with searchBar at the top and TableView below it. TableView is populated by dynamic data. I have a custom tableViewCell, with a label for names and a checkBox(M13CheckBox Library) to select a name.
Now, when I search for a name, Firstly the tableView is not loaded as the user types a name in the search bar. For eg, Suppose there are persons named "Mary", "Mackenzie", "Margaret" and "Mallory". I want to search for "Margaret", so as I start typing "Mar" in searchBar, then "Mary" and "Margaret" are filtered properly in tableView, but when I go back i.e "Ma", then it should show all the 4 names, since "Ma" is present in the list, But the tableView does not show anything.
So tableView should always reload as user types in searchBar if the letters are contained in the names. Please help me sort this issue. Since it is a popup I am passing data to tableView from another VC, by notification.
Here is my code for search VC:
class ParticipantsListVC: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate{
public static var participantNameArray:[String] = [String]() //global var
var viewController: ViewController!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
searchParticipantFilter.delegate = self
viewController = ViewController()
let notificationName = NSNotification.Name("reloadList")
NotificationCenter.default.addObserver(forName: notificationName, object: nil, queue: OperationQueue.main) { (notifObject) in
self.tableView.reloadData()
}
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText:String) {
if searchText == "" {
ParticipantsListVC.participantNameArray.removeAll()
viewController.getParticipantList() // func to get list from sever
}else{
ParticipantsListVC.participantNameArray = ParticipantsListVC.participantNameArray.filter({(name) -> Bool in
return name.lowercased().contains(searchText.lowercased())
})
}
self.tableView.reloadData()
}
}
Also if I select a name, then checkBox is selected in front of that name.But when I click on cancel(X) in searchBar, then always the first cell in tableView is shown selected and not the name that I had selected. I don't know why always the first cell gets selected, after selecting name from filtered list.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ParticipantListCell
let dict = ParticipantsListVC.participantNameArray[indexPath.row]
cell.participantNameLabel.text = dict
if selectedIndexPaths.contains(indexPath) {
cell.selectedParticipantCB.setCheckState(.checked, animated: true)
}else{
cell.selectedParticipantCB.setCheckState(.unchecked, animated: true)
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Since any random cell was getting selected on scrolling So I added this code.
tableView.deselectRow(at: indexPath, animated: true)
if selectedIndexPaths.contains(indexPath) {
selectedIndexPaths.removeObject(object: indexPath)
}else{
selectedIndexPaths.append(indexPath)
}
tableView.reloadData()
}
I don't want to use searchBar in headerView or another tableView to show filtered list. Please much appreciated.Thank you.
You need to create another array to hold the backup of data array.
var arrParticipantList = [String]()
var arrParticipantListBackup = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.searchBar.delegate = self
self.tblParticipantList.delegate = self
self.tblParticipantList.dataSource = self
self.arrParticipantList = ["Mary", "Mackenzie", "Margaret", "Mallory","Molly"]
self.arrParticipantListBackup = self.arrParticipantList
}
Code to search for search string, refill array and reload tableview
extension ViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
var searchText = searchBar.text! + text
if range.length > 0 {
if range.location == 0 {
self.arrParticipantList = self.arrParticipantListBackup
self.tblParticipantList.reloadData()
return true
}
searchText = String(searchText.dropLast(range.length))
}
self.arrParticipantList = self.arrParticipantListBackup.filter({$0.lowercased().hasPrefix(searchText.lowercased())})
self.tblParticipantList.reloadData()
return true
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
self.searchBar.text = ""
self.searchBar.resignFirstResponder()
self.arrParticipantList = self.arrParticipantListBackup
self.tblParticipantList.reloadData()
}
}
Code for tableview
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.arrParticipantList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
cell?.textLabel?.text = self.arrParticipantList[indexPath.row]
return cell!
}
}
Hope this solves your issue.
struct namelist {
var searchname: NSString
}
var searchActive = Bool()
var newSearchArray = [namelist]()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searchActive ? newSearchArray.count : nameOldArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let Cell:SearchTableViewCell! = tableView.dequeueReusableCell(withIdentifier: "Cell") as! SearchTableViewCell
Cell.selectionStyle = .none
if (searchActive == true) {
if ( newSearchArray.count > 0) {
var para = NSMutableAttributedString()
para = NSMutableAttributedString(string:(newSearchArray[indexPath.row].searchname) as String)
do {
let regex = try NSRegularExpression(pattern: searchText, options: NSRegularExpression.Options.caseInsensitive )
let nsstr = newSearchArray[indexPath.row].searchname
text = nsstr as String
let all = NSRange(location: 0, length: nsstr.length)
var matches : [String] = [String]()
regex.enumerateMatches(in: text, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: all) {
(result : NSTextCheckingResult?, _, _) in
if let r = result {
let results = nsstr.substring(with: r.range) as String
matches.append(results)
let substringrange = result!.rangeAt(0)
para.addAttribute(NSForegroundColorAttributeName, value:UIColor.init(red: 237/255.0, green: 60/255.0, blue: 58/255.0, alpha: 1.0), range: substringrange)
Cell.namelbl.attributedText = para
}
}
} catch {
}
}
}
else {
Cell.namelbl.text = self.searchname[indexPath.row] as? String
}
return Cell
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchArray.removeAllObjects()
newSearchArray.removeAll()
if Search.text != nil {
for i in 0 ..< searchname.count {
searchText = Search.text!
text = ((searchname.object(at: i))) as! String
if text.lowercased().contains(searchText.lowercased()) {
let elm = namelist(searchname: text as NSString)
self.newSearchArray.append(elm)
}
}
}
searchActive = !newSearchArray.isEmpty
searchBar.resignFirstResponder()
yourTableName.reloadData()
}
I put UITextField inside UITableViewCell and want to make highlight tableViewCell and unselected tableViewCell goes original color if user key-in inside each UITextField. So, I did like that.
func textFieldDidBeginEditing(_ textField: UITextField) {
defaultIndex = textField.tag
dynamicFormTable.reloadData()
}
But problem is Keyboard is not showing when I've added dynamicFormTable.reloadData(). Please let me know how to resolve it. Thanks.
Following code will give good result, to avoid reloads
var cellBGColr = [Int : UIColor]()
var previouselectedRow = [Int]()
override func viewDidLoad() {
super.viewDidLoad()
for i in 0..<70 // numberOfRows
{
cellBGColr[i] = UIColor.white
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 70
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "table", for: indexPath) as! TblTableViewCell
cell.backgroundColor = cellBGColr[indexPath.row]
cell.selectionStyle = .none
return cell
}
func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
let cellPosition = textView.superview?.convert(CGPoint.zero, to: tblView)
let indPath : IndexPath = tblView.indexPathForRow(at: cellPosition!)!
let cell = tblView.cellForRow(at: indPath) as! TblTableViewCell
var previousSelectedCellRow : Int = -1 // FOR VALIDATION
if previouselectedRow.count == 0 // FIRST EDIT
{
previouselectedRow.append(indPath.row)
}
else
{
previousSelectedCellRow = previouselectedRow[0]
if previousSelectedCellRow == indPath.row // SAME ROW EDITING AGAIN
{
}
else // NEW ROW
{
let previousIndPath : IndexPath = IndexPath(row: previousSelectedCellRow, section: 0)
if (tblView.indexPathsForVisibleRows?.contains(previousIndPath))!
{
let previousCell = tblView.cellForRow(at: previousIndPath) as! TblTableViewCell
previousCell.backgroundColor = UIColor.white
cellBGColr[previousSelectedCellRow] = UIColor.white
}
else
{
cellBGColr[previousSelectedCellRow] = UIColor.white
}
previouselectedRow.remove(at: 0)
previouselectedRow.append(indPath.row)
}
}
cell.backgroundColor = UIColor.red // HERE YOU CAN CHANGE UR CELL COLOR
cellBGColr[indPath.row] = UIColor.red // HERE STORED IN DICT
return true
}
On scrolling your tableview, or somewhere you try to reload, cell background color will not change / reuse.
When reloadData is called it resigns first responder. But you can use beginUpdates/endUpdates methods:
dynamicFormTable.beginUpdates()
dynamicFormTable.reloadRows(at: [IndexPath(row: defaultIndex, section: 0)], with .none)
dynamicFormTable.endUpdates()
I am just starting to learn swift and firebase. I want to add a search bar that will allow users to search through my firebase database. This is what I want to get
I have added the searchbar, what I'm having problem with is the display of search result.
I created a container view that include Name, subdescription and logo like the image above and then set them up with this function
func searchResultContainer(){
searchResultView.addSubview(businesslogoView)
searchResultView.addSubview(businessNameLabel)
searchResultView.addSubview(businessSectorLabel)
//need x. y, width, height constraints for searchResult
searchResultView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
searchResultView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
searchResultView.heightAnchor.constraint(equalToConstant: 220).isActive = true
}
I then append the searchResult view to var bussinesarray. and then insert it into the tableview. Please see my code below
var businessArray = [NSDictionary]()
var filterBusiness = [NSDictionary]()
var ref : FIRDatabaseReference!
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.insertRows(at: [IndexPath(row: self.businessArray.count-1, section: 0)], with: UITableViewRowAnimation.automatic)
ref.child("Businesses").queryOrdered(byChild: "Basic-Info/business").observe(.childAdded, with: { (snapshot) in
view.addSubview(searchResultView)
searchResultContainer()
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// if searchbar is not empty "", then return filtered businesses if the user is not typing anything return all businesses.
if searchController.isActive && searchController.searchBar.text !=
""{
return filterBusiness.count
}
return self.businessArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let business : NSDictionary?
if searchController.isActive && searchController.searchBar.text !=
""{
business = filterBusiness[indexPath.row]
}
else
{
business = self.businessArray[indexPath.row]
}
cell.textLabel?.text = business?["Business"] as? String
cell.detailTextLabel?.text = business?["handle"] as? String
return cell
}
func filterContent (searchText:String) {
self.filterBusiness = self.businessArray.filter{ Businesses in
let businessName = Businesses["Business"] as? String
return(businessName?.contains(searchText.lowercased()))!
}
tableView.reloadData()
}
func updateSearchResults(for searchController: UISearchController) {
// update the search results
filterContent(searchText: self.searchController.searchBar.text!)
}
I am not getting the search result from firebase DB, how do I correctly implement the search result from firebase DB? I am building everything programmatically, please a sample code with be greatly appreciated.
This tutorial was a great help for me in figuring out a similar implementation, see the code near the bottom of the tutorial.
http://shrikar.com/swift-ios-tutorial-uisearchbar-and-uisearchbardelegate/
Code adjustments beyond this tutorial included the below code. I still have some clean up that could be done around the if/else section however the two critical concepts for me was using the model and getting the target correct with: let temp: NSString = text.EntityName! as NSString
Model file:
class Dealer: NSObject{
var DealerNumber: String?
var EntityName: String?
//matchup all other firebase data fields
}
ViewController Adjustments
var dealerList = [Dealer]()
var filterDealers = [Dealer]()
---
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filterDealers = dealerList.filter({ (text) -> Bool in
let temp: NSString = text.EntityName! as NSString
let range = temp.range(of: searchText, options: NSString.CompareOptions.caseInsensitive)
return range.location != NSNotFound
})
if(filterDealers.count == 0){
searchActive = false;
} else {
searchActive = true;
}
refreshTable()
}
----
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
var cell:UITableViewCell? = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)
cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellIdentifier)
if(searchActive){
cell?.textLabel?.text = filterDealers[indexPath.row].EntityName
cell?.detailTextLabel?.text = filterDealers[indexPath.row].DealerNumber
} else {
cell?.textLabel?.text = dealerList[indexPath.row].EntityName
cell?.detailTextLabel?.text = dealerList[indexPath.row].DealerNumber
}
return cell!;
}
Trying to navigate through text fields in UITableView. Able to navigate through text fields on simple view but not getting how to navigate when text fields are in UITableView.
Below is the code tried so far:
func textFieldDidBeginEditing(textField: UITextField)
{
//textField.inputAccessoryView = numberToolbar
if(textField == txtConfirmPassword)
{
textField.returnKeyType = UIReturnKeyType.Done
}
else
{
textField.returnKeyType = UIReturnKeyType.Next
}
}
Please guide thanks.
Update:
func textFieldDidBeginEditing(textField: UITextField)
{
if(delegate != nil)
{
delegate?.performSelector(NSSelectorFromString("editingTextField"))
}
if(textField.tag == 3)
{
textField.returnKeyType = UIReturnKeyType.Done
}
else
{
textField.returnKeyType = UIReturnKeyType.Next
}
}
func textFieldShouldReturn(textField: UITextField) -> Bool
{
if(delegate != nil)
{
delegate?.performSelector(NSSelectorFromString("editingDone"))
}
if(textField.tag == 3)
{
textField.resignFirstResponder()
delegate?.performSelector(NSSelectorFromString("editingDone"))
}
let nextTage=textField.tag+1
// Try to find next responder
let nextResponder=textField.superview?.viewWithTag(nextTage) as UIResponder!
if (nextResponder != nil){
// Found next responder, so set it.
nextResponder?.becomeFirstResponder()
}
else
{
// Not found, so remove keyboard
textField.resignFirstResponder()
}
return true
}
Here is the code for Swift 2.1
Here I have taken SampleTableViewCell which is a custom cell in which i have created textField.
For the purpose I have just taken the tag based on cell, so while accessing it in the textField's delegate method, You can know the textField is for which cell.
Here is the code :
//UITableView Delegate
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! SampleTableViewCell
cell.txtFld.delegate = self;
cell.txtFld.tag = indexPath.row + 100
cell.selectionStyle = UITableViewCellSelectionStyle.Gray;
return cell;
}
UPDATE : Here is the delegate for TextField
//UITextField Delegate
func textFieldDidBeginEditing(textField: UITextField)
{
//textField.inputAccessoryView = numberToolbar
if(textField.tag == 100)
{
textField.returnKeyType = UIReturnKeyType.Done
}
else
{
textField.returnKeyType = UIReturnKeyType.Next
}
}
Here I have navigate to next textfield by clicking the return button of text field.
// called when 'return' key pressed. return NO to ignore.
func textFieldShouldReturn(textField: UITextField) -> Bool
{
textField.resignFirstResponder();
if(textField.tag == 100)
{
let txtFld = self.tblList.viewWithTag(101);
txtFld?.becomeFirstResponder();
}
return true;
}
Hope it helps.
Happy coding ...
You should use the tag to check if the current textfield is the first responder.
Note: Swift 3.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// let's say that you are reading the date from an array...
return myArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! TableViewCell
// here you set the tag
cell.myTextfield?.tag = indexPath.row
// ...
return cell
}
func textFieldDidBeginEditing(textField: UITextField) {
// now, based on textField you can check (tag == myArray.count - 1 means it is the last)
textField.returnKeyType = (textField.tag == myArray.count - 1) ? .done : .next
}
Hope that helped.
Best way for me.
UITableViewCell
class CustomTableViewCell: UITableViewCell {
var nextTextField: (() -> Void)?
}
UITableViewDataSource, UITableViewDelegate
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
cell.nextTextField = { in
guard let cell = tableView.cellForRow(at: IndexPath(row: indexPath.row + 1, section: 0)) as? CustomTableViewCell else {
return
}
cell.textField.becomeFirstResponder()
}
return cell
}
UITextFieldDelegate
...
func textFieldDidBeginEditing(textfield: RCTextField) {
if viewModel.items.count-1 == textfield.tag {
textField.returnKeyType = UIReturnKeyType.done
} else {
textField.returnKeyType = UIReturnKeyType.next
}
}
...