2013-06-06 6 views
19

Próbuję dodać UIScrollView do wnętrza UICollectionViewCell. Chodzi o to, że można użyć szczypania, aby powiększyć UIScrollView (a wraz z nim obraz wewnątrz), ale widok przewijania nie obsługuje żadnego gestu. Zgaduję, że zostali złapani przez UICollectionView.Jak powiększać UIScrollView wewnątrz UICollectionViewCell?

Ustawiłem delegata UIScrollView na UICollectionViewCell, ale żadna z metod delegatów nie jest wywoływana.

EDYCJA: Zrobiłem repozytorium github z kodem (uprościłem tyle, ile mogłem). Mimo że to tylko kilka linii kodu, nie widzę, co zrobiłem źle.

EDIT2: Po odpowiedź stwierdzono, dodałem poprawki do wyżej wymienionych repo, nadzieja inni uważają, że jest zbyt pomocne :)

https://github.com/krummler/gallery-pinchzoom-example

+1

Dziękujemy za oddanie zaktualizowany kod w repo. Przydało mi się to! – super9

Odpowiedz

23

Możecie spróbować manipulowanie UIGestureRecognizers, aby to zrobić. W GalleryViewController:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView 
        cellForItemAtIndexPath:(NSIndexPath *)indexPath { 

    GalleryImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"galleryImageCell" forIndexPath:indexPath]; 

    ImageContext *imageContext = [self.images objectAtIndex:indexPath.row]; 

    cell.imageContext = imageContext; 
    [self.collectionView addGestureRecognizer:cell.scrollView.pinchGestureRecognizer]; 
    [self.collectionView addGestureRecognizer:cell.scrollView.panGestureRecognizer]; 

    return cell; 
} 

Od Apple's documentation on UIView:

Dołączanie rozpoznawania gestów do widoku określa zakres reprezentowanego gest, powodując jej odbierać poprawki hit przetestowanych do tego widoku i wszystkich jego subviews. Widok zachowuje narzędzie do rozpoznawania gestów.

Należy również upewnić się, że zostały usunięte, gdy komórka nie jest już wyświetlana.

- (void)collectionView:(UICollectionView *)collectionView 
    didEndDisplayingCell:(UICollectionViewCell *)cell 
    forItemAtIndexPath:(NSIndexPath *)indexPath { 

    // Get the cell instance and ... 
    [self.collectionView removeGestureRecognizer:cell.scrollView.pinchGestureRecognizer]; 
    [self.collectionView removeGestureRecognizer:cell.scrollView.panGestureRecognizer]; 
} 

Ponieważ nie jesteś modyfikowanie delegować UIGestureRecognizer, zaledwie jego zakresu, to nadal kontrolować powiększanie Scrollview tylko, że komórki.

EDIT:

panGestureRecognizer I dodaje się do powyższych przykładów, zgodnie z sugestią, że PO jest potrzebne. Sam zoom jest całkowicie obsługiwany przez pinchGestureRecognizer, ale prawdą jest, że w większości przypadków, po powiększeniu obrazu do punktu, w którym widoczny jest tylko jego podzestaw, należy przesunąć, aby przesunąć widoczną część dookoła. Oznacza to, że jest to część prawidłowego zoomowania.

+0

Awesome! Musiałem zrobić to samo dla 'panGestureRecognizer' i dobrze mi poszło! Dzięki :) (nie mogę nagrodzić nagrody jeszcze z jakiegoś powodu, zrobię to później.) –

+0

@matehat Im używając Swift i mojej komórki didEndDisplaying, ciągle otrzymuję błąd "found nil unwrapping optional". Próbowałem zrobić to "jeśli pozwól", to nigdy nie zostanie wywołane. :/Oto jak otrzymuję instancję: let cell = collectionView.cellForItemAtIndexPath (indexPath) as! FSImageCell –

+0

Nie trzeba dodawać/usuwać gestów do komórki. Zarówno szczypanie, jak i panoramowanie działały już dla mnie w komórce, a jednocześnie pozwalały mi przewijać poziomo przez mój widok kolekcji. Używałem pełnoekranowych komórek do galerii obrazów. – thgc

0

Sprawdź, czy multitouch wszystkich powiązanych View jest włączony. System iOS domyślnie wyłącza multitouch w większości widoków, aby oszczędzać energię.

+0

Próbowałem tego i próbowałem naśladować kilka przykładów, które mogłem znaleźć, ale nadal nie mogę go uruchomić. Dodałem adres URL repozytorium github do oryginalnego postu. –

