Custom Uitableview Section Index

Customizing Section indexes in UITableView in iphone application

It doesn't look like standard index view is customizable.

In my application I just created custom index view instead of standard one. Basically all you need to do here is track touch position in that view and scroll UITableView accordingly. You may also need to add some visual effects - change view's background color on touch and highlight current section title.

Custom UITableView section index

I ended up using a custom view. It's not possible to customize the table index.

Adding section index headers for A to Z UITableView scrolling

Should we be sorting the Array into an alphabetised Array in some sort? So that it has multiple sections?

Yes.

You added the delegate methods for the section index, but you didn't show any code that actually performed the collation.

Here's some sample code from NSHipster showing how to use UILocalizedIndexedCollation to collate an array of objects (e.g., contacts) into an array of sections of objects (e.g., contacts grouped by section):

let collation = UILocalizedIndexedCollation.currentCollation()
var sections: [[AnyObject]] = []
var objects: [AnyObject] = [] {
didSet {
let selector: Selector = "localizedTitle"
sections = Array(count: collation.sectionTitles.count, repeatedValue: [])

let sortedObjects = collation.sortedArrayFromArray(objects, collationStringSelector: selector)
for object in sortedObjects {
let sectionNumber = collation.sectionForObject(object, collationStringSelector: selector)
sections[sectionNumber].append(object)
}

self.tableView.reloadData()
}
}

You'll also want to update your remaining tableView delegates to use the sections array:

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sections.count
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].count
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let contact = sections[indexPath.section][indexPath.row]
...
}

FYI, you can simplify your delegate code by assigning the collation property to your view controller, instead of repeatedly declaring a local variable for the (current) collation inside each delegate method. For example:

override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String {
return collation.sectionTitles[section]
}

Adding index list and section headers to translated tableview

There are a few ways to accomplish this. One of the simplest is to use the delegate functions provided with UITableView.

For organizational purposes I'd start by creating a class to represent sections. Something like this:

class GhostSection {

// a title for this section
var sectionTitle: String

// a list of items for this particular section
var items: [Ghost] = []

init(title: String, items: [Ghost]) {
sectionTitle = title
self.items = items
}
}

Then update the list variable to use the sections instead of a raw list of items:

var tabledata = [GhostSections]()

Ideally I'd create my GhostSection from a json object, but if it must be done manually then something like this would work:

// setup the table data to use GhostSection instances for each section
var tabledata = [
GhostSection(title: "a", items: [Ghost(name:"an".localized, sort:"sort.an".localized, id:"0101")]),
GhostSection(title: "b", items: [Ghost(name:"bc".localized, sort:"sort.bc".localized, id:"0102")]),
GhostSection(title: "c", items: [Ghost(name:"cd".localized, sort:"sort.cd".localized, id:"0103")])
]

I'd have numberOfSections(in tableView: UITableView) return the tabledata count, which would be the count of the total number of sections:

func numberOfSections(in tableView: UITableView) -> Int {
return tabledata.count
}

and the numberOfRowsInSection return the list count for each items array on each GhostSection in your tabledata array:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tabledata[section].items.count
}

Then I'd update cellForRow(at indexPath) to return the info for the right cell in that section:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "library", for: indexPath)
// this gets the section data, then gets the item from that section
var data = list[indexPath.section].items[indexPath.row]
cell.textLabel?.text = data.name
return cell

}

I also like to create my headers as reusable nib views, so the ListHeaderView just has a title label in it:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

// this loads the view from the nib
guard let view = ListHeaderView.fromNib() as? ListHeaderView else {
return nil
}

// get the section object for this current section
let data = tabledata[section]

// and set the title label text here from our section object
view.titleLabel.text = data.sectionTitle
return view
}

// if you want to also have a custom footer you can do that here...
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
return UIView()
}

// and let the header height be dynamic, or return a set height here...
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return UITableViewAutomaticDimension
}

In case you want to use this approach here's how I implemented the fromNib() function so you can instantiate any view that has an associated .xib file:

public extension UIView {

public static func fromNib() -> UIView? {
let nibName = String(describing: self)
let bundle = Bundle(for: self)
let nib = UINib(nibName: nibName, bundle: bundle)
guard let view = nib.instantiate(withOwner: nil, options: nil).first as? UIView else {
print("Unable to instantiate nib named: \(nibName) in bundle: \(String(describing: bundle)) -- nib: \(String(describing: nib))")
return nil
}
return view
}
}

Also note it's a good idea to get in the habit of using camel case for class/object names with the first letter capitalized IF you want to keep with current conventions. So instead of naming your class ghost get in the habit of doing Ghost. For variables the convention is also camel case but start with a lowercase.

How to get custom section index titles as in Contacts app in iPhone

Got solution,
i followed this link: https://developer.apple.com/documentation/uikit/uilocalizedindexedcollation

class ObjectTableViewController: UITableViewController {
let collation = UILocalizedIndexedCollation.currentCollation()
var sections: [[AnyObject]] = []
var objects: [AnyObject] = [] {
didSet {
let selector: Selector = "localizedTitle"
sections = Array(count: collation.sectionTitles.count, repeatedValue: [])

let sortedObjects = collation.sortedArrayFromArray(objects, collationStringSelector: selector)
for object in sortedObjects {
let sectionNumber = collation.sectionForObject(object, collationStringSelector: selector)
sections[sectionNumber].append(object)
}

self.tableView.reloadData()
}
}

// MARK: UITableViewDelegate

override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String {
return collation.sectionTitles[section]
}

override func sectionIndexTitlesForTableView(tableView: UITableView) -> [String] {
return collation.sectionIndexTitles
}

override func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
return collation.sectionForSectionIndexTitleAtIndex(index)
}
}

UITableview Sections Indexing Click Event

You can use the tableView(_:sectionForSectionIndexTitle:at:) method to return the appropriate section index when a index title is clicked.

let sectionArr = ["a","a","b","c","d","d"]
func numberOfSections(in tableView: UITableView) -> Int {
return sectionArr.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sectionArr[section]
}
func sectionIndexTitles(for tableView: UITableView) -> [String]? {
return Array(Set(sectionArr))//["a","b","c","d"]
}
func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
if let index = sectionArr.firstIndex(where: { $0 == title }) {
return index//0 for a, 2 for b, 3 for c, 4 for d
}
return 0
}


Related Topics



Leave a reply



Submit