9

Я пытаюсь сделать Collection View, в котором кто-то выбирает cell, и для каждого выбора он берет их в другой View Controller, который содержит контент выбора. Однако я сталкиваюсь с трудностями, поскольку как только я применяю эту строку кода к didSelectItemAtIndexPath;Swift: UICollectionView select cell indexPath issues

self.performSegueWithIdentifer("showDetail", sender: self) 

, а затем запустить его в тренажере cell отбора работает в соответствии с indexPath, но его запоминанием выбора каждый раз, когда я выбираю новый cell. Так, например, у каждого cell есть фотография и ярлык, и если я выберу первый cell в indexPath, то segue берет меня сначала на пустой, а затем на мой выбранный cell. Если я выберу еще один cell, номер 3 на indexPath, пустой вид теперь является первым cell из моего предыдущего выбора, после которого он берет на мой выбранный третий cell. Это делает это каждый раз. Если я удалю код performSegueWithIdentifer (из Xcode 6.2 (в 6.1.1 он был случайным)) выбор - это мой предыдущий выбор и никогда не мой «selectedCell», но, по крайней мере, его единственный выбор один раз вместо двух, чтобы попасть в view. Что-то не так на indexPath. Это код для моего prepareForSegue

override func prepareForSegue(segue: UIStoryBoardSegue, sender: AnyObject?) { 
     if segue.identifer == "showDetail" { 
      let detailVC:DetailViewController = segue.destinationViewController as DetailViewController 
      detailVC.selectedImageName = selectedImage 
      detailVC.selectedLabel = selectedLabels 
      } 
     } 

я застрял на том, что делать &, что решение применить. Должен ли я держать performSegueWithIdentifer код & создать Equatable для реализации find(array, selection) на indexPath? Или я мог бы написать цикл (который кажется намного проще), который будет проходить через indexPath на основе выбора, и это приведет к удалению ячейки, которая больше не будет выбрана. Однако я не уверен, какое условие писать в цикле, потому что я не знаю значения свойства «selectedCell», потому что он необязательный.

for (index, value) in enumerate(cellItems) { 
//something here to remove 'selectedItem' in the indexPath 
} 

Если удалить performSegueWithIdentifer код из didSelectItemAtIndexPath, что я могу сделать в моей prepareForSegue, чтобы получить выбор на правильном indexPath?

EDIT полный код на didSelectItemAtIndexPath

override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { 
    selectedImage = cellImages[indexPath.row] as String 
    selectedLabels = cellLabels[indexPath.row] as String 
    self.performSegueWithIdentifer("showDetail", sender: self) 
    } 

Я попытался изменить отправителя в performSegueWithIdentifer к indexPath, но проблема все еще остается.

EDIT 2 Полный код для моего CollectionViewController

class CollectionViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate { 

@IBOutlet weak var collectionView: UICollectionView! 

var selectedImage = String() 
var selectedLabels = String() 

var cellImages:[String] = ["1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg", "6.jpg", "7.jpg", "8.jpg", "9.jpg", "10.jpg", "11.jpg", "13.jpg", "14jpg"] 

var cellLabels:[String] = ["Photo 1", "Photo 2", "Photo 3", "Photo 4", "Photo 5", "Photo 6", "Photo 7", "Photo 8", "Photo 9", "Photo 10", "Photo 11", "Photo 12", "Photo 13", "Photo 14"] 

func collectionView(collectionView: UICollectionView, numberOfNumberItemsInSection: Int) -> Int { 
    return cellImages.count 
} 

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 
    let cell: PhotoViewCell = collectionView.dequeueReuseableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as PhotoViewCell 
    cell.labelCell.text = cellLabels[indexPath.row] 
    cell.ImageCell.image = UIImage(named: cellImages[indexPath.row]) 
    return cell 
} 

override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { 
    selectedImage = cellImages[indexPath.row] as String 
    selectedLabels = cellLabels[indexPath.row] as String 
    self.performSegueWithIdentifer("showDetail", sender: self) 
    } 

