最近的新項目有一個如下的界面
而設(shè)計的要求是這樣的
于是我開始了百度 google stackOverFlow ...都沒有找到合適的方法.StackOverFlow上的解決方法是給每一個字符后添加一個空字符,注意是數(shù)組中的元素后.這也數(shù)組長度變大,這樣indexTitle中間插入一些空格索引.看起來是變長了,但是需要在返回section高度和返回sectionview以及返回section和index關(guān)聯(lián)三個代理方法中分別設(shè)置對于空字符的處理.較為麻煩 而且布局也不夠美觀.詳見[StackOverFlow]--UITableView section index spacing on iOS 7
另外也有國內(nèi)開發(fā)者對這篇文章的翻譯見[4byte.cn]--在iOS 7表格部分指標(biāo)間距
下面介紹我的方法,先介紹下整體思路.我是自定義一個indexview,indexview的高度設(shè)置為控制器view減去導(dǎo)航條高度和tabbar高度乘以0.910.91是一個比例系數(shù),可以適當(dāng)調(diào)高和調(diào)低
,放在控制器indexview上.再根據(jù)sectionTitles的數(shù)量來創(chuàng)建多個letterLabel放在.每個letterLabel高度為indexview的高度除以數(shù)組的個數(shù),letterLabel的text設(shè)置為數(shù)組中各個字符.這樣就能保證indexview的高度更加填充慢屏幕,并且每個letterLabel距離平均分布.而對于點擊indexview調(diào)轉(zhuǎn)到對應(yīng)的section,我是這樣解決的.通過給indexview添加一個tap手勢,再通過手勢的位置Y除以indexview高度乘以letterLabel高度得到點擊的索引indexPath,然后讓table滾動到對應(yīng)的索引.具體代碼如下.[Github]-解決tableview的sectionIndex不能平均分布問題
1.創(chuàng)建indexView,指定frame
// 113為導(dǎo)航欄高度64 + tabar高度49
let indexViewH = (kScreenH - 113) * 0.91
// 這樣設(shè)置Y保證indexview居中顯示
let indexViewY = ((kScreenH - 113) - indexViewH) * 0.5 + 64
let indexView = UIView(frame: CGRect(x: kScreenW - 15, y: indexViewY, width: 10, height: indexViewH))
2.根據(jù)數(shù)據(jù)源數(shù)組個數(shù)添加LetterLabel
// 獲取數(shù)組個數(shù)
let count = CGFloat(self.brandList.count)
// 利用EnumerateSequence遍歷可以獲得帶index的元組
for (index,letter) in EnumerateSequence(self.brandList.map{ $0.letter! }) {
// 設(shè)置letterLabelfram和字體顏色等
let letterLabel = UILabel(frame: CGRect(x: 0, y: indexViewH / count * CGFloat(index) , width: 12, height: indexViewH / count))
letterLabel.font = UIFont.systemFontOfSize(12)
letterLabel.textColor = QGColor.GrayColor
letterLabel.text = letter
indexView.addSubview(letterLabel)
}
3.給indexView添加手勢
let touch = UITapGestureRecognizer(target: self, action: "indexViewTap:")
indexView.addGestureRecognizer(touch)
4.通過手勢讓tableview滾動到指定的section
// 手勢響應(yīng)的方法
func indexViewTap(tap: UITapGestureRecognizer) {
// 獲得點擊手勢在indexview的坐標(biāo)Y
let touchY = tap.locationInView(indexView).y
// 利用坐標(biāo)Y獲得一個索引也就是letterLabel在indexview的索引
let index = Int(touchY / indexView.bounds.height * CGFloat(brandList.count))
// 創(chuàng)建indexPath 讓tableview滾動到該位置
let indexPath = NSIndexPath(forRow: 0, inSection: index)
tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
}
如果你覺得這個方法不錯,可以這樣來使用我的代碼.把UITbleview+Extension
拖入你的項目,或者只把代碼拷到你寫tableview分類的文件.然后在有需要設(shè)置sectionindex的控制器這樣設(shè)置tableview
就可以了
// self.brandList為[String]類型的數(shù)組 我的示例代碼中brandList中放的是對象,所以用map去得到一個純字符串的數(shù)組
tableView.setIndexViewWith(self.brandList.map{ $0.letter! })
// 由于這個方法后兩個參數(shù)有默認值 傳和不傳都可以 這句代碼就是傳入自定義的索引文字顏色和文字大小
tableView.setIndexViewWith(self.brandList.map{ $0.letter! }, letterColor: UIColor.grayColor(), letterFont: UIFont.systemFontOfSize(12))