因此,我使用搜索功能和TableView
实施了正确的sectionIndexTitles
。现在,我正在尝试实现UICollectionView
并且它到目前为止工作,除了我不能轻易拥有sectionIndexTitles
(右滚动条)。
如果我查看Facebook应用程序,它看起来像UICollectionView
,但确实是sectionIndexTitles
和搜索栏。我似乎无法为UICollectionView
模型找到这样的函数。
有什么想法吗?!
谢谢!
答案 0 :(得分:16)
我有一个类似的要求(对于水平集合视图)并最终自己构建索引视图子类。
我打算开源,但这可能要等到下个月,所以这里有一个存根让你开始:
<强> 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
答案 1 :(得分:1)
从iOS 14开始(已对UICollectionView
进行了重大增强,尤其是使UITableView
过时),此方法可以通过实现委托方法indexTitles
来实现。
答案 2 :(得分:0)
您找到了解决方案吗?
我正在尝试为UICollectionView实现相同的功能。
到目前为止,sectionIndexTitles我使用的自定义UITableView与原始UICollectionView具有相同的部分,但是使用空单元格。结果我有一个IndexTableView类
indexTableView = [[IndexTableView alloc] initWithFrame:CGRectZero];
[self.view addSubview:indexTableView];
...
indexTableView.frame = CGRectMake(CGRectGetWidth(self.view.frame) - 40, 0, 40, CGRectGetHeight(self.view.frame));
indexTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
indexTableView.sectionHeaderHeight = 0;
indexTableView.backgroundColor = [UIColor clearColor];
我在UICollectionView的顶部添加了IndexTableView,并获得了与原始UITableView相同的视觉效果。 现在我正在尝试链接索引选择和UICollectionView并使其工作。
<强>编辑:强> 我刚刚将UISearchBar添加到UICollectionController
将以下代码添加到UICollectionController的子类
- (void)viewDidLoad
{
[super viewDidLoad];
...
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.collectionView.frame.size.width, 44)];
self.searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
self.searchBar.delegate = self;
[self.collectionView addSubview:self.searchBar];
[self.collectionView setContentOffset:CGPointMake(44, 0)];
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
if (section == 0) {
return UIEdgeInsetsMake(CGRectGetHeight(self.searchBar.frame), 6, 0, 6);
}
return UIEdgeInsetsMake(0, 6, 0, 6);
}
答案 3 :(得分:0)
索引标题确实适用于 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)
}
答案 4 :(得分:-1)
您现在可以简单地使用(从iOS 10.3开始)
optional func indexTitles(for collectionView: UICollectionView) -> [String]?
哪个阵列喜欢:
['A', 'B' ,'C']
作为其返回值。
答案 5 :(得分:-2)
您可以通过为UICollectionViewDataSource
实现并返回以下函数的值来提供此标头collectionView:viewForSupplementaryElementOfKind:atIndexPath:
请注意,标题的大小将来自UICollectionViewFlowLayoutDelegate方法collectionView:layout:referenceSizeForHeaderInSection:
返回的CGRect的高度值