override func prepareForSegue(segue: UIStoryBoardSegue, sender: AnyObject?) { 
     if segue.identifer == "showDetail" { 
      let detailVC:DetailViewController = segue.destinationViewController as DetailViewController 
      detailVC.selectedImageName = selectedImage 
      detailVC.selectedLabel = selectedLabels 
      } 
     } 
} 

PhotoViewCell

class PhotoViewCell: UICollectionViewCell { 

@IBOutlet var labelCell: UILabel! 
@IBOutlet var ImageCell: UIImage! 

} 

EDIT 3 - Измененный

Я попробовал ваше предложение и, к сожалению, проблема все еще сохраняющиеся на двойных взглядов - это все еще передавая два представления, прежде чем он приведет меня к фактическому выбранному cell. Я также немного изменил код в didSelectItemAtIndexPath, но он все еще не исправил проблему.

if let cell = collectionView.cellForItemAtIndexPath(indexPath) as? PhotoViewCell { 

performSegueWithIdentifier("showDetail", sender: cell) 
} 

Однако после вашего другого предложения, в моем StoryBoard я добавил segue от моего Collection Viewcell к моему DetailViewController, который имеет идентификатор «showDetail». Если я удалю segue, то ничего не может быть выбран из моего cells.

Хотя это кажется performSegueWithIdentifer код является триггером для двойных взглядов, потому что когда я удалить его, cell только выбирается один раз, проблема заключалась в том, что indexPath отбора cell не было правильным, потому что это первый выбор на пустой вид (это связано с showDetail segue?), который затем отключает мой indexPath.

EDIT - решаемые

Это остановило двойные выборы (performSegueWithIdentifier линия была удалена): -

override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { 
if let cell = collectionView.cellForItemAtIndexPath(indexPath) { 
cellLabels[indexPath.row] as String 
cellImages[indexPath.row] as String 
    } 
} 

Большое спасибо за вашу помощь !!!!

+0

где вы установили selectedImage и selectedLabel? Вы можете отправить indexPath в отправителе self.performSegueWithIdentifer ("showDetail", sender: indexPath), а затем в prepareforsegue захватить элемент массива с помощью этого указательного пути. – Godfather

+0

@ user588125 selectedImage и выбранная метка установлены в файле didSelectItemAtIndexPath. Я пробовал этот self.performSegueWithIdentifer ("showDetail", отправитель: indexPath), но это не сработало. Как написать это в состояние в prepareForSegue? – j03T

+0

let element = yourArray [indexPath.row]; detailVC.selectedImage = element.selectedImage ... не может сделать больше без фактического кода. – Godfather

ответ

9

Я придерживаюсь UIView объектов как можно больше.

override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { 
    if let cell = collectionView.cellForItemAtIndexPath(indexPath) { 
     performSegueWithIdentifier("showDetail", sender: cell) 
    } else { 
     // Error indexPath is not on screen: this should never happen. 
    } 
} 

Тогда в func prepareForSegue(,sender:)

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    assert(sender as? UICollectionViewCell != nil, "sender is not a collection view") 

    if let indexPath = self.collectionView?.indexPathForCell(sender as UICollectionViewCell) { 
     if segue.identifier == "showDetail" { 
      let detailVC: DetailViewController = segue.destinationViewController as DetailViewController 
      detailVC.selectedImageName = cellImages[indexPath.row] 
      detailVC.selectedLabel = cellLabels[indexPath.row] 
     } 
    } else { 
     // Error sender is not a cell or cell is not in collectionView. 
    } 
} 

У меня есть подозрение, что у вас есть SEGUE в уже раскадровки и не нуждаются в func collectionView(, didSelectItemAtIndexPath:), но в любом случае, подготовить переход должен работать.

1

Swift 3,0

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 

    let iPath = self.collectionView.indexPathsForSelectedItems 
    let indexPath : NSIndexPath = iPath![0] as NSIndexPath 
    let rowIndex = indexPath.row 
    print("row index = \(rowIndex)") 
} 
+0

У этого вопроса уже есть принятый ответ. – dfd