Ios UICollectionView的SectionIndexTitles

Ios UICollectionView的SectionIndexTitles,ios,ios5,ios6,uicollectionview,Ios,Ios5,Ios6,Uicollectionview,因此,我实现了一个适当的TableView,带有搜索功能和sectionIndexTitles。现在,我正在尝试实现一个UICollectionView,到目前为止,它一直在工作,只是我无法轻松获得sectionIndexTitles(右滚动条) 如果我看一下Facebook应用程序,它看起来像一个UICollectionView,但实际上它有sectionIndexTitles和一个搜索栏。对于UICollectionView模型,我似乎找不到这样的函数 有什么想法吗 谢谢 您可以通过为以下函

因此,我实现了一个适当的
TableView
,带有搜索功能和
sectionIndexTitles
。现在,我正在尝试实现一个
UICollectionView
,到目前为止,它一直在工作,只是我无法轻松获得
sectionIndexTitles
(右滚动条)

如果我看一下Facebook应用程序,它看起来像一个
UICollectionView
,但实际上它有
sectionIndexTitles
和一个搜索栏。对于
UICollectionView
模型,我似乎找不到这样的函数

有什么想法吗

谢谢


您可以通过为以下函数实现并返回值来提供此标题


请注意,标题的大小将来自从方法collectionView:layout:ReferenceSizeForHeaderInstitution:

返回的CGRect的高度值。我有一个类似的要求(对于水平集合视图),最后自己构建了一个索引视图子类

我计划将其开源,但这可能要等到下个月,所以这里有一个存根让您开始:

YMCollectionIndexView.h

@interface YMCollectionIndexView : UIControl

- (id) initWithFrame:(CGRect)frame indexTitles:(NSArray *)indexTitles;

// Model
@property (strong, nonatomic) NSArray *indexTitles; // NSString
@property (readonly, nonatomic) NSUInteger currentIndex;
- (NSString *)currentIndexTitle;

@end
YMCollectionIndexView.m

#import "YMCollectionIndexView.h"

@interface YMCollectionIndexView ()
@property (readwrite, nonatomic) NSUInteger currentIndex;
@property (strong, nonatomic) NSArray *indexLabels;
@end

@implementation YMCollectionIndexView

- (id) initWithFrame:(CGRect)frame indexTitles:(NSArray *)indexTitles {
    self = [super initWithFrame:frame];
    if (self) {
        self.indexTitles = indexTitles;
        self.currentIndex = 0;
        // add pan recognizer
    }
    return self;
}

- (void)setIndexTitles:(NSArray *)indexTitles {
    if (_indexTitles == indexTitles) return;
    _indexTitles = indexTitles;
    [self.indexLabels makeObjectsPerformSelector:@selector(removeFromSuperview)];
    [self buildIndexLabels];
}

- (NSString *)currentIndexTitle {
    return self.indexTitles[self.currentIndex];
}

#pragma mark - Subviews

- (void) buildIndexLabels {
    CGFloat cumulativeItemWidth = 0.0; // or height in your (vertical) case
    for (NSString *indexTitle in self.indexTitles) {
            // build and add label
        // add tap recognizer
    }
    self.indexLabels = indexLabels;
}

#pragma mark - Gestures

- (void) handleTap:(UITapGestureRecognizer*)recognizer {
    NSString *indexTitle = ((UILabel *)recognizer.view).text;
    self.currentIndex = [self.indexTitles indexOfObject:indexTitle];
    [self sendActionsForControlEvents:UIControlEventTouchUpInside];
}

// similarly for pan recognizer

@end
在视图控制器中:

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.collectionIndexView addTarget:self action:@selector(indexWasTapped:) forControlEvents:UIControlEventTouchUpInside];
    // similarly for pan recognizer
}

- (void)indexWasTapped:(id)sender {
    [self.collectionView scrollToIndexPath:...];
}

// similarly for pan recognizer
编辑:这已被验证为已修复,并在iOS 14中按预期工作 您现在可以简单地使用(从iOS 10.3开始)

可选函数索引(对于collectionView:UICollectionView)->[String]?

它需要一个类似以下的数组:
['A','B','C']

作为它的返回值。

从iOS 14开始(它大大增强了
UICollectionView
,特别是使
UITableView
过时),通过实现委托方法
indexTitles
索引标题确实在iOS上起作用,但在我测试时,它似乎只在iOS 14+上起作用

func indexTitles(for collectionView: UICollectionView) -> [String]? {
    return Array(Set(objects.map{ String($0.name.prefix(1)) })).sorted(by: { $0 < $1 })
}

func collectionView(_ collectionView: UICollectionView, indexPathForIndexTitle title: String, at index: Int) -> IndexPath {
    guard let index = objects.firstIndex(where: { $0.name.prefix(1) == title }) else {
        return IndexPath(item: 0, section: 0)
    }
    return IndexPath(item: index, section: 0)
}
func索引标题(对于collectionView:UICollectionView)->[String]?{
返回数组(Set(objects.map{String($0.name.prefix(1))}))。排序(按:{$0<$1})
}
func collectionView(collectionView:UICollectionView,indexPathForIndexTitle标题:字符串,索引:Int)->IndexPath{
guard let index=objects.firstIndex(其中:{$0.name.prefix(1)==title})else{
返回IndexPath(项:0,节:0)
}
返回IndexPath(项:索引,节:0)
}

问题指的是屏幕右侧的
部分索引
,而不是补充部分标题。我也想得到一个好的答案;如果可能的话,我还想避免隐藏另一个表视图(内存问题)。这看起来很棒!如果你把它开源,我敢肯定,整个iOS社区都会喜欢你的。赏金!我在-让我知道你的想法-中快速实现了一个完整的实现(使用writeup)。看起来@BenKreeger为他的解决方案创建了一个GitHub repo/CoCoCoapod:这对任何人都有效?即使在一个简单的例子中,我也无法调用indexTitles func。我也无法让它在iOS上工作(还没有尝试tvOS)。在线文档说明它在iOS 10.3+和tvOS 10.2+上可用,但从头文件看,它只说API_可用(tvOS(10.2))。我在苹果开发者论坛上发布了一个问题,不幸的是,这只在tvOS上实现,尽管在线文档中另有说明。我已经为此申请了一个雷达。我只是简单地把它添加到我的数据源中就可以工作。
func indexTitles(for collectionView: UICollectionView) -> [String]? {
    return Array(Set(objects.map{ String($0.name.prefix(1)) })).sorted(by: { $0 < $1 })
}

func collectionView(_ collectionView: UICollectionView, indexPathForIndexTitle title: String, at index: Int) -> IndexPath {
    guard let index = objects.firstIndex(where: { $0.name.prefix(1) == title }) else {
        return IndexPath(item: 0, section: 0)
    }
    return IndexPath(item: index, section: 0)
}