UITableView Section Header not showing - ios

I'm trying to make section headers with autolayout.
A simple header with a title and a counter
class ProfilePeopleListHeaderViewCell: UIView {
let titleLeftOffset = 12
let counterRightOffset = 5
let counterWidth = 50
var title = "title" {
didSet {
titleLabel.text = title
}
}
var numberOfPeople = 0 {
didSet {
peopleCounter.text = "\(numberOfPeople)"
}
}
let titleLabel = UILabel()
let peopleCounter = UILabel()
convenience init(title: String, numberOfPeople:Int) {
self.init()
self.title = title
self.numberOfPeople = numberOfPeople
backgroundColor = UIColor.greenColor()
titleLabel.textColor = Constants.Colors.ThemeGreen
titleLabel.textAlignment = .Left
if #available(iOS 8.2, *) {
titleLabel.font = Constants.Fonts.Profile.PeopleListHeaderFont
peopleCounter.font = Constants.Fonts.Profile.PeopleListHeaderFont
} else {
titleLabel.font = UIFont.systemFontOfSize(14)
peopleCounter.font = UIFont.systemFontOfSize(14)
}
peopleCounter.textAlignment = .Right
peopleCounter.textColor = Constants.Colors.ThemeDarkGray
addSubview(titleLabel)
addSubview(peopleCounter)
self.titleLabel.snp_makeConstraints { (make) -> Void in
make.centerY.equalTo(self)
make.height.equalTo(self)
make.width.equalTo(peopleCounter).multipliedBy(3)
make.left.equalTo(self).offset(titleLeftOffset)
}
self.peopleCounter.snp_makeConstraints { (make) -> Void in
make.centerY.equalTo(self)
make.height.equalTo(self)
make.width.equalTo(counterWidth)
make.left.equalTo(titleLabel.snp_right)
make.right.equalTo(self).offset(counterRightOffset)
}
}
}
The code to retrieve the header is:
let mutualFriendsSectionView = ProfilePeopleListHeaderViewCell(title: Strings.Title.MutualFriends, numberOfPeople: 0)
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == 1 {
//mutualFriendsSectionView.layoutSubviews()
return mutualFriendsSectionView
}
}
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
I get a green background in the section header.
But I don't see any label...

Try this out for UITableView Section Header.
Programatically create headerview
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView.init(frame: CGRectMake(0, 0, tblView.bounds.size.width, 50))
let lblHeader = UILabel.init(frame: CGRectMake(15, 13, tableView.bounds.size.width - 10, 24))
if section == 0 {
lblHeader.text = "Image Settings"
}
else if section == 1 {
lblHeader.text = "Personal Settings"
}
else {
lblHeader.text = "Other Settings"
}
lblHeader.font = UIFont (name: "OpenSans-Semibold", size: 18)
lblHeader.textColor = UIColor.blackColor()
headerView.addSubview(lblHeader)
headerView.backgroundColor = UIColor(colorLiteralRed: 240.0/255.0, green: 240.0/255.0, blue: 240.0/255.0, alpha: 1.0)
return headerView
}
Height for HeaderView
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}

Check if a tableView delegate is connected

Actually it's working.
my mistake was to believe that didSet{} was also called within the class -> it's not the case.
When I was setting the title in the init() it was not setting the label text.

try instantiating your headerView inside viewForHeader method
Edit your code as below
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
let mutualFriendsSectionView = ProfilePeopleListHeaderViewCell(title: Strings.Title.MutualFriends, numberOfPeople: 0)
if section == 1
{
//mutualFriendsSectionView.layoutSubviews()
return mutualFriendsSectionView
}
}

Related

UITableView Alphabetical Header Sections Determined by a First Letter of a Model Property

