ก่อนโหลดมุมมองคอลเลกชันผู้ใช้ตั้งค่าจำนวนภาพในอาร์เรย์ของมุมมองคอลเลกชัน เซลล์ทั้งหมดไม่พอดีกับหน้าจอ ฉันมี 30 เซลล์และมีเพียง 6 เซลล์บนหน้าจอ
คำถาม: จะเลื่อนไปยังเซลล์ด้วยภาพที่ต้องการโดยอัตโนมัติที่โหลด UICollectionView ได้อย่างไร?
ก่อนโหลดมุมมองคอลเลกชันผู้ใช้ตั้งค่าจำนวนภาพในอาร์เรย์ของมุมมองคอลเลกชัน เซลล์ทั้งหมดไม่พอดีกับหน้าจอ ฉันมี 30 เซลล์และมีเพียง 6 เซลล์บนหน้าจอ
คำถาม: จะเลื่อนไปยังเซลล์ด้วยภาพที่ต้องการโดยอัตโนมัติที่โหลด UICollectionView ได้อย่างไร?
คำตอบ:
ฉันพบว่าการเลื่อนเข้าviewWillAppear
อาจทำงานได้ไม่น่าเชื่อถือเนื่องจากมุมมองคอลเลกชันยังไม่เสร็จสิ้นการจัดวาง คุณอาจเลื่อนไปที่รายการที่ไม่ถูกต้อง
ฉันยังพบว่าการเลื่อนเข้าviewDidAppear
จะทำให้เห็นแฟลชชั่วขณะของมุมมองที่ไม่ได้เลื่อน
และหากคุณเลื่อนทุกครั้งviewDidLayoutSubviews
ผู้ใช้จะไม่สามารถเลื่อนด้วยตนเองได้เนื่องจากเค้าโครงคอลเลกชันบางส่วนทำให้เค้าโครงมุมมองย่อยทุกครั้งที่คุณเลื่อน
นี่คือสิ่งที่ฉันพบว่าทำงานได้อย่างน่าเชื่อถือ:
วัตถุประสงค์ C:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
// If we haven't done the initial scroll, do it once.
if (!self.initialScrollDone) {
self.initialScrollDone = YES;
[self.collectionView scrollToItemAtIndexPath:self.myInitialIndexPath
atScrollPosition:UICollectionViewScrollPositionRight animated:NO];
}
}
รวดเร็ว:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if (!self.initialScrollDone) {
self.initialScrollDone = true
self.testNameCollectionView.scrollToItem(at:selectedIndexPath, at: .centeredHorizontally, animated: true)
}
}
[self.collectionView layoutIfNeeded];
viewDidLoad
ใหม่คำตอบที่แก้ไข:
เพิ่มสิ่งนี้ใน viewDidLayoutSubviews
SWIFT
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let indexPath = IndexPath(item: 12, section: 0)
self.collectionView.scrollToItem(at: indexPath, at: [.centeredVertically, .centeredHorizontally], animated: true)
}
โดยปกติ.centerVertically
เป็นกรณี
ObjC
-(void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:12 inSection:0];
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically | UICollectionViewScrollPositionCenteredHorizontally animated:NO];
}
คำตอบเก่าใช้ได้กับ iOS รุ่นเก่า
เพิ่มสิ่งนี้ในviewWillAppear
:
[self.view layoutIfNeeded];
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO];
indexPath
:[NSIndexPath indexPathForItem:numberOfTheObject inSection:sectionNumber]
ฉันเห็นด้วยอย่างยิ่งกับคำตอบข้างต้น สิ่งเดียวคือสำหรับฉันการแก้ปัญหาคือการตั้งรหัสใน viewDidAppear
viewDidAppear
{
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES];
}
เมื่อฉันใช้ viewWillAppear การเลื่อนไม่ทำงาน
สิ่งนี้ดูเหมือนจะใช้ได้ผลสำหรับฉันมันคล้ายกับคำตอบอื่น แต่มีความแตกต่างที่ชัดเจน:
- (void)viewDidLayoutSubviews
{
[self.collectionView layoutIfNeeded];
NSArray *visibleItems = [self.collectionView indexPathsForVisibleItems];
NSIndexPath *currentItem = [visibleItems objectAtIndex:0];
NSIndexPath *nextItem = [NSIndexPath indexPathForItem:someInt inSection:currentItem.section];
[self.collectionView scrollToItemAtIndexPath:nextItem atScrollPosition:UICollectionViewScrollPositionNone animated:YES];
}
รวดเร็ว:
your_CollectionView.scrollToItemAtIndexPath(indexPath, atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: true)
สวิฟต์ 3
let indexPath = IndexPath(row: itemIndex, section: sectionIndex)
collectionView.scrollToItem(at: indexPath, at: UICollectionViewScrollPosition.right, animated: true)
ตำแหน่งเลื่อน:
UICollectionViewScrollPosition.CenteredHorizontally / UICollectionViewScrollPosition.CenteredVertically
คุณสามารถใช้ GCD เพื่อส่งการเลื่อนไปยังการวนซ้ำถัดไปของลูปรันหลักใน viewDidLoad เพื่อให้บรรลุพฤติกรรมนี้ การเลื่อนจะดำเนินการก่อนที่จะแสดงมุมมองคอลเลคชันบนหน้าจอดังนั้นจะไม่มีการกะพริบ
- (void)viewDidLoad {
dispatch_async (dispatch_get_main_queue (), ^{
NSIndexPath *indexPath = YOUR_DESIRED_INDEXPATH;
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
});
}
ฉันขอแนะนำให้ทำในcollectionView: willDisplay:
จากนั้นคุณสามารถมั่นใจได้ว่าผู้รับมอบสิทธิ์มุมมองคอลเลกชันส่งมอบบางสิ่ง นี่คือตัวอย่างของฉัน:
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
/// this is done to set the index on start to 1 to have at index 0 the last image to have a infinity loop
if !didScrollToSecondIndex {
self.scrollToItem(at: IndexPath(row: 1, section: 0), at: .left, animated: false)
didScrollToSecondIndex = true
}
}
เป็นอีกทางเลือกหนึ่งที่กล่าวมาข้างต้น โทรหลังจากโหลดข้อมูล:
รวดเร็ว
collectionView.reloadData()
collectionView.layoutIfNeeded()
collectionView.selectItem(at: indexPath, animated: true, scrollPosition: .right)
คำตอบทั้งหมดที่นี่ - แฮ็ก ฉันพบวิธีที่ดีกว่าในการเลื่อนมุมมองคอลเลคชันที่ใดที่หนึ่งหลังจาก relaodData:
Subclass collection view เลย์เอาท์ที่คุณเคยใช้มาแทนที่วิธีการจัดเตรียมการจัดเตรียมหลังจาก super call ตั้งค่าสิ่งที่จะชดเชยที่คุณต้องการ
เช่นhttps://stackoverflow.com/a/34192787/1400119
initialScrollDone
แฟล็กตามที่ LenK ทำเนื่องจากวิธีนี้จะถูกเรียกมากกว่าหนึ่งครั้งและถ้าคุณเรียก scrollToItemAtIndexPath: มากกว่าหนึ่งครั้งดูเหมือนว่าจะแสดงคอลเลคชันดูไม่สามารถเลื่อนได้ (iOS จำลอง iPhone 5 / iOS 8)