ios 自定义 UITableView 部分索引

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5987399/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 19:54:04  来源:igfitidea点击:

Custom UITableView section index

iosuitableviewindexing

提问by Mustafa

Is it possible to customize the UITableView's section index? I mean, changing the font style/size, background (which is semitransparent by default) etc. I'm guessing that the answer would be NO.

是否可以自定义 UITableView 的部分索引?我的意思是,更改字体样式/大小、背景(默认情况下是半透明的)等。我猜答案是否定的。

So, are there any open-source solutions out there that can be used for implementing a custom UITableView section index? If not, how should i go about creating such a component/control/view?

那么,是否有任何开源解决方案可用于实现自定义 UITableView 部分索引?如果没有,我应该如何创建这样的组件/控件/视图?

采纳答案by Mustafa

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

我最终使用了自定义视图。无法自定义表索引。

回答by Nicolas Miari

Update (2017-08-31):Finally edited for ARC, modern Objective-C and iOS SDK (API deprecations).

更新 (2017-08-31):最终针对 ARC、现代 Objective-C 和 iOS SDK(API 弃用)进行了编辑。

I made this class some time ago. Feel free to use it as reference. It does not have any properties to set the appearance, but you can modify those directly in the source code (it has lots of hard-coded constants, distances, colors etc.)

我前段时间做了这门课。随意使用它作为参考。它没有任何设置外观的属性,但您可以直接在源代码中修改这些属性(它有很多硬编码的常量、距离、颜色等)

Interface:

界面:

#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

Implementation:

执行:

#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

And finally, the index view's delegate (which ideally is the table view's delegate/data source) does this on notification:

最后,索引视图的委托(理想情况下是表视图的委托/数据源)在通知时执行此操作:

(e.g., UITableViewController subclass implementation)

(例如, UITableViewController 子类实现)

- (void) tableIndexView:(TableIndexView *)tableIndexView didSwipeToSection:(NSUInteger)section {
    [_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]
                      atScrollPosition:UITableViewScrollPositionTop
                              animated:NO];
}

Alternatively, you can have the TableIndexView keep a pointer to the UITableView in an ivar, and on swipe, manipulate the table view directly (obviating the need for a delegate). but the index view does not own the table view, so it kind of feels wrong.

或者,您可以让 TableIndexView 在 ivar 中保留指向 UITableView 的指针,并在滑动时直接操作表视图(无需委托)。但是索引视图不拥有表视图,所以感觉有点不对。

回答by NamshanNet

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

回答by Ash

In iOS 6 you can configure the Table Index using the methods below on UITableView:

在 iOS 6 中,您可以在 UITableView 上使用以下方法配置表索引:

  • sectionIndexMinimumDisplayRowCount
  • sectionIndexColor
  • sectionIndexTrackingBackgroundColor
  • sectionIndexMinimumDisplayRowCount
  • 部分索引颜色
  • sectionIndexTrackingBackgroundColor

回答by SoftDesigner

Swift version:

迅捷版:

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

To customize the index view height (UITableViewStylePlainstyle only):

自定义索引视图高度(UITableViewStylePlain仅限样式):

tableView.sectionIndexMinimumDisplayRowCount = 15

回答by Patrick

It is possible to adjust it if you're okay with accessing private properties. I believe this would pass store approval but don't take my word for it. Here are the properties/functions you would be able to access. https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UITableViewIndex.h

如果您可以访问私有属性,则可以对其进行调整。我相信这会通过商店的批准,但不要相信我的话。以下是您可以访问的属性/功能。https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UITableViewIndex.h

I've tested changing the font with the following and it worked.

我已经测试过使用以下更改字体并且它有效。

func viewDidLoad() {
    super.viewDidLoad()

    DispatchQueue.main.async { [unowned self] in
        if let tableViewIndex = self.tableView.subviews.first(where: { String(describing: type(of: 
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];
)) == "UITableViewIndex" }) { tableViewIndex.setValue(*Insert Font Here*, forKey: "font") self.tableView.reloadSectionIndexTitles() } } }

回答by Emile Khattar

https://github.com/Hyabusa/CMIndexBar

https://github.com/Hyabusa/CMIndexBar

Use this plugin from Hyabusa. Simple replacment for UITableView Index that allows setting of colors

使用 Hyabusa 的这个插件。允许设置颜色的 UITableView 索引的简单替换

- (void)indexSelectionDidChange:(CMIndexBar *)IndexBar:(int)index:(NSString*)title;

Delegate

代表

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

    if(!IS_IOS6)
    {

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

回答by r-dent

I started a custom implementation of the table index on GitHub. You may try this one: https://github.com/r-dent/RGIndexViewFeel free to contribute.

我开始在 GitHub 上自定义表索引的实现。你可以试试这个:https: //github.com/r-dent/RGIndexView随意贡献。

回答by KumarS

its help for ios 6 and ios 7&8

它对 ios 6 和 ios 7&8 的帮助

##代码##