web-dev-qa-db-fra.com

Comment définir la taille de cellule de la vue de collection via la mise en page automatique

Bonjour, j'essaie de redimensionner la cellule via le auto layout.

Je veux afficher la cellule par 3 par 3.

Marge de la première cellule à gauche = 0

Marge de la dernière cellule à droite = 0

Et tout l'espace de la cellule a 1 pt. Comme un instagram.

 enter image description here

 enter image description here

Devrais-je régler à la taille de la cellule? Je veux définir la contrainte via l'Autolayout.

J'essaie également de définir la taille de la cellule à l'aide du code.

Voici mon code:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    return CGSizeMake(123, 123);
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
    return 1;
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
    return 1;
}

Mais..Je pense que ce n'est pas exactement calculer la taille de la cellule.

Comment définir la taille de la cellule en fonction de la taille de l'écran?

Je dois définir l'espace le 1pt entre les cellules.

Y a-t-il un moyen de ne configurer que l'utilisation du storyboard?

Sinon, comment définir le code?

Je vous remercie.

17
Shawn Baek

Je ne pense pas que vous puissiez définir la taille en utilisant uniquement le Storyboard, car vous ne pouvez pas définir de contraintes pour les éléments récurrents tels que les cellules de vue de collection créées à la volée au moment de l'exécution.

Vous pouvez facilement calculer la taille à partir des informations qui vous sont données. Dans collectionView(_:layout:sizeForItemAt:), vous pouvez accéder aux limites de la collectionView pour calculer la taille souhaitée de votre cellule:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    // Compute the dimension of a cell for an NxN layout with space S between
    // cells.  Take the collection view's width, subtract (N-1)*S points for
    // the spaces between the cells, and then divide by N to find the final
    // dimension for the cell's width and height.

    let cellsAcross: CGFloat = 3
    let spaceBetweenCells: CGFloat = 1
    let dim = (collectionView.bounds.width - (cellsAcross - 1) * spaceBetweenCells) / cellsAcross
    return CGSize(width: dim, height: dim)
}

Cela fonctionne alors pour les iPhones et les iPad de toutes tailles.

23
vacawama

Excellente réponse de vacawama mais j'avais 2 problèmes. Je voulais que l'espacement que j'ai défini dans le storyboard soit automatiquement utilisé. 

 enter image description here

Et deuxièmement, je ne pouvais pas invoquer cette fonction et personne n'a mentionné comment? Afin d'appeler le paramètre sizeForItemAt de collectionView, vous devez étendre UICollectionViewDelegateFlowLayout au lieu d'étendre UICollectionViewDelegate. J'espère que cela sauve du temps à quelqu'un d'autre.

extension MyViewController: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let cellsAcross: CGFloat = 3
        var widthRemainingForCellContent = collectionView.bounds.width
        if let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout {
            let borderSize: CGFloat = flowLayout.sectionInset.left + flowLayout.sectionInset.right
            widthRemainingForCellContent -= borderSize + ((cellsAcross - 1) * flowLayout.minimumInteritemSpacing)
        }
        let cellWidth = widthRemainingForCellContent / cellsAcross
        return CGSize(width: cellWidth, height: cellWidth)
    }

}
13
Travis M.

Je l'ai configuré à l'aide des méthodes de délégation de CollectionView. Cela vous donnera une configuration 2xN mais vous pouvez facilement en faire une 3xN à la place. Voici une capture d'écran et vous pouvez vous référer à mon projet sur GitHub ...

https://github.com/WadeSellers/GoInstaPro

 CollectionView flow layout screenshot

7
Wade Sellers

Code de version de Swift 3 basé sur la réponse de vacawama:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        let cellsAcross: CGFloat = 3
        let spaceBetweenCells: CGFloat = 1
        let dim = (collectionView.bounds.width - (cellsAcross - 1) * spaceBetweenCells) / cellsAcross

        return CGSize(width: dim, height: dim)
    }
4
mriaz0011

Voici une autre solution mais cela ne fonctionne que sur iPhone6.

Je vais essayer de mettre à jour pour iphone5/6plus

Un merci spécial à @vacawama! 

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {


        // Compute the dimension of a cell for an NxN layout with space S between
        // cells.  Take the collection view's width, subtract (N-1)*S points for
        // the spaces between the cells, and then divide by N to find the final
        // dimension for the cell's width and height.

        let cellsAcross: CGFloat = 3
        let spaceBetweenCells: CGFloat = 1
        let dim = (collectionView.bounds.width - (cellsAcross - 1) * spaceBetweenCells) / cellsAcross
                print(indexPath.row)

        var width = dim

        //last cell's width
        if(  (indexPath.row + 1) % 3 == 0){
            width = 124

        }else {
            width = 124.5
        }
        print(width)
        return CGSizeMake(width, dim)

    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
        return 1;
    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
        return 1;
    }
0
Shawn Baek