Soru Bir hücrenin ekran konumunu UICollectionView'den alma


Bu, bu sorunun nasıl çözüleceğine dair bir açıklama olarak bir soru değil.

Anlaşılması gereken ilk şey, UICollectionView birinden miras UIScrollView - Kaydırma görünümü içeriğiyle standart bir arama yapmak en iyi çözümdür.

İşte benim adreslediğim problem:

sahiptim UICollectionView Her hücrenin farklı hücrelere sahip olduğu farklı hücreler vardı. Hücredeki görüntüyü, tüm ekranın genişletilmesi ve ele geçirilmesi için görünmesi için bir hücre seçimine ihtiyacım var. Genişlemeyi nasıl yaptım başka bir yazı için.

Meydan okuma, hücrenin ekran üzerindeki konumunu almaktı, böylece animasyon bölümünün nereden başlayacağına dair bir referans noktası olacaktır.

Bu bilgiyi elde etmeyi kolaylaştırmak için aşağıdaki kodu dikkate alınız:

İlk not:

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's 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's location on the current screen...  You do this by getting the contentOffset
        // from the collectionView subtracted from the cell's 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's 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...

İnşallah bu, hücrede bir şeyleri tam olarak nasıl konumlandırabileceğimizi anlamaya çalışan diğer insanlara yardımcı olur.


44
2018-02-06 19:28


Menşei


Bunu iki parçaya ayırmanızı şiddetle öneririm; meydan okuma / soru ve cevap. Herhangi bir sorun olmadan, bir soruya kendi cevabınızı ekleyebilirsiniz. - Till
Ne yazık ki, gönderirken çok fazla şey kaybolmuş gibi görünüyor. Bu sayfanın kaynağına bakıldığında, en az yaklaşık iki sayfa kodlama kaybedildi - bu yüzden bu yazı silinmeli ve işlemi tekrar açıklayacağım. - Joe Jupin
Bu yazı için @JoeJupin +1. Seçilen koleksiyon görünümü hücresinin merkezinden başlayarak uygun bir animasyon alma ile ilgili sorunlar yaşıyordum. Seçili hücreye sahip olmama rağmen, animasyonun başlangıç ​​noktası olarak merkez özelliğini kullanıyordum, bir kez de koleksiyonda ilerlemeye başladım, animasyon ekrandan bir yerde başlıyordu. Gönderindeki noktaları kullanarak bunu düzelttim. - topwik
Stackoverflow.com/q/12504924/1698467 kopyası - skywinder
@JoeJupin - Büyümeyi nasıl yaptığınızı açıklayan diğer yazıyı hiç yaptın mı? Aynı senaryo için tam olarak ihtiyacım olan şey ... şu anda, hücrede görüntüye dokunduğumda, tüm ekranı ele geçiren bir ImageView ile yeni bir UIView'i canlandırıyorum. Mükemmel çalışır, animasyonun ekranın ortasında başladığını EXCEPT. Dokunduğum hücre noktasından başlamak isterim. Seni doğru anlıyorsam, aynen böyle yaptı. Şimdiden teşekkürler! - SonnyB


Cevaplar:


-(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);
}

Benim için çalışıyorsun. Kendini deneyebilirsin


65
2017-09-07 13:33



Çok mükemmel! Tam da aradığım şey. - Meet
Mükemmel! Yani, tekrarlamak için, cellRect temelde koleksiyonun İçeriği içindeki hücrenin konumu, genellikle değişmeyecektir. CellFrameInSuperview, süper görünümle ilgili hücrenin mutlak konumu. CellFrameInSuperView öğesini CellRect'e karşı kontrol edin ve hücrenin tamamen görünür olup olmadığını kontrol edebileceksiniz. - Ben
mükemmel cevap :) - Shaik Riyaz
İnanılmaz :) Teşekkürler! - mdonati
Bir çekicilik gibi çalış - ejanowski


Peki sorunuzun ilk kısmı oldukça açık, ikincisi? neyse Eğer almak istediğiniz şey koleksiyonunuzdaki seçim hücresinin çerçevesi ise bunu kullanabilirsiniz:

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

Daha fazla bilgi İşte


39
2018-02-06 19:42



Aslında çok fazla kod kesildi - ya da bunu yapamayacağınızı görmüş olsaydınız - önce öğenin görünür olmasını sağlamalısınız - aksi takdirde tamamen ekrandan bir çerçeve elde edersiniz. - Joe Jupin
Yanlış düğmelere basmaya devam ediyorum - yine de, görüntü dizisi dizisinden geçtikten sonra - ve aradığınız şeyi bulduktan sonra, sadece bunun gibi bir kareyi yakalayabilirsiniz: - Joe Jupin
Dang it - tekrar dönüşü vurmak: İşte onun özü - görünürden hücreyi al - ve sonra, sadece onun cell.frame kapmak - Yukarıdaki gösterdiğiniz öznitelikler yöntemine gerek yok. Bu yazıyı kaldırmam gerekiyor - ve her şeyi tekrar uygun bir şekilde yapmam - her şey güzelce karıştırılıyordu ve kod bölümünde yukarı ve aşağı kaydırmaya çalışana kadar bunu fark etmemiştim ... - Joe Jupin
İOS7 için güzel bir kod olsa da, iOS7'de kullanmam gerekiyordu [view convertRect: ... fromView: ...] - Calin Chitu


@Alivin çözümü kullanarak layoutAttributesForItemAtIndexPath sadece kullanıcının gördüğü mevcut / geçerli kaydırma görünümü için çalışır.

Anlamı, eğer ilk gerçekleri alacağınız görünür hücreleri sundu frame, fakat kaydırırsanız frame Bir sapma olacak ve ihtiyacınız olan koordinatları alamayacaksınız.

Bu yüzden kullanmanız gerek convertPoint: bileti görüntüleyebilir :

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

Temel olarak, bu yöntem bir görünümde bir nokta (cell.center) alır ve bu noktayı tam olarak ihtiyacımız olan başka bir görünüm (collectionView.superview) koordinat sistemine dönüştürür.

Böylece, realCenter her zaman seçili hücrenin koordinatlarını içerecektir.


13
2017-12-24 09:39



Siz efendim, bir ödül kazanmalısınız. - Roi Mulia


Bunu daha önce de yaptım. biraz zaman aldı ama mümkün.

Kullanmalısın

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

CurrentImageView, kullanıcının dokunduğu görüntüdür. Süper manzara, hücre olacak. Görüntünüzün doğrultusunu, aslında farklı bir görünümde olduğu yere dönüştürmek istersiniz. Bu manzaraya "translateView" denir.

Peki translateView nedir? Çoğu durumda sadece self.view.

Bu, görüntünüzün tablonuzda nerede yer alacağını görüntüleyeceğiniz yeni bir çerçeve sunacaktır. Bunu aldıktan sonra, tüm ekranı kaplayacak şekilde görüntüyü genişletebilirsiniz.

Burada, bir görüntüye dokunmak ve ardından görüntüyü genişletmek ve görüntünün kaydırılmasına izin veren yeni bir denetleyici görüntülemek için kullandığım kodun bir özeti.

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


7
2018-02-15 23:19





Bir alternatif, sorulara tüm cevapları olmasa bile, en iyi şekilde sağlamaktır.

Bir dokunma olayının tüm bunları başlatacağını varsayalım, bu yüzden anlamlı bir şey uygulansın;

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

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

   // lets ensure it's 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 ... mutlu saatler için acele etmeden önce, okumayı unutma;

   <UICollectionViewDelegate> (hint - it's needed)  

1
2017-07-03 02:54