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
}
Related
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”;
}
}
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 UI as shown in the screenshot. I have currently done this using tableviews. The screen is a tableview with static prototype cell 4 rows. One for the header including the profile image, next for the profile bio, third row for the favourites, subscriptions, event image button, and last row for the content which is another tableview.
Favourite section
Subscription section
I have used a single inner table view for the content with all elements in the favourites, subscriptions, and events in one cell. One load, I hide other elements and show only the one depending on the icon tap.
The problem is the cell height is inconsistent in favourites section. There is gap when there is more than one line in the label. In the subscriptions section, the last item touches the tabbar.
I have disabled scrolling for the outer table view, so only the inner table view (content section) scrolls, which is not pleasant on smaller screens.
class ProfileViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
profileTableView = ProfileSectionTableView() // inner table view
profileTableView.profileDelegate = self
profileSectionTableView.delegate = profileTableView
profileSectionTableView.dataSource = profileTableView
profileSectionTableView.rowHeight = UITableView.automaticDimension
profileSectionTableView.estimatedRowHeight = 44
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
switch (indexPath.row) {
case 0:
return 176
case 1:
return 72
case 2:
let height = self.view.frame.height - (176 + 72 + (self.tabBarController?.tabBar.frame.height)! + 8)
return height
default:
return UITableView.automaticDimension
}
}
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 44
}
}
The content section table view code is:
class ProfileSectionTableView: UITableView, UITableViewDelegate, UITableViewDataSource, ProfileSectionViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let cell = updateTableCell(tableView, indexPath) as! ProfileCell
var height = UITableView.automaticDimension
if (ProfileData.profileViewType == .favourite) {
height = cell.favouritesTitleLabel.text!.height(withConstrainedWidth: cell.favouritesTitleLabel.frame.width - 64, font: UIFont(name: "Roboto", size: 17.0)!) + 28
} else if (ProfileData.profileViewType == .subscription) {
height = cell.subscriptionTitleLabel.text!.height(withConstrainedWidth: cell.subscriptionTitleLabel.frame.width - 64, font: UIFont(name: "Roboto", size: 17.0)!) + 16
}
return height
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
// ...
}
extension String {
func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil)
return ceil(boundingBox.height)
}
}
How to fix the gap between the cells? I have label lines set as 0. How to layout UI elements for screens like this? Is the above method correct? Or should I use a UIViewController with a container view for the sections?
Related question on this How to change the cell height of inner table view cell in iOS?
Dependent your work, i am friendly with only tableView in screen.
Then setup tableView with composionSection:[[String:Any]] data; either item is data of section. ex: Favourites, Subscription ...
For section: i setup keyId for section, headSection, footer section, of course cell section.
you can scroll to top section for an other section.
For example:
// MARK: UITableViewDataSource
var composionSection = [[String: Any]]()
extension CountryDetailViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return composionSection.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let componentSection = self.composionSection[section] as? [String:Any]{
if let keyId = componentSection[kId] as? String, let object = componentSection[kObject] as? [String:Any] {
if keyId == kFavourites || keyId == kSubscription{
return object.count
}
}
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let componentSection = self.composionSection[indexPath.section] as? [String:Any]{
if let keyId = componentSection[kId] as? String, let object = componentSection[kObject] as? [String:Any] {
if keyId == kFavourites {
let cell = tableView.dequeueReusableCell(withIdentifier: identifierForViewCell, for: indexPath) as! ViewFavourites
return cell
}
else if keyId == kSubscription {
let cell = tableView.dequeueReusableCell(withIdentifier: identifierForViewCell, for: indexPath) as! ViewSubscription
return cell
}
}
}
return UITableViewCell()
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if let componentSection = self.composionSection[section] as? [String:Any]{
if let keyId = componentSection[kId] as? String, let object = componentSection[kObject] as? [String:Any] {
if keyId == kFavourites {
let sectionView = UIView()
return sectionView
}
else if keyId == kSubscription {
let sectionView = UIView()
return sectionView
}
}
}
return nil
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if let componentSection = self.composionSection[section] as? [String:Any] {
if let keyId = componentSection[kId] as? String {
if keyId == kFavourites {
return 80
}
else if keyId == kSubscription {
return 64 // or other
}
}
}
return 0
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return CGFloat.leastNormalMagnitude
}
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 am using a table view with multiple section. In one table view cell which is having text label and detailed text label to display array objects. Now I want add a new section, in this section I will be having more text like a paragraph. How to display data in text view?
{
var dataSection01:NSMutableArray = NSMutableArray()
var dataSection02:NSMutableArray = NSMutableArray()
var sectionTitleArray : NSMutableArray = NSMutableArray()
var arrayForBool : NSMutableArray = NSMutableArray()
var sectionContentDict : NSMutableDictionary = NSMutableDictionary()
in viewDidLoad()
sectionTitleArray = ["Assignment Information","Details"]
let tmp1 : NSArray = assignInfoArray
var string1 = sectionTitleArray .objectAtIndex(0) as? String
[sectionContentDict .setValue(tmp1, forKey:string1! )]
let tmp2 : NSArray = detailsInfoArray
string1 = sectionTitleArray .objectAtIndex(1) as? String
[sectionContentDict .setValue(tmp2, forKey:string1! )]
dataSection01 = [ "Name:", "Phone", "Email" so on]
dataSection02 = [ "Address", "Street", "State","ZipCode"]
//mapping like this using object mapper
assignInfoArray.addObject((newDetails?.clientName)!)
assignInfoArray.addObject((newDetails?.clientPhone)!)
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sectionTitleArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let CellIdentifier = "CellRightDetail"
var cell :UITableViewCell?
cell = self.tableView.dequeueReusableCellWithIdentifier(CellIdentifier)
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Value2, reuseIdentifier: "CellRightDetail")
}
let manyCells : Bool = arrayForBool .objectAtIndex(indexPath.section).boolValue
if (!manyCells) {
// cell.textLabel.text = #"click to enlarge";
}
else{
let items: NSMutableArray = self.dataFromIndexPath(indexPath)
let content = sectionContentDict .valueForKey(sectionTitleArray.objectAtIndex(indexPath.section) as! String) as! NSArray
cell!.detailTextLabel?.text = content .objectAtIndex(indexPath.row) as? String
cell!.detailTextLabel?.textColor = UIColor.whiteColor()
cell!.textLabel?.textColor = UIColor.whiteColor()
cell!.textLabel?.font = UIFont(name:"Helvetica-Bold", size: 13.0)
cell!.textLabel?.text = items[indexPath.row] as? String
}
return cell!
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
if(arrayForBool .objectAtIndex(section).boolValue == true)
{
let tps = sectionTitleArray.objectAtIndex(section) as! String
let count1 = (sectionContentDict.valueForKey(tps)) as! NSArray
return count1.count
}
return 0;
}
func dataFromIndexPath(indexPath: NSIndexPath!) -> NSMutableArray!
{
if (indexPath.section == 0)
{
return dataSection01
}
else if (indexPath.section == 1)
{
return dataSection02
}
return nil
}
}
In storyboard
Blue color is the first cell and green color is my second cell.
You have to create two cell like this and for each cell you have to create different customcell class. Make outlets of UILabel and UITextView in their respective class and use the below code .
May be your requirement vary little bit, so use delegates according to it.
Implement your code like this:
// MARK:- --- TableView Height ---
open func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat{
return 45
}
open func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat{
return 1
}
open func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 45
}
open func numberOfSections(in tableView: UITableView) -> Int{
return 2
}
// MARK:- --- TableView tittle ---
open func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?{
return "hearder " + String(section)
}
open func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?{
let viewHeader : UIView = UIView(frame: CGRect(x: 0 , y: 64, width: self.view.frame.size.width , height: 45))
viewHeader.backgroundColor = UIColor(red: 180.0/255.0, green: 160.0/255.0, blue: 240.0/255.0, alpha: 1)
let btnHeader : UIButton = UIButton(frame: CGRect(x: 0 , y: 0, width: viewHeader.frame.size.width , height: viewHeader.frame.size.height))
btnHeader.setTitle("section #\(section)", for: UIControlState())
btnHeader.backgroundColor = UIColor.darkGray
btnHeader.isSelected = arrIsExpand[section]
btnHeader.tag = section
btnHeader.addTarget(self, action:#selector(expandMethod(_:)) , for: UIControlEvents.touchUpInside)
viewHeader.addSubview(btnHeader)
return viewHeader
}
// MARK:- --- TableView data source ---
open func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return 10
}
open func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
if(indexPath.section == 0){ // for your first section
let firstCell : MyFirstCustomCell = tableView.dequeueReusableCell(withIdentifier: "firstcell") as! DesignTableCell
firstCell.lblTittle?.text = "Tittle"
firstCell.lblDescription?.text = "Description"
return firstCell
}
//for second section
else{
let secondCell : MySecondCustomCell = tableView.dequeueReusableCell(withIdentifier: "secondcell") as! DesignTableCell
secondCell.lblTittle?.text = "Tittle"
secondCell.txtViewData?.text = "Blah! Blah!"
return secondCell
}
}
May be you face the problem with the row height because I give static height here i.e. 45, so use uiautomaticdimension instead of static 45, and also impliment the delegate estimatedHeightForRow.