Подтвердить что ты не робот

Пользовательский индекс раздела UITableView

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

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

4b9b3361

Ответ 1

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

Ответ 2

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

Ответ 3

self.tableView.sectionIndexColor = [UIColor brownColor];
self.tableView.sectionIndexBackgroundColor = [UIColor clearColor];
self.tableView.sectionIndexTrackingBackgroundColor = [UIColor blueColor];

Ответ 4

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

  • sectionIndexMinimumDisplayRowCount
  • sectionIndexColor
  • sectionIndexTrackingBackgroundColor

Ответ 5

Быстрая версия:

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

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

tableView.sectionIndexMinimumDisplayRowCount = 15

Ответ 6

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;

Ответ 7

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

Ответ 8

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

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

    if(!IS_IOS6)
    {

        tableview.sectionIndexBackgroundColor = [UIColor clearColor];
    }
    tableview.sectionIndexColor = [UIColor whiteColor];
}

Ответ 9

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

}