0
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch 
{    
    if (touch.view == [self myScrollView]) //<- whatever your scrollView is called 
    { 
     return YES; 
    } 
    return NO; 
} 

Nie znam swojego kodu, ale spróbuj odtworzyć powyższy kod, aby sprawdzić, czy możesz filtrować swoje dotknięcia do żądanych obiektów. Powyższy kod pochodzi z .

+0

Dzięki, dodałem go do komórki collectionview, nie wydaje się, że jest wywołany w nim widok przewijania, tylko w widoku zewnętrznym. –

0

Delegaci nie są wywoływani, ponieważ dodano je do widoku UICollectionview. Zdarzenia dotykowe są dostępne dla widoku kolekcji, który jest podglądem, a więc nie można go uzyskać w widoku wewnątrz. Może trzeba pomyśleć o innym sposobie osiągnąć ten model.

UICollectionView się o ten sam wzór co UITableView problem occours w tableview wewnątrz Scrollview, to dotknięcie zdarzenie jest akceptowane przez Scrollview [który jest Superview] oraz do tableview przewijana w tym przypadku, zwój scrollview musi być wyłączony. Jest to inna wersja tego problemu.

Dokumenty Apple mówią, że powyższy przypadek powoduje nieprzewidywalne wyniki. Więc może to być takie samo dla twojego problemu.

Moim zdaniem koniecznością iść do lepszego projektu, który może osiągnąć to, czego szukać

2

proszę dodać Scrollview w swojej komórce i bieżącym widoku komórka obrazu dodać Scrollview. następnie skorzystać z poniższego kodu:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 
    ImageContext *context = [self.images objectAtIndex:indexPath.row]; 
    ImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"imageCell" forIndexPath:indexPath]; 
    cell.cellScrollView.autoresizesSubviews = YES; 
    cell.cellScrollView.multipleTouchEnabled =YES; 
    cell.cellScrollView.maximumZoomScale = 4.0; 
    cell.cellScrollView.minimumZoomScale = 1.0; 
    cell.cellScrollView.clipsToBounds = YES; 
    cell.cellScrollView.delegate = self; 
    cell.cellScrollView.zoomScale = 1.0; 

    [cell.imageView setImage:[UIImage imageNamed:context.thumbImageUrl]]; 

return cell; 
} 
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView 
{ NSLog(@"%i",scrollView.subviews.count); 
    for (UIView *v in scrollView.subviews) { 
    if ([v isKindOfClass:[UIImageView class]]) { 
     return v; 
     } 
    } 

}

15

Zrobiłem implementację dla SWIFT 3 iOS 9.3+ na i wszystko, co było zrobione:

1. Umieść widok obrazu wewnątrz Scrollview

storyboard example

2. Połącz delegata z przewijaniem do klasy z komórką kolekcjonowania

3. Wdrożenie poniższy kod na podklasy CollectionView

class FullScreenImageTextDetailCollectionViewCell: UICollectionViewCell, UIScrollViewDelegate { 

    @IBOutlet var scrollview: UIScrollView! 
    @IBOutlet weak var backgroundImageView: UIImageView! 

    override func awakeFromNib() { 
     self.scrollview.minimumZoomScale = 0.5 
     self.scrollview.maximumZoomScale = 3.5 
     self.scrollview.delegate = self 
    } 

    func viewForZooming(in scrollView: UIScrollView) -> UIView? { 
     return self.backgroundImageView 
    } 
} 

Nie gest rozpoznawania dodawanie lub usuwanie na kontrolerze CollectionView dominującej była konieczna, pracował jak urok!

Dzięki za poprzednie przykłady, aby to osiągnąć!

+0

Świetna odpowiedź. Najważniejszym zadaniem jest wywoływanie wywołania zwrotnego viewForZooming w klasie komórki. –

+0

dzięki @ alku83! – mourodrigo

+0

dziękuję to działa dla mnie –

0
I've set the delegate of the UIScrollView to be the UICollectionViewCell, but none of the delegate methods are being called. 

Do tego wystarczy zdefiniować jedną funkcję w collectionViewCell

@IBOutlet weak var mainScrollView:UIScrollView! 
    func setup(){ 
     mainScrollView.minimumZoomScale=1 
     mainScrollView.maximumZoomScale=10.0 

     mainScrollView.delegate=self 

    } 

    func viewForZooming(in scrollView: UIScrollView) -> UIView? { 
     return yourimageviewinside of scrollview 
    } 

wezwanie to fuction w collectionview(_,cellForItem) metody CollectionView