I'm trying to create an UITableView with alphabetical order headers depending on my businessName property's first letter of my Company model, and then hide the header sections if there's not a company in the collection that starts with a letter. I'm already fetching the companies into the controller, but I'm having difficulty with limiting my companies into the right section and then hiding the sections that don't have the businessName's first letter.
// Current situation
// What I'm looking for
// Company Model
`struct Company {
var uid: String
var businessAddress: String
var businessName: String
init(dictionary: [String : Any]) {
self.uid = dictionary["uid"] as? String ?? ""
self.businessAddress = dictionary["businessAddress"] as? String ?? ""
self.businessName = dictionary["businessName"] as? String ?? ""
}
}`
// Service
`struct EmployeeService {
static func fetchCompanies(completion: #escaping([Company]) -> Void) {
var companies = [Company]()
let query = REF_COMPANIES.order(by: "businessName")
query.addSnapshotListener { snapshot, error in
snapshot?.documentChanges.forEach({ change in
let dictionary = change.document.data()
let company = Company(dictionary: dictionary)
companies.append(company)
companies.sort {
$0.businessName < $1.businessName
}
completion(companies)
})
}
}
}`
// CompanySelectionController
`class CompanySelectionController: UIViewController {
// MARK: - Properties
var companies = [Company]()
let sectionTitles = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".map(String.init)
}
// MARK: - UITableViewDataSource
extension CompanySelectionController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return sectionTitles.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return companies.count
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
// Create the header view
let headerView = UIView.init(frame: CGRectMake(0, 0, self.view.frame.size.width, 40))
headerView.backgroundColor = UIColor.groupTableViewBackground
// Create the Label
let label = UILabel(frame: CGRectMake(10, -40, 120, 60))
label.font = UIFont(name: "AvenirNext-DemiBold", size: 16)
label.textAlignment = .left
label.text = sectionTitles[section]
// Add the label to your headerview
headerView.addSubview(label)
return headerView
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifiers.CompanySelectionCell, for: indexPath) as! CompanySelectionCell
cell.selectionStyle = .none
cell.company = companies[indexPath.row]
return cell
}
}`
// CompanySelectionCell
`protocol CompannyViewModelItem {
var type: CompannyViewModelItemType { get }
var rowCount: Int { get }
var sectionTitle: String { get }
}
class CompanySelectionCell: UITableViewCell {
// MARK: - Properties
var company: Company! {
didSet {
configure()
}
}
private let businessNameLabel: UILabel = {
let label = UILabel()
label.font = UIFont(name: "AvenirNext-DemiBold", size: 14)
label.textColor = .black
label.textAlignment = .left
return label
}()
private let businessAddressLabel: UILabel = {
let label = UILabel()
label.font = UIFont(name: "AvenirNext-MediumItalic", size: 12)
label.textColor = .darkGray
label.textAlignment = .left
return label
}()
lazy var businessStack = UIStackView(arrangedSubviews: [businessNameLabel, businessAddressLabel])
// MARK: - Lifecycle
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Helper Functions
fileprivate func configure() {
guard let company = company else { return }
let viewModel = CompannyViewModel(company: company)
businessNameLabel.text = viewModel.businessName
businessAddressLabel.text = viewModel.businessAddress
}
}`
// CompannyViewModel
enum CompannyViewModelItemType { case uid case businessName }
I have tried changing the label property inside viewForHeaderInSection to try and conform to the right letter, but the screenshot of my problem has been the furthest I've got.
Your problem is your datasource for the UITableView. What you're using is actually a static structure with 26 sections (all letters) and you're appending all your companies to every section. That is happening here:
func numberOfSections(in tableView: UITableView) -> Int {
return sectionTitles.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return companies.count
}
To show what you actually want you need a different datastructure like a nested Array to fill your table view.
let dataSource: [String: [Company]] = // however you want to read the data in here
func numberOfSections(in tableView: UITableView) -> Int {
dataSource.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
datasource[section].count
}
To create the datasource you'd need to go through all your companies and only fill the letters (section) of the ones actually existing.
Edit: I'd highly recommend you using AutoLayout to create your views

black area above navigation bar appears when search bar is not active?

