Ответ 1
Я закончил использование пользовательского представления. Невозможно настроить индекс таблицы.
Можно ли настроить индекс раздела UITableView? Я имею в виду изменение стиля/размера шрифта, фона (который по умолчанию полупрозрачен) и т.д. Я предполагаю, что ответ будет НЕТ.
Итак, существуют ли какие-либо решения с открытым исходным кодом, которые можно использовать для реализации пользовательского индекса раздела UITableView? Если нет, как мне нужно создавать такой компонент/элемент управления/просмотр?
Я закончил использование пользовательского представления. Невозможно настроить индекс таблицы.
Обновление (2017-08-31): Наконец отредактировано для ARC, современных Objective-C и iOS SDK (отклонения API).
Я сделал этот класс некоторое время назад. Не стесняйтесь использовать его в качестве ссылки. У него нет никаких свойств для установки внешнего вида, но вы можете изменять их непосредственно в исходном коде (в нем много жестко закодированных констант, расстояний, цветов и т.д.).
#import <UIKit/UIKit.h>
@class TableIndexView;
@protocol TableIndexViewDelegate <NSObject>
- (void) tableIndexView:(TableIndexView*) tableIndexView
didSwipeToSection:(NSUInteger) section;
@end
@interface TableIndexView : UIView
@property (nonatomic, weak) id<TableIndexViewDelegate> delegate;
@property (nonatomic) NSUInteger numberOfSections;
- (id)initWithTableView:(UITableView *)tableView;
@end
#import "TableIndexView.h"
#import <QuartzCore/QuartzCore.h>
#define TableIndexViewDefaultWidth 20.0f
#define TableIndexViewDefaultMargin 16.0f
@interface TableIndexView()
@property (nonatomic) NSUInteger currentSection;
@property (nonatomic, strong) UIView* backgroundView;
@property (nonatomic, strong) UIView* contentView;
- (void)show;
- (void)hide;
@end
@implementation TableIndexView
@synthesize delegate = _delegate;
@synthesize numberOfSections = _numberOfSections;
- (id)initWithTableView:(UITableView *)tableView {
CGRect tableBounds = [tableView bounds];
CGRect outerFrame = CGRectZero;
outerFrame.origin.x = tableBounds.size.width - (40 + TableIndexViewDefaultWidth);
outerFrame.origin.y = 0;
outerFrame.size.width = (40 + TableIndexViewDefaultWidth);
outerFrame.size.height = tableBounds.size.height;
CGRect indexFrame = CGRectZero;
indexFrame.origin.x = tableBounds.size.width - (TableIndexViewDefaultWidth + TableIndexViewDefaultMargin);
indexFrame.origin.y = TableIndexViewDefaultMargin;
indexFrame.size.width = TableIndexViewDefaultWidth;
indexFrame.size.height = tableBounds.size.height - 2*TableIndexViewDefaultMargin;
if ((self = [super initWithFrame:outerFrame])) {
// Initialization code
self.backgroundColor = [UIColor clearColor];
[self setUserInteractionEnabled:YES];
// Content View (Background color, Round Corners)
indexFrame.origin.x = 20;
_backgroundView = [[UIView alloc] initWithFrame:indexFrame];
_backgroundView.backgroundColor = [UIColor colorWithRed:1.00f
green:1.00f
blue:1.00f
alpha:0.75f];
CGFloat radius = 0.5f*TableIndexViewDefaultWidth;
_backgroundView.layer.cornerRadius = radius;
[self addSubview:_backgroundView];
_numberOfSections = [[tableView dataSource] numberOfSectionsInTableView:tableView];
CGRect contentFrame = CGRectZero;
contentFrame.origin.x = 0;
contentFrame.origin.y = radius;
contentFrame.size.width = TableIndexViewDefaultWidth;
contentFrame.size.height = indexFrame.size.height - 2*radius;
_contentView = [[UIView alloc] initWithFrame:contentFrame];
_contentView.backgroundColor = [UIColor clearColor];
[_backgroundView addSubview:_contentView];
CGFloat labelWidth = contentFrame.size.width;
CGFloat labelHeight = 12;
CGFloat interLabelHeight = (contentFrame.size.height - (_numberOfSections)*labelHeight)/(_numberOfSections - 1.0);
CGFloat fontSize = 12;
for (NSUInteger i=0; i < _numberOfSections; i++) {
if ( _numberOfSections > 20 && i%2 == 0 ) {
// Skip even section labels if count is greater than, say, 20
continue;
}
CGRect labelFrame = CGRectZero;
labelFrame.size.width = labelWidth;
labelFrame.size.height = labelHeight;
labelFrame.origin.x = 0;
labelFrame.origin.y = i*(labelHeight+interLabelHeight);
UILabel* label = [[UILabel alloc] initWithFrame:labelFrame];
label.text = [NSString stringWithFormat:@"%lu", i+1];
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor blackColor];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont systemFontOfSize:floorf(1.0f*fontSize)];
[_contentView addSubview:label];
}
[_backgroundView setHidden:YES];
}
return self;
}
#pragma mark - Control Actions
- (void)didTap:(id) sender {
[_backgroundView setHidden:NO];
}
- (void)didRelease:(id) sender {
[_backgroundView setHidden:YES];
}
#pragma mark - Internal Operation
- (void)show {
[self didTap:nil];
}
- (void)hide {
[self didRelease:nil];
}
#pragma mark - UIResponder Methods
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInView:_contentView];
CGFloat ratio = location.y / _contentView.frame.size.height;
NSUInteger newSection = ratio*_numberOfSections;
if (newSection != _currentSection) {
_currentSection = newSection;
[_delegate tableIndexView:self didSwipeToSection:_currentSection];
}
[_backgroundView setHidden:NO];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInView:_contentView];
CGFloat ratio = location.y / _contentView.frame.size.height;
NSUInteger newSection = ratio*_numberOfSections;
if (newSection != _currentSection) {
_currentSection = newSection;
if (newSection < _numberOfSections) {
if (_delegate) {
[_delegate tableIndexView:self didSwipeToSection:_currentSection];
}
else{
// **Perhaps call the table view directly
}
}
}
[_backgroundView setHidden:NO];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[_backgroundView setHidden:YES];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[_backgroundView setHidden:YES];
}
@end
И наконец, делегат представления индекса (который идеально представляет собой делегат таблицы/источник данных) делает это при уведомлении:
(например, реализация подкласса UITableViewController)
- (void) tableIndexView:(TableIndexView *)tableIndexView didSwipeToSection:(NSUInteger)section {
[_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]
atScrollPosition:UITableViewScrollPositionTop
animated:NO];
}
Кроме того, вы можете заставить TableIndexView указывать указатель на UITableView в ivar, а при прокрутке - непосредственно обрабатывать представление таблицы (устраняя необходимость в делетете). но индексный вид не имеет вида таблицы, поэтому он выглядит неправильно.
self.tableView.sectionIndexColor = [UIColor brownColor];
self.tableView.sectionIndexBackgroundColor = [UIColor clearColor];
self.tableView.sectionIndexTrackingBackgroundColor = [UIColor blueColor];
В iOS 6 вы можете настроить индекс таблицы, используя приведенные ниже методы в UITableView:
Быстрая версия:
tableView.sectionIndexBackgroundColor = UIColor.clearColor()
tableView.sectionIndexTrackingBackgroundColor = UIColor.clearColor()
tableView.sectionIndexColor = UIColor.redColor()
Чтобы настроить высоту индексного вида (только стиль UITableViewStylePlain
):
tableView.sectionIndexMinimumDisplayRowCount = 15
https://github.com/Hyabusa/CMIndexBar
Используйте этот плагин из Hyabusa. Простая замена для индекса UITableView, который позволяет устанавливать цвета
CMIndexBar *indexBar = [[CMIndexBar alloc] initWithFrame:CGRectMake(self.view.frame.size.width-35, 10.0, 28.0, self.view.frame.size.height-20)];
[indexBar setIndexes:[NSMutableArray arrayWithObjects:@"A",@"B",@"C",@"D",@"E",@"F",@"G", nil]];
[self.view addSubview:indexBar];
[indexBar release];
делегат
- (void)indexSelectionDidChange:(CMIndexBar *)IndexBar:(int)index:(NSString*)title;
Я начал собственную реализацию индекса таблицы в GitHub. Вы можете попробовать следующее: https://github.com/r-dent/RGIndexView Не стесняйтесь вносить свой вклад.
его помощь для ios 6 и ios 7 & 8
if ([tableview respondsToSelector:@selector(setSectionIndexColor:)])
{
if(!IS_IOS6)
{
tableview.sectionIndexBackgroundColor = [UIColor clearColor];
}
tableview.sectionIndexColor = [UIColor whiteColor];
}
Можно настроить его, если вы в порядке с доступом к приватным свойствам. Я верю, что это пройдет одобрение магазина, но не верьте мне на слово. Вот свойства/функции, к которым вы могли бы получить доступ. https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UITableViewIndex.h
Я тестировал изменение шрифта следующим образом: он работал.
func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async { [unowned self] in
if let tableViewIndex = self.tableView.subviews.first(where: { String(describing: type(of: $0)) == "UITableViewIndex" }) {
tableViewIndex.setValue(*Insert Font Here*, forKey: "font")
self.tableView.reloadSectionIndexTitles()
}
}
}