Пользовательский индекс раздела UITableView - PullRequest
18 голосов
/ 13 мая 2011

Можно ли настроить индекс раздела UITableView?Я имею в виду изменение стиля / размера шрифта, фона (который по умолчанию является полупрозрачным) и т. Д. Я предполагаю, что ответом будет НЕТ.

Итак, есть ли какие-либо решения с открытым исходным кодом, которые могутиспользоваться для реализации пользовательского индекса раздела UITableView?Если нет, то как мне создать такой компонент / элемент управления / представление?

Ответы [ 9 ]

24 голосов
/ 16 мая 2012

Обновление (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, а при пролистывании манипулировал табличным представлением напрямую (устраняя необходимость в делегате).но индексному представлению не принадлежит табличное представление, поэтому оно кажется неправильным.

14 голосов
/ 12 ноября 2013
self.tableView.sectionIndexColor = [UIColor brownColor];
self.tableView.sectionIndexBackgroundColor = [UIColor clearColor];
self.tableView.sectionIndexTrackingBackgroundColor = [UIColor blueColor];
10 голосов
/ 29 октября 2012

В iOS 6 вы можете настроить индекс таблицы, используя методы, описанные ниже в UITableView:

  • sectionIndexMinimumDisplayRowCount
  • sectionIndexColor
  • sectionIndexTrackingBackgroundColor
7 голосов
/ 03 июня 2011

В итоге я использовал пользовательский вид.Невозможно настроить индекс таблицы.

6 голосов
/ 27 октября 2015

Swift версия:

tableView.sectionIndexBackgroundColor = UIColor.clearColor()
tableView.sectionIndexTrackingBackgroundColor = UIColor.clearColor()
tableView.sectionIndexColor = UIColor.redColor()

Чтобы настроить высоту представления индекса (только для стиля UITableViewStylePlain):

tableView.sectionIndexMinimumDisplayRowCount = 15
2 голосов
/ 06 февраля 2013

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;
1 голос
/ 23 августа 2017

Возможно настроить его, если вы в порядке с доступом к частным свойствам. Я верю, что это пройдет одобрение магазина, но не верьте мне на слово. Вот свойства / функции, к которым вы могли бы получить доступ. 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()
        }
    }

}
1 голос
/ 30 октября 2014

его помощь для ios 6 и ios 7 & 8

if ([tableview respondsToSelector:@selector(setSectionIndexColor:)])
{

    if(!IS_IOS6)
    {

        tableview.sectionIndexBackgroundColor = [UIColor clearColor];
    }
    tableview.sectionIndexColor = [UIColor whiteColor];
}
1 голос
/ 17 декабря 2013

Я запустил пользовательскую реализацию индекса таблицы на GitHub.Вы можете попробовать это: https://github.com/r-dent/RGIndexView Не стесняйтесь вносить свой вклад.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...