I have a search controller added to navigationController.searchController. When the screen initially loads there is a black space above the navigation bar. Only when I tap on the search bar this space correctly shows white. When I tap off the search bar, this area shows black again.
import UIKit
import Foundation
import InstantSearch
class AlgoliaViewController: UIViewController, UISearchBarDelegate {
let userHitsInteractor: HitsInteractor<User> = .init(infiniteScrolling: .off, showItemsOnEmptyQuery: false)
let businessHitsInteractor: HitsInteractor<Business> = .init(infiniteScrolling: .off, showItemsOnEmptyQuery: false)
let multiSearch = MultiIndexSearcher(appID: APP_ID, apiKey: APP_KEY, indexNames: ["dev_USERS","dev_BUSINESS"])
lazy var multiConnector: MultiIndexSearchConnector = .init(searcher: multiSearch, indexModules: [
.init(indexName: "dev_USERS",
hitsInteractor: userHitsInteractor),
.init(indexName: "dev_BUSINESS",
hitsInteractor: businessHitsInteractor)
], searchController: searchController, hitsController: hitsTableViewController)
lazy var searchController: UISearchController = .init(searchResultsController: hitsTableViewController)
let hitsTableViewController = MultiIndexController()
let statsInteractor: StatsInteractor = .init()
override func viewDidLoad() {
super.viewDidLoad()
multiConnector.connect()
multiSearch.search()
statsInteractor.connectController(self)
setupUI()
}
func setupUI() {
view.backgroundColor = .white
navigationItem.searchController = searchController
navigationController?.navigationBar.backgroundColor = .white
// navigationItem.titleView = searchController.searchBar
navigationController?.navigationBar.backgroundColor = .white
navigationController?.navigationBar.isTranslucent = false
navigationController?.hidesBarsOnSwipe = false
searchController.hidesNavigationBarDuringPresentation = false
searchController.showsSearchResultsController = true
searchController.automaticallyShowsCancelButton = false
searchController.searchBar.delegate = self
searchController.obscuresBackgroundDuringPresentation = false
hitsTableViewController.view.backgroundColor = .white
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchController.isActive = true
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
searchController.isActive = false
}
}
extension AlgoliaViewController: StatsTextController {
func setItem(_ item: String?) {
title = item
}
}
class MultiIndexController: UITableViewController, MultiIndexHitsController {
var hitsSource: MultiIndexHitsSource?
let cellID = "cellID"
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(ResultsItemCell.self, forCellReuseIdentifier: cellID)
setupUI()
self.tableView.keyboardDismissMode = .onDrag
}
func setupUI() {
view.backgroundColor = .white
tableView.backgroundColor = .white
tableView.separatorStyle = .none
}
override func numberOfSections(in tableView: UITableView) -> Int {
return (hitsSource?.numberOfSections())!
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (hitsSource?.numberOfHits(inSection: section)) ?? 0
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 50))
let sectionTitle = UILabel(frame: CGRect(x: 0, y: 0, width: headerView.frame.width, height: headerView.frame.height))
Utilities.styleLblFont(sectionTitle, fontName: "Cabin-SemiBold", fontSize: 18, color: .black)
var headertitle = ""
switch section {
case 0:
print("section 0")
headertitle = "People"
case 1:
print("section 1")
headertitle = "Businesses"
default:
break
}
headerView.backgroundColor = .white
sectionTitle.text = headertitle
headerView.addSubview(sectionTitle)
return headerView
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellID) as! ResultsItemCell
switch indexPath.section {
case 0:
if let item: User = try? hitsSource?.hit(atIndex: indexPath.row, inSection: indexPath.section) {
cell.nameLbl.text = item.userName
cell.avatar.loadImage(item.profilePhotoUrl)
cell.jobTitleLbl.text = item.userType
}
case 1:
if let business: Business = try? hitsSource?.hit(atIndex: indexPath.row, inSection: indexPath.section) {
cell.nameLbl.text = business.businessName
cell.avatar.loadImage(business.businessAvatarUrl)
cell.jobTitleLbl.text = business.mission
}
default:
break
}
return cell
}
override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 50))
let seeResultsBtn = UIButton(frame: CGRect(x: 0, y: 0, width: footerView.frame.width, height: footerView.frame.height))
var footerTitle = ""
switch section {
case 0:
footerTitle = "See all people"
case 1:
footerTitle = "See all businesses"
default:
footerTitle = "See all results"
}
footerView.addSubview(seeResultsBtn)
seeResultsBtn.translatesAutoresizingMaskIntoConstraints = false
seeResultsBtn.centerYAnchor.constraint(equalTo: footerView.centerYAnchor).isActive = true
seeResultsBtn.centerXAnchor.constraint(equalTo: footerView.centerXAnchor).isActive = true
Utilities.buttonTitle(seeResultsBtn, title: footerTitle, titleColour: .jabiMain, fontName: "Cabin-Medium", fontSize: 16)
footerView.backgroundColor = .white
return footerView
}
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 50
}
}
Please see the screenshots:

