Tôi đã được cân nhắc một thuật toán mà sẽ cho phép bạn biết khi người dùng đã cuộn qua một tiêu đề phần để cập nhật tiêu đề, và sau một số thử nghiệm tôi đã tìm ra cách để thực hiện hành vi mong muốn.
Về cơ bản, mỗi lần thay đổi vị trí cuộn, bạn cần biết phần người dùng đang ở trên và cập nhật tiêu đề. Bạn làm điều này thông qua scrollViewDidScroll
trên UIScrollViewDelegate
- ghi nhớ chế độ xem bộ sưu tập là chế độ xem cuộn. Lặp qua tất cả các tiêu đề và tìm một tiêu đề gần nhất với vị trí cuộn hiện tại, mà không có chênh lệch âm. Để làm điều đó, tôi sử dụng một thuộc tính lưu trữ một mảng của từng vị trí của phần đầu. Khi một tiêu đề được tạo, tôi lưu trữ vị trí của nó trong mảng tại chỉ mục thích hợp. Khi bạn đã tìm thấy tiêu đề gần nhất với vị trí cuộn của bạn (hoặc vị trí chỉ mục của tiêu đề đã nói), chỉ cần cập nhật tiêu đề trong thanh điều hướng có tiêu đề phù hợp.
Trong viewDidLoad
, điền vào bất động sản mảng với NSNull
cho mỗi phần bạn có:
self.sectionHeaderPositions = [[NSMutableArray alloc] init];
for (int x = 0; x < self.sectionTitles.count; x++) {
[self.sectionHeaderPositions addObject:[NSNull null]];
}
Trong collectionView:viewForSupplementaryElementOfKind:atIndexPath:
, cập nhật các mảng với vị trí của các điểm tiêu đề tạo:
NSNumber *position = [NSNumber numberWithFloat:headerView.frame.origin.y + headerView.frame.size.height];
[self.sectionHeaderPositions replaceObjectAtIndex:indexPath.section withObject:position];
Trong scrollViewDidScroll:
, thực hiện các tính toán để xác định tiêu đề nào phù hợp để hiển thị cho vị trí cuộn đó:
CGFloat currentScrollPosition = self.collectionView.contentOffset.y + self.collectionView.contentInset.top;
CGFloat smallestPositiveHeaderDifference = CGFLOAT_MAX;
int indexOfClosestHeader = NSNotFound;
//find the closest header to current scroll position (excluding headers that haven't been reached yet)
int index = 0;
for (NSNumber *position in self.sectionHeaderPositions) {
if (![position isEqual:[NSNull null]]) {
CGFloat floatPosition = position.floatValue;
CGFloat differenceBetweenScrollPositionAndHeaderPosition = currentScrollPosition - floatPosition;
if (differenceBetweenScrollPositionAndHeaderPosition >= 0 && differenceBetweenScrollPositionAndHeaderPosition <= smallestPositiveHeaderDifference) {
smallestPositiveHeaderDifference = differenceBetweenScrollPositionAndHeaderPosition;
indexOfClosestHeader = index;
}
}
index++;
}
if (indexOfClosestHeader != NSNotFound) {
self.currentTitle.text = self.sectionTitles[indexOfClosestHeader];
} else {
self.currentTitle.text = self.sectionTitles[0];
}
Điều này sẽ cập nhật chính xác tiêu đề trong thanh điều hướng khi người dùng cuộn qua tiêu đề cho một phần.Nếu họ cuộn ngược lên, nó cũng sẽ cập nhật chính xác. Nó cũng chính xác đặt tiêu đề khi chúng không cuộn qua phần đầu tiên. Tuy nhiên nó không xử lý luân chuyển rất tốt. Nó cũng sẽ không hoạt động tốt nếu bạn có nội dung động, điều này có thể khiến vị trí được lưu trữ của chế độ xem tiêu đề không chính xác. Và nếu bạn hỗ trợ nhảy tới một phần cụ thể, người dùng sẽ nhảy đến phần có tiêu đề phần của phần trước chưa được tạo và phần đó không đủ cao sao cho tiêu đề phần nằm bên dưới thanh điều hướng (phần cuối cùng) có lẽ), tiêu đề không chính xác sẽ được hiển thị trong thanh điều hướng.
Nếu bất cứ ai có thể cải thiện điều này để làm cho nó hiệu quả hơn hoặc tốt hơn thì hãy làm và tôi sẽ cập nhật câu trả lời cho phù hợp.
Bạn có tìm thấy giải pháp để có được hành vi mong muốn không? – Joey
hello @Joey kiểm tra câu trả lời của tôi. – KDeogharkar