2014-07-08 4 views
1

J'essaye de créer un contrôleur de vue de collection très basique dans Swift qui me permet de lister certains nombres, et quand je tape l'un d'entre eux, cela m'amène à une page de détail qui dit simplement (dans une étiquette) quel numéro vous avez tapé.UICollectionView Array index out of range

Storyboard: Mon storyboard est doté d'un contrôleur de navigation en tant que racine et d'un contrôleur de vue de collection chargé. Cela contient une cellule, qui a un identifiant de cellule. Cette cellule a un bouton qui agit comme un lien vers la page de détail. J'ai assigné la source de données pour pointer sur elle-même (le contrôle a cliqué sur la ligne au contrôleur de vue pour établir la source de données) et j'ai identifié le segue comme showDetail.

Quand je charge l'application, il affiche mes boutons 7 fois, mais quand je clique sur l'un d'eux, je reçois un indice hors des limites sur la ligne ci-dessous:

Voici mon code:

importation Fondation importation UIKit

class WeekCollectionView : UICollectionViewController 
{ 
    override func collectionView(collectionView: UICollectionView!, numberOfItemsInSection section: Int) -> Int 
    { 
     return 7 
    } 

    override func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell! 

    { 
     let cell: ShiftCell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as ShiftCell 
     return cell; 
    } 

    override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) 

    {  
     if (segue.identifier == "showDetail") { 
      **//CRASHES ON THIS LINE BELOW FOR THE ARRAY [0]** 
      let indexPaths: NSArray = self.collectionView.indexPathsForSelectedItems()[0] as NSArray 
      let destinationViewController = segue.destinationViewController as DetailViewController 
      //var someNumber = images[indexPath.row] 
      destinationViewController.mySpecialID = 1 //replace this with someNumber, always set 1 for now as a test 
     } 
    } 
} 

Ma classe de cellules (ci-dessus) est simplement:

class ShiftCell: UICollectionViewCell { 
    init(frame: CGRect) { 
     super.init(frame: frame) 
    } 

    init(coder aDecoder: NSCoder!) { 
     super.init(coder: aDecoder) 
    } 

} 

Je ne suis pas vraiment sûr de ce que j'ai fait de mal - peut-être que quelque chose d'autre doit se passer dans mon storyboard? J'ai suivi un tutoriel d'apple (en objectif-c) qui fonctionne parfaitement, et tout le code est identique si je ne me trompe pas!

Je suis vraiment coincé ici, merci beaucoup si quelqu'un peut me pointer dans la bonne direction! :)

Répondre

0

Vous obtenez ce plantage car il n'y a pas d'éléments sélectionnés. Vous avez un bouton sur le dessus de la cellule qui bloque le toucher d'atteindre la cellule pour le sélectionner réellement. Vous allez devoir trouver une façon différente d'identifier la rangée que chaque bouton représente. Un modèle commun pour cela consiste à utiliser la propriété tag du bouton. Cela peut stocker n'importe quel nombre entier arbitraire pour vous aider à identifier la vue.

Ainsi, collectionView:cellForItemAtIndexPath vous devez définir l'étiquette de votre bouton à l'indice actuel:

override func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell! 
{ 
    let cell: ShiftCell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as ShiftCell 
    cell.myButton.tag = indexPath.item 
    return cell; 
} 

Alors je crois que le sender du Segue sera le bouton. Vous pouvez obtenir l'index de retour que:

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) 
{  
    if (segue.identifier == "showDetail") { 
     var possibleIndex : Int? 
     if let button = sender as? UIButton { 
      possibleIndex = button.tag 
     } 

     if let index = possibleIndex { 
      // ... 
     } 
    } 
} 

Remarque: Je ne suis pas positif que l'expéditeur sera le bouton comme je le fais normalement les choses à travers le code sans story-board. Si l'expéditeur n'est pas le bouton, vous pouvez toujours le faire à la manière "old fashion" et accrocher le bouton à une méthode sur le contrôleur de vue depuis le Storyboard au lieu d'utiliser une section. Vous devez ensuite créer le nouveau contrôleur en code et l'afficher comme vous le souhaitez.

+0

Merci beaucoup - je vais essayer plus tard. Donc, si je clique sur le bouton, et que je fais défiler vers le bas pour 'marquer', je peux juste lui donner un # comme 200 ou quelque chose? Et c'est tout? Est-ce que ce "répéteur" ferait que chaque bouton aurait une étiquette de 200? – NullHypothesis

+0

Alors j'ai essayé et ça plante toujours (j'ai cliqué sur le bouton dans la cellule, et j'ai mis le tag à quelque chose comme 198). Dois-je donner à chaque bouton une étiquette unique en quelque sorte? Comme si je n'avais qu'un seul bouton dans la cellule, à chaque itération, est-ce que je dois donner au bouton une étiquette unique par programme? – NullHypothesis

+0

@ user3379785 J'ai mis à jour ma réponse avec un exemple de code. Vous devez avoir un tag unique pour chaque bouton.Plus précisément, vous souhaitez que l'étiquette de la cellule corresponde exactement à l'index pour lequel elle est affichée. – drewag

Questions connexes