2016-04-27 5 views
16

Я использовал UICollectionView (flowlayout) для создания простой компоновки. ширина для каждой ячейки установлена ​​на ширину экрана, используя self.view.frame.widthSwift: как обновить макет UICollectionView после поворота устройства

, но когда я поворачиваю устройство, ячейки не обновляются.

enter image description here

Я нашел функцию, которая вызывается при изменении ориентации:

override func willRotateToInterfaceOrientation(toInterfaceOrientation: 
    UIInterfaceOrientation, duration: NSTimeInterval) { 
    //code 
} 

, но я не могу найти способ, чтобы обновить UICollectionView макет

Основной код является здесь:

class ViewController: UIViewController , UICollectionViewDelegate , UICollectionViewDataSource , UICollectionViewDelegateFlowLayout{ 

    @IBOutlet weak var myCollection: UICollectionView! 

    var numOfItemsInSecOne: Int! 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     numOfItemsInSecOne = 8 
     // Do any additional setup after loading the view, typically from a nib. 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) { 

     //print("orientation Changed") 
    } 

    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { 
     return 1 
    } 

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return numOfItemsInSecOne 
    } 

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cellO", forIndexPath: indexPath) 

     return cell 
    } 

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize{ 
    let itemSize = CGSize(width: self.view.frame.width, height: 100) 
    return itemSize 
    }} 

ответ

13

Добавить эту функцию:

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 
    myCollection.collectionViewLayout.invalidateLayout() 
} 

При изменении ориентации эта функция будет вызываться.

+0

спасибо @ khuong291 что, если у меня нет цели моего CollectionView, и у меня есть UICollectionViewController? как я могу назвать reloadData? –

+2

UICollectionViewController уже имеет свойство 'collectionView', поэтому вы просто вызываете их, как я уже сказал. Просто отредактируйте их в 'collectionView.reloadData()'. Это будет работать. – Khuong

+2

Итак, вам нужно перезагрузить представление, вы не можете просто запустить обновление макета? – Rivera

1

вы можете обновить UICollectionView макет с помощью

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { 
    if isLandscape { 
     return CGSizeMake(yourLandscapeWidth, yourLandscapeHeight) 
    } 
    else { 
     return CGSizeMake(yourNonLandscapeWidth, yourNonLandscapeHeight) 
    } 
} 
27

Лучшим вариантом является вызов invalidateLayout() вместо reloadData(), потому что это не заставит воссоздание клеток, поэтому производительность будет немного лучше:

override func viewWillLayoutSubviews() { 
    super.viewWillLayoutSubviews() 
    myCollection.collectionViewLayout.invalidateLayout() 
} 
+0

Это правильный путь. Это должен быть принятый ответ. – thesummersign

+0

это правильный способ сделать это. Не перезагрузите данные снова –

+3

, что вызвало у меня сокрушение. и бесконечный цикл, распознанный, когда я помещаю оператор print в функцию viewDidLayoutSubviews. – nyxee

3

Также вы можете аннулировать его таким образом.

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator { 
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; 

    [self.collectionView.collectionViewLayout invalidateLayout]; 
} 
0

обновить UICollectionViewLayouttraitCollectionDidChange метод может быть использован, а также:

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

    guard let previousTraitCollection = previousTraitCollections else { 
     return 
    } 
    collectionView?.collectionViewLayout.invalidateLayout() 
} 
0

The viewWillLayoutSubviews() не работает для меня. Также не было viewDidLayoutSubviews(). Оба приложения превратились в бесконечный цикл, который я проверил с помощью команды печати.

Один из способов, которые делают работу в

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 
// Reload here 
} 
Смежные вопросы