Подтвердить что ты не робот

Получение местоположения экрана ячейки из UICollectionView

Это не столько вопрос, сколько объяснение того, как решить эту проблему.

Первое, что нужно понять, - это то, что UICollectionView наследует от UIScrollView, поэтому наилучшим решением является стандартный поиск со списком прокрутки.

Здесь проблема, с которой я обращался:

У меня был UICollectionView, у которого были разные элементы в каждой ячейке - вместе с различными типами ячеек. Мне нужен выбор ячейки, чтобы вызвать эффект изображения в ячейке, чтобы он расширялся и захватил весь экран. Как я сделал расширение для другой должности.

Задача заключалась в том, чтобы получить положение ячейки на экране, чтобы анимационная секция имела контрольную точку от того, где начать.

Итак, чтобы облегчить получение этой информации, рассмотрите следующий код:

Первое примечание:

UICollectionView *picturesCollectionView;
DrawingCell cell; // -> instanceof UICollectionViewCell with custom items.

// first, get the list of cells that are visible on the screen - you must do this every time
// since the items can change...  This is a CRITICAL fact.  You do not go through the
// entire list of cells - only those the collectionView indicates are visible.  Note 
// there are some things to watch out for - the visibles array does not match the indexPath.item
// number - they are independent.  The latter is the item number overall the cells, while
// the visibles array may have only 2 entries - so there is NOT a 1-to-1 mapping - keep
// that in mind.

NSArray *visibles = [self.picturesCollectionView visibleCells];

// now, cycle through the times and find the one that matches some criteria.  In my
// case, check that the cell for the indexPath passed matches the cell imageView...
// The indexPath was passed in for the method call - note that the indexPath will point
// to the number in your datasource for the particular item - this is crucial.

for (int i=0; i<visibles.count; i++) {
    DrawingCell *cell = (DrawingCell *)visibles[i];
    if (cell.imageView.image == (UIImage *)images[indexPath.item]) {

        // at this point, we've found the correct cell - now do the translation to determine
        // what is it location on the current screen...  You do this by getting the contentOffset
        // from the collectionView subtracted from the cell origin - and adding in (in my case)
        // the frame offset for the position of the item I wish to animate (in my case the
        // imageView contained within my custom collection cell...

        CGFloat relativeX = cell.frame.origin.x - self.picturesCollectionView.contentOffset.x + cell.imageView.frame.origin.x;
        CGFloat relativeY = cell.frame.origin.y - self.picturesCollectionView.contentOffset.y + cell.imageView.frame.origin.y;

        // I now have the exact screen coordinates of the imageView - so since I need this
        // to perform animations, I save it off in a CGRect - in my case, I set the size
        // exactly to the size of the imageView - so say you were doing a Flicker display
        // where you wanted to grow a selected image, you get the coordinates of the image
        // in the cell and the size from the displayed image...

        UIImageView *image = cell.imageView;

        // selectedCell is a CGRect that global for the sake of this code...

        selectedCell = cell.frame;
        selectedCell.origin.x = relativeX;
        selectedCell.origin.y = relativeY;
        selectedCell.size.width = cell.imageView.frame.size.width;
        selectedCell.size.height = cell.imageView.frame.size.height;
    }
}

// done.  I have my coordinates and the size of the imageView I wish to animate and grow...

Надеюсь, это поможет другим людям, которые пытаются понять, как сказать, что-то накладывать на ячейку в точном месте и т.д.

4b9b3361

Ответ 1

-(void)collectionView:(UICollectionView *)cv didSelectItemAtIndexPath:(NSIndexPath *)indexPath;
{

UICollectionViewLayoutAttributes *attributes = [cv layoutAttributesForItemAtIndexPath:indexPath];

CGRect cellRect = attributes.frame;

CGRect cellFrameInSuperview = [cv convertRect:cellRect toView:[cv superview]];

NSLog(@"%f",cellFrameInSuperview.origin.x);
}

Это работает для меня. Вы можете попробовать себя.

Ответ 2

Ну, первая часть вашего вопроса в значительной степени ясна, вторая? так или иначе если вы хотите получить кадр ячейки выбора в своей коллекции, вы можете использовать это:

UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath];
CGRect cellRect = attributes.frame;

Подробнее здесь

Ответ 3

Решение

@Alivin с использованием layoutAttributesForItemAtIndexPath работает, но только для отображаемого/текущего вида прокрутки, которое видит пользователь.

Значение, если вы выберете видимые ячейки first, вы получите фактические frame, , но, если вы прокрутите список, frame будет иметь отклонение и вы не получите требуемые координаты.

Вот почему вам нужно использовать convertPoint: toView:

let realCenter = collectionView.convertPoint(cell.center, toView: collectionView.superview)

В основном этот метод принимает точку (cell.center) в одном представлении и преобразует эту точку в другую систему координат (collectionView.superview), которая именно то, что нам нужно.

Таким образом, realCenter всегда будет содержать координаты для фактической выбранной ячейки.

Ответ 4

Я сделал это и раньше. это заняло некоторое время, но это возможно.

Вам нужно использовать

[currentImageView.superview convertRect:currentImageView.frame toView:translateView]

Если currentImageView - это изображение, которое пользователь удаляет. Это супервизор будет ячейкой. Вы хотите преобразовать прямоугольник своего изображения туда, где он на самом деле находится на другом представлении. Это представление называется "translateView" здесь.

Итак, что такое translateView? В большинстве случаев это просто self.view.

Это даст вам новый фрейм для вашего изображения, который встретит, где ваше изображение находится на вашем столе. После этого вы можете развернуть изображение, чтобы отобразить весь экран.

Вот суть кода, который я использую, чтобы коснуться изображения, затем разверните изображение и отобразите новый контроллер, который позволяет панорамировать изображение. Забастовкa >

https://gist.github.com/farhanpatel/4964372

Ответ 5

Альтернативой является использование событий для предоставления большинства, если не всех ответов на ваши вопросы.

Я предполагаю, что событие touch начнет все это, поэтому позволит реализовать что-то значимое;

  //First, trap the event in the collectionView controller with;

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{

   // lets ensure it actually visible (yes we got here from a touch event so it must be... just more info)
   if ([self.collectionView.indexPathsForVisibleItems containsObject:indexPath]) {

     // get a ref to the UICollectionViewCell at indexPath
     UICollectionViewCell *cell =(UICollectionViewCell *)[self.collectionView cellForItemAtIndexPath:indexPath];

     //finally get the rect for the cell
     CGRect cellRect = cell.frame


      // do your processing here... a ref to the cell will allow you to drill down to the image without the headache!!


  }
}

oh... прежде чем вы спешите в течение счастливого часа, не забывайте читать дальше;

   <UICollectionViewDelegate> (hint - it needed)