2015-12-07 13 views
29

मैंने एक UICollectionView बनाया है, ताकि मैं साफ कॉलम में दृश्य व्यवस्थित कर सकूं। मैं चाहता हूं कि डिवाइस पर 500 स्तंभ पिक्सेल चौड़े हों।UICollectionView - डिवाइस घुमाने पर कोशिकाओं का आकार बदलना - स्विफ्ट

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { 
    let size = collectionView.frame.width 
    if (size > 500) { 
     return CGSize(width: (size/2) - 8, height: (size/2) - 8) 
    } 
    return CGSize(width: size, height: size) 
} 

यह काम करता है पहले लोड पर अपेक्षा के अनुरूप है, लेकिन जब मैं डिवाइस घुमाने के लिए, गणना हमेशा फिर से नहीं होता है, और विचारों डॉन:

इस लक्ष्य को हासिल करने के लिए, मैं इस समारोह के लिए बनाया अपेक्षित के रूप में हमेशा redraw नहीं है। यहाँ जब डिवाइस घुमाया जाता है के लिए अपने कोड है:

override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) { 
    collectionView.collectionViewLayout.invalidateLayout() 
    self.view.setNeedsDisplay() 
} 

मैं यह सोचते हैं रहा हूँ मैं कुछ पुनः बनाने का भूल गया हूँ, लेकिन मुझे यकीन है कि क्या नहीं कर रहा हूँ। किसी भी विचार बहुत आभारी हैं!

उत्तर

18

आप viewWillLayoutSubviews का उपयोग कर सकते हैं। This question सहायक होना चाहिए, लेकिन जब भी व्यू कंट्रोलर दृश्य अपने सबव्यूज़ लेआउट के बारे में है, तो इसे बास्केटिक रूप से बुलाया जाता है।

तो अपने कोड इस तरह दिखेगा:

override func viewWillLayoutSubviews() { 
    super.viewWillLayoutSubviews() 

    guard let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout else { 
    return 
    } 

    if UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication().statusBarOrientation) { 
    //here you can do the logic for the cell size if phone is in landscape 
    } else { 
    //logic if not landscape 
    } 

    flowLayout.invalidateLayout() 
} 
+6

इस दृष्टिकोण का उपयोग कर आप एक अनंत लूप में प्रवेश करेंगे द्वारा:

यहाँ एक उदाहरण है। – valvoline

+3

मुझे यकीन नहीं है कि @valvoline सही है कि इससे अनंत लूप का कारण बन जाएगा - हालांकि यह प्रदर्शन समस्याओं का कारण बन सकता है क्योंकि यह आवश्यक है जितना अधिक बार संग्रहदृश्य लेआउट को अमान्य कर रहा है। 'ViewWillTransitionToSize' का उपयोग करना बेहतर है। – JosephH

+3

यह कोड एक अनंत लूप का कारण बनता है। यह सही जवाब नहीं होना चाहिए। – Josh

13

मैं एक ही बात के साथ viewWillTransitionToSize का उपयोग करने की प्रवृत्ति है और बस वहाँ में एक कॉल invalidateLayout() बनाया है।

22

शायद सबसे सीधे इस बनाने के लिए जिस तरह से viewWillTransitionToSize दौरान invalidateLayout के लिए है:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 
    super.viewWillTransition(to: size, with: coordinator) 
    guard let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout else { 
     return 
    } 
    flowLayout.invalidateLayout() 
} 
0

मैं UICollectionView उपवर्ग में आइटम के आकार को समायोजित करने के लिए एक चुनौती थी। इसके लिए सबसे अच्छी विधि सेट फ्रेम है। संपत्ति संग्रहViewFlowLayout मैं ViewController से पारित किया (मेरे मामले में यह डिफ़ॉल्ट प्रवाह लेआउट से आउटलेट था)।

// .h 
@property (nonatomic, weak) UICollectionViewFlowLayout *collectionViewFlowLayout; 

// .m 
- (void)setFrame:(CGRect)frame { 
    if (!CGSizeEqualToSize(frame.size, self.frame.size)) { 
     collectionViewFlowLayout.itemSize = 
     CGSizeMake((UIDeviceOrientationIsLandscape(UIDevice.currentDevice.orientation) ? (frame.size.width - 10)/2 : frame.size.width), collectionViewFlowLayout.itemSize.height); 
    } 
    [super setFrame:frame]; 
} 
0

traitCollectionDidChange विधि viewWillLayoutSubviews के बजाय रूप में अच्छी तरह से इस्तेमाल किया जा सकता है:

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { 
    super.traitCollectionDidChange(previousTraitCollection) 

    guard let previousTraitCollection = previousTraitCollection, traitCollection.verticalSizeClass != previousTraitCollection.verticalSizeClass || 
     traitCollection.horizontalSizeClass != previousTraitCollection.horizontalSizeClass else { 
      return 
    } 

    if traitCollection.horizontalSizeClass == .regular && traitCollection.verticalSizeClass == .regular { 
     // iPad portrait and landscape 
     // do something here... 
    } 
    if traitCollection.horizontalSizeClass == .compact && traitCollection.verticalSizeClass == .regular { 
     // iPhone portrait 
     // do something here... 
    } 
    if traitCollection.horizontalSizeClass == .regular && traitCollection.verticalSizeClass = .compact { 
     // iPhone landscape 
     // do something here... 
    } 
    collectionView?.collectionViewLayout.invalidateLayout() 
    collectionView?.reloadData() 
} 
0

आप एक मुखौटा सामग्री बनाने और इसे collectionView जा सकते हैं। लैंडस्केप/पोर्ट्रेट एनीमेशन समाप्त होने के बाद, आपको इसे ASAP को हटाना होगा।

@property (strong, nonatomic) UIImageView *maskImage; 

......... 

- (UIImageView *) imageForCellAtIndex: (NSInteger) index { 
    UICollectionView *collectionView = self.pagerView.test; 
    FSPagerViewCell *cell = nil; 
    NSArray *indexPaths = [collectionView indexPathsForVisibleItems]; 
    for (NSIndexPath *indexPath in indexPaths) { 
     if (indexPath.item == index) { 
      cell = (FSPagerViewCell *)[collectionView cellForItemAtIndexPath: indexPath]; 
      break; 
     } 
    } 
    if (cell) { 
     return cell.imageView; 
    } 
    return nil; 
} 


- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator 

{ 
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; 

    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) 
    { 
     UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; 
     [self test_didRotateFromInterfaceOrientation: orientation]; 

     UIImageView *imageView = [self imageForCellAtIndex: self.pagerView.currentIndex]; 
     if (imageView) { 
       UIImageView *imageView = [self imageForCellAtIndex: self.pagerView.currentIndex]; 
       CGSize itemSize = self.pagerView.itemSize; 
       UIImageView *newImage = [[UIImageView alloc] initWithImage: imageView.image]; 
       [newImage setFrame: CGRectMake((_contentView.bounds.size.width - itemSize.width)/2.0f, 0, itemSize.width, itemSize.height)]; 
       newImage.contentMode = imageView.contentMode; 
       newImage.clipsToBounds = imageView.clipsToBounds; 
       newImage.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 
       [self.pagerView addSubview: newImage]; 

       self.maskImage = newImage; 
     } 

     [self.pagerView.test performBatchUpdates:^{ 
      [self.pagerView.test setCollectionViewLayout:self.pagerView.test.collectionViewLayout animated:YES]; 
     } completion:nil]; 
     // do whatever 
    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) 
    { 
     [self.maskImage removeFromSuperview]; 
    }]; 
} 
संबंधित मुद्दे