I am trying to load my different controller using Expandable Tableview but my headerview is set
as switch condition
For Header XXX1 -> two sub menu a and b ..
For Header XXX2-> sub menu c
but for Header XXX3 no sub menu ,, So i will work on click with XXX3(currently working with check SectionData.count == 0 ) but for multiple how to manage .. check out my code
sectionNames = ["xxxx1","xxxx2","xxx3","xxxx4"] //this is main header
sectionItems = [ ["a","b"],[c],[],[],[],[],[],[]]// This is sub menu items
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (self.expandedSectionHeaderNumber == section) {
let arrayOfItems = self.sectionItems[section] as! NSArray
return arrayOfItems.count;
} else {
return 0;
}
//return arraylist.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if (self.sectionNames.count != 0) {
return self.sectionNames[section] as? String
}
return ""
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 60.0;
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 50))
return footerView
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 0.5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifer, for: indexPath)
let section = self.sectionItems[indexPath.section] as! NSArray
cell.textLabel?.textColor = UIColor.black
cell.textLabel?.text = section[indexPath.row] as? String
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
}
let indexPath = tableView.indexPathForSelectedRow
// print(indexPath as Any)
//getting the current cell from the index path
let currentCell = tableView.cellForRow(at: indexPath!)! as UITableViewCell
// print(currentCell as Any)
//getting the text of that cell
let currentItem = currentCell.textLabel!.text
print(currentItem!)
switch currentItem {
case "XXXX1":
//// Here unable to do any work
break
case "a":
APICalla()
case "b":
APICallb ()
default:
break
}
return
}
Using this link
Sorry this tutorial is quite poor.
Swift is an object oriented language so use a custom model, a generic Section object with name, items and the information if the section is collapsed
class Section<T> {
var name : String
var items = [T]()
var isCollapsed = false
init(name : String, items : [T] = []) {
self.name = name
self.items = items
}
}
and a suitable struct for the items with a title and a closure to be called in didSelect
struct Item {
let title : String
let selectorClosure : (() -> Void)?
}
Rather than using multiple arrays populate the data source array consistently
var sections = [Section<Item>(name:"xxxx1", items: [Item(title: "a", selectorClosure: APICalla), Item(title: "b", selectorClosure: APICallb)]),
Section<Item>(name:"xxxx2", items: [Item(title: "c", selectorClosure: APICallc)]),
Section<Item>(name:"xxxx3")]
In numberOfRowsInSection return the proper number of items depending on isCollapsed
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let currentSection = sections[section]
return (currentSection.isCollapsed) ? 0 : currentSection.items.count
}
In cellForRow don't use typeless Foundation collection types
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifer, for: indexPath)
let item = sections[indexPath.section].items[indexPath.row]
cell.textLabel?.textColor = UIColor.black
cell.textLabel?.text = item.title
return cell
}
In the method to collapse/expand the sections just toggle isCollapsed
let currentSection = sections[section]
currentSection.isCollapsed.toggle()
and perform the animation
titleForHeaderInSection is much simpler, too
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section].name
}
In didSelectRow never get any data from the view (the cell) get it from the model (the data source array) and call the selector closure. With this logic a switch is not needed.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
let item = sections[indexPath.section].items[indexPath.row]
item.selectorClosure?()
}
Swift4 I think this will helps you
// declare globally
var isExpanded : Bool = true
var indexOfSection = Int()
var yourArray = [ModelName]()
override func viewDidLoad() {
super.viewDidLoad()
indexOfSection = 999
}
extension ViewController: UITableViewDelegate, UITableViewDataSource
{
func numberOfSections(in tableView: UITableView) -> Int {
if yourArray.count > 0{
return yourArray.count
}else{
return 0
}
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView(frame: CGRect(x: view.frame.origin.x,y: 0 , width: view.frame.size.width ,height: 60))
headerView.backgroundColor = .white
let collapseBtn = UIButton(frame: CGRect(x: headerView.frame.origin.x,y: headerView.frame.origin.y , width: view.frame.size.width ,height: 60))
collapseBtn.addTarget(self, action: #selector(expandSection(sender:)), for: .touchUpInside)
collapseBtn.tag = section
collapseBtn.backgroundColor = .clear
headerView.addSubview(collapseBtn)
return headerView
}
#objc func expandSection(sender:UIButton){
print(sender.tag)
if isExpanded == true{
indexOfSection = sender.tag
mIdeaTableView.reloadData()
isExpanded = false
mTableView.reloadSections([indexOfSection], with: UITableView.RowAnimation.bottom)
}else{
indexOfSection = 999
isExpanded = true
self.mTableView.reloadData()
}
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 60
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if yourArray.count > 0{
if yourArray[section].items!.count > 0{
if indexOfSection == section{
return yourArray[section].items!.count
}else{
return 0
}
}else{
return 0
}
}else{
return 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: “CellID”, for: indexPath) as! Cell
if yourArray[indexPath.section]. items!.count > 0{
if yourArray[indexPath.section]. items!.count > 0{
let ideas = yourArray[indexPath.section].ideaItems
if ideas!.count > 0{
if indexOfSection == indexPath.section{
cell.mLbl.text = ideas![indexPath.row].name ?? ""
if ideas![indexPath.row].isExpanded == true{
cell.mAddImg.image = #imageLiteral(resourceName: "tick")
}else{
cell.mAddImg.image = #imageLiteral(resourceName: "edit213-1")
}
}
}
}
}
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 60
}
}
//Structure of my response
{
items = (
{
name = “a”;
},
{
name = “b”;
},
);
name = “xxxx1”;
}
items = (
{
name = “c”;
},
);
name = “xxxx2”;
}
}
Related
I've implemented tableView section index in my app.
TableView Section Index shows when data of tableView is local, When i get data from api call at that time tableview section index hides.
I don't understand why this happening
Here is my tableview section index code:
var sectionArray = UILocalizedIndexedCollation.current().sectionIndexTitles // section Array
func numberOfSections(in tableView: UITableView) -> Int
{
return memberStructList.count // this is structList
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return memberStructList[section].memberArray.count
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
let cell = tableView.dequeueReusableCell(withIdentifier: "MembersHeaderTVCell") as! MembersTVCell
cell.lblSectionHeader.text = memberStructList[section].sectionName
return cell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
{
return 40
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "MembersTVCell") as! MembersTVCell
let sectionRows = memberStructList[indexPath.section]
let row = sectionRows.memberArray[indexPath.row]
cell.lblMemberName.text = row.first_name
return cell
}
func sectionIndexTitles(for tableView: UITableView) -> [String]?
{
return sectionArray
}
func tableView(_ tableView: UITableView,
sectionForSectionIndexTitle title: String,
at index: Int) -> Int
{
if memberStructList.contains(where: {$0.sectionName == title}),
let sectionIndex = memberStructList.firstIndex(where: {$0.sectionName == title})
{
return sectionIndex
}
else
{
return NSNotFound
}
}
And Here is Structure Code:
struct MemberStruct
{
var sectionName : String
var memberArray : [MemberModel] = []
}
Here is My Webservice Code and MVCServer is My Webservice Function
MVCServer().serviceRequestWithURL(reqMethod: .get, withUrl: strUrl, withParam: [:], diplayHud: true, includeToken: true) { (ResponseCode, Response) in
if ResponseCode == 1
{
if let array = Response.value(forKeyPath: "payload.data") as? NSArray
{
var memberArray = MemberModel.modelsFromDictionaryArray(array: array)
memberArray.forEach({$0.first_name = $0.first_name.capitalized + " " + $0.last_name.capitalized})
memberArray.sort(){$0.first_name < $1.first_name}
let groupedDictionary = Dictionary(grouping: memberArray, by: {String($0.first_name.capitalized.prefix(1))})
let keys = groupedDictionary.keys.sorted()
self.memberStructList = keys.map({ MemberStruct(sectionName: $0, memberArray: groupedDictionary[$0]!)})
self.tblMembers.reloadData()
}
}
else
{
Utility.showToast(messageData: Response)
}
}
If everything is ok with your local data so, I guess You did not follow the priority.
You must set your tableview Delegate and Datasource after receiving the response from webservice.
self.tableview.dataSource = self
self.tableview.delegate = self
or you should reload your tableview again:
self.tableview.reloadData()
Have you tried this instead of using TableViewCell on the section header?
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView(frame: CGRectMake(0, 0, tableView.frame.size.width, 18))
let label = UILabel(frame: CGRectMake(10, 5, tableView.frame.size.width, 18))
label.font = UIFont.systemFontOfSize(14)
label.text = memberStructList[section].sectionName
view.addSubview(label)
view.backgroundColor = UIColor.grayColor() // Set your background color
return view
}
I have created grouped sections in UITableView but values are getting duplicate. How to populate items under each section? Sections I already created. Few Title items are null.
SectionList --> Title --> Items
Like:
Bir have one item
Proj Plan have null item
Proj Ev has three items
I want to display textField in every section Title.
code:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView.dataSource = self
tableView.delegate = self
if let url = Bundle.main.url(forResource: "AppD", withExtension: "json") {
do {
let data = try Data(contentsOf: url)
let decoder = JSONDecoder()
let jsonData = try decoder.decode(AppointmentDetail.self, from: data)
self.AppData = jsonData
self.tableView.reloadData()
} catch {
print("error:\(error)")
}
}
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return AppData?.sectionList?[section].title
}
func numberOfSections(in tableView: UITableView) -> Int {
return AppData?.sectionList?.count ?? 0
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return AppData?.sectionList?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath)
// Configure the cell...
if let sections = AppData?.sectionList?[indexPath.section].items {
for item in sections {
if item.textField != "" {
cell.textLabel?.text = item.textField
}
}
}
Make changes as below
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return AppData?.sectionList?[section].items?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath)
cell.textLabel?.text = AppData?.sectionList?[indexPath.section].items?[indexPath.row].textField
cell.textLabel?.sizeToFit()
cell.textLabel?.numberOfLines = 0
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
For Adding HeaderView XIB to table view
var tableHeaderViewObj : BookNowHotelDetailHeader?
inViewdidload
tableHeaderViewObj = BookNowHotelDetailHeader(frame: CGRect(x: 0.0, y: 0.0, width: (window?.frame.width)!, height: 350))
self.BookNowTV.tableHeaderView = tableHeaderViewObj
tableHeaderViewObj?.parentVC = self
tableHeaderViewObj?.UpdateBookNowHotelData(Obj: hotelDetailObj ?? HotelDetailModal())
i have a table view in which i'm populating data getting from my service. the data is totally dynamic and table view contain sections and cell under it all the things are dynamic. I have a button action outside the table view which is used to add the selected cell data. Now i want to restrict the button that it does not add the data till all the cell under the sections are selected. I want user to first check the cells and than add through add button. My code for the table view is this,
func numberOfSections(in tableView: UITableView) -> Int {
return AddonCategoryModel!.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return AddonCategoryModel![section].name
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 34
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return AddonCategoryModel![section].addonItems.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = addonTableView.dequeueReusableCell(withIdentifier: "addonCell", for: indexPath) as! RestaurantMenuDetailAddonTVC
cell.addonTitleLbl.text = AddonCategoryModel![indexPath.section].addonItems[indexPath.row].name
cell.priceLbl.text = String(AddonCategoryModel![indexPath.section].addonItems[indexPath.row].price)
if selection[indexPath.section].isSelected[indexPath.row] {
cell.radioBtn.setImage(UIImage (named: "radio"), for: UIControlState.normal)
addonItemName = cell.addonTitleLbl.text!
addonItemprice = AddonCategoryModel![indexPath.section].addonItems[indexPath.row].price
addonItemId = AddonCategoryModel![indexPath.section].addonItems[indexPath.row].addonPKcode
addonItemNameArray.append(addonItemName)
addonItemPriceArray.append(addonItemprice)
addonItemIdArray.append(addonItemId)
let defaults = UserDefaults.standard
defaults.set(addonItemName, forKey: "addonItemName")
defaults.set(addonItemprice, forKey: "addonItemPrice")
defaults.set(addonItemId, forKey: "addonItemId")
defaults.synchronize()
}
else {
cell.radioBtn.setImage(UIImage (named: "uncheckRadio"), for: UIControlState.normal)
}
cell.radioBtn.tag = indexPath.row
// cell.radioBtn.addTarget(self, action: #selector(checkBoxSelection(_:)), for: .touchUpInside)
cell.selectionStyle = .none
cell.backgroundColor = UIColor.clear
return cell
}
My screen looks like this,
Basically, you have to set selected true and false based on user have selected the row or deselected the row, then just check in your data set is anything selected if yes then make the button highlighted/enable else disable/unhighlighted
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selection[indexPath.section].isSelected = true
tableView.reloadData()
CheckIfAnyOneIsSelected()
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
selection[indexPath.section].isSelected = false
tableView.reloadData()
CheckIfAnyOneIsSelected()
}
func CheckIfAnyOneIsSelected() {
//loop through your array and check if anyone is selected if yes break the loop and set the button to enable
//else make the button disable
var anyOneSelecte = false
for singleModel in AddonCategoryModel {
for item in addonItems {
if item.isSelected == true
anyOneSelecte = true
break;
}
}
if anyOneSelecte {
//enable your button
} else {
//disable your button
}
}
I have created demo, Let's say you have two Model classes,
class AddOnCategoryModel {
var name: String = ""
var arrValues = [Category]()
init(name: String) {
self.name = name
}
}
class Category {
var name: String = ""
var price : String = ""
var isSelected: Bool = false
}
and following is the mainArray,
for i in 0...2 {
let model = AddOnCategoryModel(name: "Section \(i)")
for j in 0...3 {
let cate = Category()
cate.name = "Category \(j)"
model.arrValues.append(cate)
}
mainArray.append(model)
}
Now considering you have following ListTableCell
There are two IBOutlets
#IBOutlet weak var lblTemp: UILabel!
#IBOutlet weak var btnRadio: UIButton!
FYI. Please set btnRadio default and selected image properly.
Your UITableViewDataSource methods,
func numberOfSections(in tableView: UITableView) -> Int {
return mainArray.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return mainArray[section].arrValues.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ListTableCell") as! ListTableCell
let category = mainArray[indexPath.section]
cell.lblTemp.text = category.arrValues[indexPath.row].name
cell.btnRadio.tag = indexPath.row
cell.tag = indexPath.section
cell.btnRadio.addTarget(self, action: #selector(btnRadioTapped), for: .touchUpInside)
return cell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return mainArray[section].name
}
Please find btnRadioTapped method,
#objc func btnRadioTapped(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
let cell = sender.superview?.superview as! ListTableCell
let addOnModel = mainArray[cell.tag]
let category = addOnModel.arrValues[sender.tag]
category.isSelected = sender.isSelected
}
Not let's check all checkbox's are selected or not in button tap event like this,
#IBAction func btnTapped(_ sender: UIButton) {
var isCheckedAll = true
for (_ , item) in mainArray.enumerated() {
let value = item.arrValues.filter({$0.isSelected==false})
if value.count > 0 {
isCheckedAll = false
break;
}
}
print("Done ", isCheckedAll)
}
It will return true if all radioButtons are selected, and return false if any one radioButton is not selected.
Let me know in case of any queries. This is just demo, you have to do minor changes as per your final requirements.
UPDATE
Please find didSelectRowAt indexPath method below,
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let model = mainArray[indexPath.section]
let category = model.arrValues[indexPath.row]
category.isSelected = !category.isSelected
let cell = tableView.cellForRow(at: indexPath) as! ListTableCell
cell.btnRadio.isSelected = category.isSelected
}
In my App I implemented Expandable tableview. It's worked perfectly but now I want to change the first section was already expandable mode but I unable to do that.
Here I have implemented my own native code for creating expandable tableview not using any third party libraries.
Here I post my Full code for Expandable TableView:
#IBOutlet weak var tableViewSecond: UITableView!
var hidden = [true]
override func viewDidLoad() {
super.viewDidLoad()
tableViewSecond.delegate = self
tableViewSecond.dataSource = self
InspectionArray = [["inspection_name":"AVM Inspection"], ["inspection_name":"Simple Inspection"], ["inspection_name":"BVM Inspection"]]
InspectionSectionArray = [["inspection_Session":"Current Inspection"], ["inspection_Session":"Past Inspection"], ["inspection_Session":"Future Inspection"]]
}
func numberOfSections(in tableView: UITableView) -> Int {
for _ in 0..<InspectionSectionArray.count {
hidden.append(true)
}
return InspectionSectionArray.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if hidden[section] {
return 0
} else {
return InspectionArray.count
}
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
headerView.backgroundColor = UIColor.orange
headerView.tag = section
let label = UILabel()
label.text = (InspectionSectionArray[section] as AnyObject).value(forKey: "inspection_Session") as? String
label.frame = CGRect(x: 45, y: 5, width: 150, height: 35)
label.font = UIFont.boldSystemFont(ofSize: 15)
headerView.addSubview(label)
label.tag = section
let tapForheaderView = UITapGestureRecognizer(target: self, action: #selector(SecondViewController.tapFunction))
headerView.isUserInteractionEnabled = true
headerView.addGestureRecognizer(tapForheaderView)
return headerView
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 2
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 45
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "SecondTableViewCell", for: indexPath) as? SecondTableViewCell
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: "SecondTableViewCell") as? SecondTableViewCell;
}
cell!.dataLbl.text = (InspectionArray[indexPath.row] as AnyObject).value(forKey: "inspection_name") as? String
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
print(indexPath.row)
print("\(indexPath.section)","\(indexPath.row)")
}
func tapFunction(sender:UITapGestureRecognizer) {
let section = sender.view!.tag
let indexPaths = (0..<InspectionArray.count).map { i in return IndexPath(item: i, section: section) }
hidden[section] = !hidden[section]
tableViewSecond.beginUpdates()
if hidden[section] {
tableViewSecond.deleteRows(at: indexPaths, with: .fade)
} else {
tableViewSecond.insertRows(at: indexPaths, with: .fade)
}
tableViewSecond.endUpdates()
}
I believe you only need to change this:
// declare hidden as this
var hidden: [Bool] = []
override func viewDidLoad() {
super.viewDidLoad()
InspectionArray = [["inspection_name":"AVM Inspection"], ["inspection_name":"Simple Inspection"], ["inspection_name":"BVM Inspection"]]
InspectionSectionArray = [["inspection_Session":"Current Inspection"], ["inspection_Session":"Past Inspection"], ["inspection_Session":"Future Inspection"]]
// initialize hidden array so that the first is false and the rest true
hidden = Array<Bool>(repeating: true, count: InspectionSectionArray.count)
hidden[0] = false
tableViewSecond.delegate = self
tableViewSecond.dataSource = self
}
// and change numberOfSections to this
func numberOfSections(in tableView: UITableView) -> Int {
return InspectionSectionArray.count
}
Just change this function
func tapFunction(sender: UITapGestureRecognizer?) {
var section = 0
if sender != nil {
section = sender!.view!.tag
}
let indexPaths = (0..<InspectionArray.count).map { i in return IndexPath(item: i, section: section) }
hidden[section] = !hidden[section]
tableViewSecond.beginUpdates()
if hidden[section] {
tableViewSecond.deleteRows(at: indexPaths, with: .fade)
} else {
tableViewSecond.insertRows(at: indexPaths, with: .fade)
}
tableViewSecond.endUpdates()
}
And call self.tapFunction(sender: nil) in viewdidLoad.
I want to select a row from different sections of the same table-view. I am getting output that many rows are selecting but I want exactly only one selected row from each section.
Here is My Arrays:
var filterFeedUnderAll = ["Complex","NotComplex","Easy"]
var filterFeedUnderAllStocks = ["AllStocks","Portfolio","Watchlist","Sector","Ticker"]
var filterFeedUnderByDate = ["ByDate","ByComments","ByLikes"]
The methods I have used:
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 3
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
var count:Int?
if section == 0
{
count = filterFeedUnderAll.count
}
else if section == 1
{
count = filterFeedUnderAllStocks.count
}
else if section == 2
{
count = filterFeedUnderByDate.count
}
return count!
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = self.m_HomeFeedFilterBaseTableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! HomeFeedFIlterBaseTableViewCell
switch (indexPath.section)
{
case 0:
cell.m_TableItemsLabel.text = filterFeedUnderAll[indexPath.row]
case 1:
cell.m_TableItemsLabel.text = self.filterFeedUnderAllStocks[indexPath.row]
case 2:
cell.m_TableItemsLabel.text = filterFeedUnderByDate[indexPath.row]
default:
cell.m_TableItemsLabel.text = "Other"
}
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
let cell = m_HomeFeedFilterBaseTableView.cellForRowAtIndexPath(indexPath) as! HomeFeedFIlterBaseTableViewCell
for selectedIndexPath: NSIndexPath in tableView.indexPathsForSelectedRows!
{
if selectedIndexPath.section == indexPath.section
{
cell.m_TableItemsLabel.textColor = selectedTextColor
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
}
}
I want to select one row from each section. Help me to achieve this task.
first of all you need to enable multiple selection in your tableView and then this is the code that I used to do that, note that I use a Dictionary with format [String:NSIndexPath] named selectedRows where I store one indexPath by section I do this in addSelectedCellWithSection
UPDATED for last swift
import UIKit
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate,UITextFieldDelegate {
#IBOutlet weak var tableView: UITableView!
var filterFeedUnderAll = ["Complex","NotComplex","Easy"]
var filterFeedUnderAllStocks = ["AllStocks","Portfolio","Watchlist","Sector","Ticker","bla bla bla1","bla bla bla2","bla bla bla3","bla bla bla1","bla bla bla2","bla bla bla3","bla bla bla1","bla bla bla2","bla bla bla3"]
var filterFeedUnderByDate = ["ByDate","ByComments","ByLikes"]
var selectedRows = [String:IndexPath]()
var alert : UIAlertController?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSections(in tableView: UITableView) -> Int
{
return 3
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50;
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerCell = tableView.dequeueReusableCell(withIdentifier: "headerCell") as! mycustomHeader
let layer = CAShapeLayer()
let corners = UIRectCorner.topLeft.union(UIRectCorner.topRight)
layer.path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: headerCell.frame.width, height: headerCell.frame.height), byRoundingCorners: corners, cornerRadii:CGSize(width: 20.0, height: 20.0)).cgPath
headerCell.layer.mask = layer
return headerCell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
var count:Int?
if section == 0
{
count = filterFeedUnderAll.count
}
else if section == 1
{
count = filterFeedUnderAllStocks.count
}
else if section == 2
{
count = filterFeedUnderByDate.count
}
return count!
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = self.tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as! testCell
switch (indexPath.section)
{
case 0:
cell.lblName.text = filterFeedUnderAll[indexPath.row]
case 1:
cell.lblName.text = self.filterFeedUnderAllStocks[indexPath.row]
case 2:
cell.lblName.text = filterFeedUnderByDate[indexPath.row]
default:
cell.lblName.text = "Other"
}
cell.lblName.textColor = UIColor.black
if(self.indexPathIsSelected(indexPath)) {
cell.lblName.textColor = UIColor.red
}
return cell
}
func addSelectedCellWithSection(_ indexPath:IndexPath) ->IndexPath?
{
let existingIndexPath = selectedRows["\(indexPath.section)"]
selectedRows["\(indexPath.section)"]=indexPath;
return existingIndexPath
}
func indexPathIsSelected(_ indexPath:IndexPath) ->Bool {
if let selectedIndexPathInSection = selectedRows["\(indexPath.section)"] {
if(selectedIndexPathInSection.row == indexPath.row) { return true }
}
return false
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = self.tableView.cellForRow(at: indexPath) as! testCell
let previusSelectedCellIndexPath = self.addSelectedCellWithSection(indexPath);
if(previusSelectedCellIndexPath != nil)
{
let previusSelectedCell = self.tableView.cellForRow(at: previusSelectedCellIndexPath!) as! testCell
previusSelectedCell.lblName.textColor = UIColor.black
cell.lblName.textColor = UIColor.red
tableView.deselectRow(at: previusSelectedCellIndexPath!, animated: true)
}
else
{
cell.lblName.textColor = UIColor.red
}
for selectedIndexPath: IndexPath in tableView.indexPathsForSelectedRows!
{
if selectedIndexPath.section == indexPath.section
{
cell.lblName.textColor = UIColor.red
tableView.deselectRow(at: indexPath, animated: true)
}
}
}
}
Hope this helps you, for me works perfect