EXC_BAD_ACCESS UITable set tableHeaderView in numberOfRowsInSection

I'm trying to set tableHeaderView in numberOfRowsInSection. But I'm getting EXC_BAD_ACCESS with no message in the output console.
Below is my numberOfRowsInSection function.
// number of rows in table view
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//SECTION 1
if self.titles.count == 0 {
self.noBookmarkView.alpha = 1.0
}
else {
self.noBookmarkView.alpha = 0.0
}
//=====================================
//SECTION 2
if self.idsb.count != self.ids.count {
self.bookmarkTableView.tableHeaderView = self.filteredView
}
else {
self.bookmarkTableView.tableHeaderView = nil
}
//=====================================
return self.titles.count
}
And below is my viewDidLoad where I initialize filteredView
#IBOutlet weak var noBookmarkView: UIView!
var filteredView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
filteredView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: bookmarkTableView.frame.width, height: 25))
filteredView.backgroundColor = UIColor.init(red: 0.4, green: 0.4, blue: 0.71, alpha: 1.0)
let label: UILabel = UILabel.init(frame: filteredView.frame)
label.text = "Filtered"
label.font = UIFont.init(name: "System", size: 14.0)
label.adjustsFontSizeToFitWidth = true
filteredView.addSubview(label)
}
So before I added filteredView it worked perfectly with the noBookmarkView.
Now it has the error EXC_BAD_ACCESS on self.noBookmarkView.alpha = 0.0. If I comment out SECTION 2 it works without errors. If I comment out SECTION 1 it then has EXC_BAD_ACCESS on line self.bookmarkTableView.tableHeaderView = nil.
I don't understand why it would fail on self.noBookmarkView.alpha = 0.0 when it seems like SECTION 2 is what is causing the problem.
How can I fix this?
You should provide header via the dataSource of the UITableView:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return self.filteredView
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 25
}

How to make custom header then image description belongs to that Header and same process is carry on in TableView

