เคลื่อนไหวเฟรมและการเปลี่ยนแปลงเค้าโครงของ UICollectionView

ฉันกำลังพยายามสร้างเอฟเฟกต์โดยเปลี่ยนเค้าโครงของ UICollectionView ในขณะที่เปลี่ยนขนาดเฟรม

ในตอนแรก เค้าโครง collectionView จะแสดงสไตล์แกลเลอรี "ภาพขนาดย่อ" แบบเต็มหน้าจอ

หลังจากปรับขนาดกรอบเป็นแถบบางๆ - ผมขอนำเสนอเค้าโครงสไตล์ "แถบฟิล์ม"

ทั้งสองเลย์เอาต์ทำงานได้ดีและเป็นไปตามที่คาดไว้

ฉันลองใช้โค้ดที่คล้ายกับสิ่งนี้:

[UIView animateWithDuration:1
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
                         self.collectionview.frame = newFrame; // animate the frame size


                     }
                     completion:^(BOOL finished) {
                        [self.collectionView.collectionViewLayout invalidateLayout];

    [self.collectionView setCollectionViewLayout:filmstriplayout animated:YES];    // now set the new layout
                     }];

แต่มันดูขาด ๆ หาย ๆ และไม่ปรับขนาดตามที่คาดไว้

มีวิธีใดที่ฉันสามารถเปลี่ยนเค้าโครงมุมมองคอลเลกชันและขนาดเฟรมพร้อมกันในขณะที่ทำให้การเปลี่ยนแปลงเคลื่อนไหวได้หรือไม่


person Avner Barr    schedule 08.09.2013    source แหล่งที่มา
comment
คุณเคยได้รับทางออกที่ดีหรือไม่? performBatchUpdates:withCompletion: นั้นดี แต่ไม่ได้ช่วยในการรวมการเปลี่ยนแปลง frame หรือ contentOffset แบบเคลื่อนไหว ฉันต้องการสิ่งนี้เพื่อให้การซูมแอนิเมชั่นราบรื่นเด้งกลับมา โดยที่เค้าโครงของฉันและ contentOffset ขึ้นอยู่กับการซูม   -  person Benjohn    schedule 02.08.2015
comment
@Benjohn คุณ พบวิธีแก้ปัญหาที่ดีหรือไม่? เพิ่งเจอสิ่งเดียวกันและคำตอบที่มีอยู่ไม่เหมาะ ...   -  person aheze    schedule 21.06.2021
comment
@aheze ขออภัย ฉันไม่รู้ — มันไกลเกินกว่าที่ฉันจำได้ตอนนี้ :-/   -  person Benjohn    schedule 21.06.2021


คำตอบ (3)


ขั้นแรกให้ตั้งค่าขนาดรายการกริดเช่น gridItemSize = CGSizeMake(98, 98); จากนั้นดำเนินการแบบแบตช์ของ UICollectionView รายการในมุมมองคอลเลกชันจะเปลี่ยนขนาดตามภาพเคลื่อนไหว :)

- (CGSize)collectionView:(UICollectionView *)collectionView
                  layout:(UICollectionViewLayout*)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
   return CGSizeMake(gridItemSize.width, gridItemSize.height);
}

[self.collectionview performBatchUpdates:^{
    [self.collectionview.collectionViewLayout invalidateLayout];
    [self.collectionview setCollectionViewLayout:self.collectionview.collectionViewLayout animated:YES];
} completion:^(BOOL finished) {    
}];
person Zulqarnain    schedule 04.11.2013
comment
นี่เป็นสิ่งที่มีประโยชน์ แต่ แล้วการเปลี่ยนแปลงเฟรมภาพเคลื่อนไหวนั้น ที่เกิดขึ้นในเวลาเดียวกันล่ะ ในทำนองเดียวกัน ฉันคิดว่า contentOffset เปลี่ยนแปลงใช่ไหม ฉันยังต้องการให้ทั้งสองอย่างเกิดขึ้นพร้อมกัน - person Benjohn; 02.08.2015
comment
ในกรณีการใช้งานของฉัน flowLayout ของฉันต้องแตกต่างออกไปเมื่อมีการเลื่อนและเมื่อเป็นแบบคงที่ สิ่งที่ฉันทำคือ: (ที่ 1) ตั้งค่าสถานะในเค้าโครงและใช้โค้ดด้านบนเพื่อทำให้เค้าโครงไม่ถูกต้อง (ที่ 2) scrollToIndexPath เคลื่อนไหวโดยใช้ collectionViewMethod เริ่มต้น (ครั้งที่ 3) รีเซ็ตแฟล็กเค้าโครงและใช้โค้ดด้านบนอีกครั้งเพื่อทำให้เคลื่อนไหวกลับสู่สถานะดั้งเดิม ฉันไม่สามารถบรรลุผลตามที่ต้องการด้วยการสร้างภาพเคลื่อนไหวพร้อมกันได้ ดังนั้นฉันจึงจัดคิวภาพเคลื่อนไหวไว้ - person marcelosalloum; 23.10.2019
comment
[self.collectionview.collectionViewLayout invalidateLayout]; เป็นเลขคี่ที่นี่ ซึ่งทำให้เกิดข้อบกพร่องในแอนิเมชัน - person surfrider; 22.05.2020

ฉันไม่มีคำตอบที่เฉพาะเจาะจง แต่มีข้อเสนอแนะบางประการที่ต้องพิจารณา

UICollectionView ไม่สามารถจัดการการสลับอินสแตนซ์เค้าโครงได้อย่างสวยงามเสมอไป นี่คือการสนทนาเกี่ยวกับปัญหาและวิธีแก้ไขปัญหาชั่วคราวที่ดี

แต่สิ่งที่ฉันได้ทำจริง ๆ ในทางปฏิบัติซึ่งได้ผลสำหรับฉันคือการใช้ทั้งสองเลย์เอาต์ในออบเจ็กต์เลย์เอาต์เดียวที่รู้วิธีสลับระหว่างโหมดเลย์เอาต์ ฉันพบว่าการสลับโหมดเค้าโครงในบล็อกการอัปเดตเป็นชุดมีปัญหาน้อยกว่าการใช้ setCollectionViewLayout กับอินสแตนซ์เค้าโครงที่แตกต่างกันสองรายการ:

[self.collectionView performBatchUpdates:^{
    MyLayout *layout = (MyLayout *)self.collectionView.collectionViewLayout;
    layout.mode = otherLayoutMode;
} completion:nil];
person Timothy Moose    schedule 08.09.2013
comment
คุณใช้อะไร performBatchUpdates:? - person alltom; 09.05.2014
comment
การตั้งค่าอินสแตนซ์ใหม่ในระหว่างการอัพเดตจริงเหรอ? ในที่สุดมันจะทำให้แอปของคุณเสียหาย - person Abdul Yasin; 02.02.2021

นี่คือเคล็ดลับง่ายๆ ทุกครั้งที่คุณอัปเดต CollectionView ให้ใช้สิ่งนี้:

[self.collectionView removeFromSuperview]; //First remove the Collection View

//Relocate the view with layouts
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
layout.minimumInteritemSpacing = 10;
layout.minimumLineSpacing = 10;

 self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.width,100) collectionViewLayout:layout];
[self.collectionView setDataSource:self];
[self.collectionView setDelegate:self];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellIdentifier"];
[self.collectionView reloadData];

[self.view addSubview:self.collectionView];
person Shivam Singh    schedule 22.02.2016