I'm building a project for what i have to make a tableview in which i have to include the images of three groups with their names and positions.
Groups are as follows: (1).OFFICE BEARERS (2).MEMBERS (3).CO-OPTED MEMBERS.
I want to make group as Heading and then want to show the images of the members which corresponds to that group with their NAME And DESIGNATION.Then another group as headings and images of the members which belongs to them. and so on. Sample Image is given below
Every group have many members so i want to use dynamic cells.
What are the best practice to do that... Please help me
Note: Images are residing in my Project's assets.
Image of tableview is like so..
Prepare a data structure, for example like this:
[
{
"name": "group name"
"members": [{
"image":"member image"
"designation":"member image"
},
{
"image":"member image"
"designation":"member image"
}]
},
{
"name": "group name"
"members": [{
"image":"member image"
"designation":"member image"
},
{
"image":"member image"
"designation":"member image"
}]
}
]
Parse this data structure into model objects shown below or you can use Dictionaries.
class Group: NSObject {
var name:String!
var members:[Member]!
}
class Member: NSObject {
var image:UIImage!
var designation:String!
}
and then use in your tableView as shown below
var groups:[Group]!
func numberOfSections(in tableView: UITableView) -> Int {
return groups.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return groups[section].members.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let group = groups[section] as Group
return group.name
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell Identifier", for: indexPath)
let member = groups[indexPath.section].members[indexPath.row]
cell.imageView?.image = member.image
cell.textLabel?.text = member.designation
return cell
}
UITableView supports headers and footers, using the UITableViewdelegate methods tableView:HeightForHeaderInSection and tableView:viewForHeaderInSection and make sure you populate your cells correctly by the sectionand row. The indexPath.section will tell which header the cell is under and the indexPath.row will tell which cell by order it is in that section.
I create expand tableview , this may be help full for you
class Order_History_ViewController: BASEVC,UITableViewDelegate ,UITableViewDataSource
{
#IBOutlet weak var tableview: UITableView!
#IBOutlet weak var menu: UIButton!
var order : NSMutableArray = NSMutableArray()
var product : NSMutableArray = NSMutableArray()
var fruit1 = ["product_name":"Apple","unit":"500 gms","img":"fruit_apple.jpeg","price":"Rs.150","shop_name":"C.G.FOOD"]
var fruit2 = ["product_name":"Banana","unit":"12 pc","img":"fruit_banana.jpeg","price":"Rs.50","shop_name":"Fresh Supply"]
var fruit3 = ["product_name":"Cherry","unit":"250 gms","img":"fruit_cherry.jpeg","price":"Rs.60","shop_name":"C.G.FOOD"]
var fruit4 = ["product_name":"Grape","unit":"250 gms","img":"fruit_grape.jpeg","price":"Rs.30","shop_name":"C.G.FOOD"]
var fruit5 = ["product_name":"Mango","unit":"500 gms","img":"fruit_mango.jpeg","price":"Rs.100","shop_name":"Cayce Food"]
var order_date = ["Fri, March 11, 2016","Fri, March 04, 2016"]
var order_number = ["Order #246","Order #126"]
var price = ["Rs.390","Rs.330"]
var charge = ["Rs.50","Rs.50"]
var total = ["Rs.440","Rs.380"]
var Fees : Double = Double()
var btnHeaderTag : Int!
var upDownImageView : UIImageView = UIImageView()
var isImgChange : Bool = false
override func viewDidLoad()
{
super.viewDidLoad()
product.addObject(fruit1)
product.addObject(fruit2)
product.addObject(fruit3)
product.addObject(fruit4)
product.addObject(fruit5)
let order1Dic : NSMutableDictionary = NSMutableDictionary()
order1Dic["isExpandable"] = 0
order1Dic["Data"] = product
let order2Dic : NSMutableDictionary = NSMutableDictionary()
order2Dic["isExpandable"] = 1
order2Dic["Data"] = product
order.addObject(order1Dic)
order.addObject(order2Dic)
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
{
return 150
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
let view = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 100))
//Header view
let headerView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 49))
let OrderDate = UILabel(frame: CGRect(x: 10, y: 10, width: 150, height: 30))
OrderDate.textColor = UIColor(red: 24/255, green: 24/255, blue: 24/255, alpha: 1)
OrderDate.font = UIFont(name: "JosefinSans-Regular_0.ttf", size: 23)
OrderDate.text = order_date[section]
headerView.addSubview(OrderDate)
headerView.backgroundColor = UIColor(red: 198/255, green: 198/255, blue: 198/255, alpha: 1)
upDownImageView = UIImageView(frame: CGRect(x: self.view.frame.width - 35, y: 23, width: 15, height: 10))
upDownImageView.image = UIImage(named: "select_time_arrow")
if self.btnHeaderTag != nil
{
if section == self.btnHeaderTag
{
if !self.isImgChange
{
upDownImageView.image = UIImage(named: "select_time_arrow")
}
else if self.isImgChange
{
upDownImageView.image = UIImage(named: "down_arrow")
}
}
}
headerView.addSubview(upDownImageView)
let btn = UIButton(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 49))
btn.addTarget(self, action: #selector(Order_History_ViewController.onHeaderClick(_:)), forControlEvents: .TouchUpInside)
btn.tag = section
print(btn.tag)
headerView.addSubview(btn)
view.addSubview(headerView)
return view
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return order.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
if btnHeaderTag != nil
{
if let isExpandable = self.order[btnHeaderTag].valueForKey(EXPANDABLE_KEY) as? Int
{
if section == btnHeaderTag
{
if isExpandable == 1
{
// product details
if let _ = self.order[btnHeaderTag].valueForKey("Data") as? NSMutableArray
{
return product.count
}
}
else if isExpandable == 0
{
return 0
}
}
}
}
return 0
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("history_cell", forIndexPath: indexPath)as!Cart_TableView_Cell
let dataDict : NSDictionary = product[indexPath.row] as! NSDictionary
cell.lblProduct_Name.text = dataDict["product_name"] as? String
cell.lblShop_Name.text = dataDict["shop_name"] as? String
cell.lblUnit.text = dataDict["unit"] as? String
cell.lblPrice.text = dataDict["price"] as? String
let img = dataDict["img"] as? String
cell.img_Product.image = UIImage(named:img!)
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath)
{
}
func onHeaderClick(button : UIButton)
{
print("click")
btnHeaderTag = button.tag
print(btnHeaderTag)
for (index,value) in self.order.enumerate()
{
if index == btnHeaderTag
{
if let isExpandable = value.valueForKey(EXPANDABLE_KEY) as? Int
{
if isExpandable == 0
{
value.setValue(1, forKey: EXPANDABLE_KEY)
self.isImgChange = true
}
else
{
value.setValue(0, forKey: EXPANDABLE_KEY)
self.isImgChange = false
}
}
}
else
{
value.setValue(0, forKey: EXPANDABLE_KEY)
}
}
self.tableview.reloadData()
}
Here is the sample code:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 4;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if (section==0)
return 5;
else
return 3;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return 60.0f;
}
-(nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
UIView *view1=[[UIView alloc] initWithFrame:CGRectMake(0.0f, 20.0f, tableView.bounds.size.width, 60.0f)];
view1.backgroundColor=[UIColor clearColor];
UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(0.0f, 20.0f, tableView.bounds.size.width, 40.0f)];
label.text=#" Appointment";
label.textColor=[UIColor whiteColor];
label.backgroundColor=[UIColor colorWithRed:1.0f/255.0f green:67.0/255.0f blue:102.0f/255.0f alpha:1];
label.textAlignment=NSTextAlignmentLeft;
label.numberOfLines=0;
[view1 addSubview:label];
return view1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier=#"BOOKINGDETAILS";
BookingDetailsTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:identifier];
if (cell==nil) {
cell=[[BookingDetailsTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
cell.lblStatic.text=[arrStatic objectAtIndex:indexPath.row];
cell.lblresult.text=[arrData objectAtIndex:indexPath.row];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
return cell;
}

TableView's textLabel height according to content

I have made an Collapsed TableView. The size of the tableView's label is not increasing according the content. I had set WordWrap and Lines = 0 but still it's not working.
I'm using 2 tableView cell's to make the collapsed view.
extension UIView {
func rotate(toValue: CGFloat, duration: CFTimeInterval = 0.2, completionDelegate: AnyObject? = nil) {
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotateAnimation.toValue = toValue
rotateAnimation.duration = duration
rotateAnimation.removedOnCompletion = false
rotateAnimation.fillMode = kCAFillModeForwards
if let delegate: AnyObject = completionDelegate {
rotateAnimation.delegate = delegate
}
self.layer.addAnimation(rotateAnimation, forKey: nil)
}
}
class CollapsibleTableViewController: UITableViewController {
struct Section {
var name: String!
var items: [String]!
var collapsed: Bool!
init(name: String, items: [String], collapsed: Bool = false) {
self.name = name
self.items = items
self.collapsed = collapsed
}
}
var sections = [Section]()
override func viewDidLoad() {
super.viewDidLoad()
sections = [Section(name: "TEXT OVER HERE", items: ["TEXT OVER HERE."])]
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sections.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (sections[section].collapsed!) ? 0 : sections[section].items.count
}
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableCellWithIdentifier("header") as! CollapsibleTableViewHeader
header.toggleButton.tag = section
header.titleLabel.text = sections[section].name
header.toggleButton.rotate(sections[section].collapsed! ? 0.0 : CGFloat(M_PI_2))
header.toggleButton.addTarget(self, action: #selector(CollapsibleTableViewController.toggleCollapse), forControlEvents: .TouchUpInside)
return header.contentView
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell!
cell.textLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping
cell.textLabel?.numberOfLines = 0
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row]
return cell
}
//
// MARK: - Event Handlers
//
func toggleCollapse(sender: UIButton) {
let section = sender.tag
let collapsed = sections[section].collapsed
// Toggle collapse
sections[section].collapsed = !collapsed
// Reload section
tableView.reloadSections(NSIndexSet(index: section), withRowAnimation: .Automatic)
}
}
try this code:
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
var lblSectionName: UILabel = UILabel()
lblSectionName.text = self.sectionNames[section]
lblSectionName.numberOfLines = 0
lblSectionName.lineBreakMode = .ByWordWrapping
lblSectionName.sizeToFit()
return lblSectionName.frame.size.height
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
var lblSectionName: UILabel = UILabel()
lblSectionName.text = self.sectionNames[section]
lblSectionName.numberOfLines = 0
lblSectionName.lineBreakMode = .ByWordWrapping
lblSectionName.sizeToFit()
return lblSectionName
}
Better is this answer: https://stackoverflow.com/a/29763200/1054550
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionHeaderHeight = 25;

Resources