2012-02-20 25 views
19

Próbuję użyć nowego scrollViewWillEndDragging: withVelocity: targetContentOffset: UIScrollView delegate call w systemie iOS 5, ale wydaje mi się, że nie mogę go właściwie odpowiedzieć. Zmieniam wartość targetContentOffset-> x, ale nigdy nie zostanie ona wykorzystana. Wiem, że kod jest uruchamiany, ponieważ dostanie pułapki w tej funkcji. Próbowałem nawet ustawić wartość przesunięcia na twardy numer, więc wiedziałbym, gdzie to się skończy, ale nigdy nie działa.Niestandardowe stronicowanie UIScrollView za pomocą scrollViewWillEndDragging

Czy ktoś był w stanie użyć tego poprawnie i sprawić, by działało? Czy jest jeszcze jakieś inne zaproszenie, które musi zostać wdrożone, aby to zadziałało?

Oto mój kod w przypadku gdy ktoś widzi coś złego z nim:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset 
{ 
    // goodOffsetX returns the contentOffset i want the scrollView to stop at 
    CGFloat goodOffsetX = [self _horizontalContentOffsetForTargetHorizontalContentOffset:(*targetContentOffset).x velocity:velocity.x]; 

    NSLog(@" "); 
    NSLog(@"scrollViewWillEndDragging"); 
    NSLog(@" velocity: %f", velocity.x); 
    NSLog(@" currentX: %f", scrollView.contentOffset.x); 
    NSLog(@" uikit targetX: %f", (*targetContentOffset).x); 
    NSLog(@" pagedX: %f", goodOffsetX); 

    targetContentOffset->x = goodOffsetX; 
} 
+2

Czy masz 'pagingEnabled' ustawiony na' YES' na tym widoku przewijania? –

+3

pagingEnabled jest ustawiony na NIE, docs mówi, że musi być ustawiony na NIE, aby mógł zostać wywołany ten delegat. Próbowałem również ustawić go na YES tylko dla kopnięć i nie jest wywoływany zgodnie z dokumentami, ale jest pewne logowanie konsoli, które mówi, aby nie robić tego z parametrem pagingEnabled ustawionym na YES. – Alex

+0

Mój problem polegał na tym, że testowałem go na telefonie z iOS4. Co więcej, ustawiłeś właściwość delegata dla UIScrollView? – Marc

Odpowiedz

49

można zaimplementować niestandardowego stronicowania z tym kodem:

- (float) pageWidth { 
    return ((UICollectionViewFlowLayout*)self.collectionView.collectionViewLayout).itemSize.width + 
    ((UICollectionViewFlowLayout*)self.collectionView.collectionViewLayout).minimumInteritemSpacing; 
} 

- (void) scrollViewWillBeginDragging:(UIScrollView *)scrollView { 

    CGFloat pageWidth = self.collectionView.frame.size.width + 10 /* Optional Photo app like gap between images. Or use [self pageWidth] in case if you want the next page be also visible */; 

    _currentPage = floor((self.collectionView.contentOffset.x - pageWidth/2)/pageWidth) + 1; 

    NSLog(@"Dragging - You are now on page %i", _currentPage); 
} 

- (void) scrollViewWillEndDragging:(UIScrollView*)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint*)targetContentOffset { 

    CGFloat pageWidth = self.collectionView.frame.size.width + 10; // [self pageWidth] 

    int newPage = _currentPage; 

    if (velocity.x == 0) { // slow dragging not lifting finger 
     newPage = floor((targetContentOffset->x - pageWidth/2)/pageWidth) + 1; 
    } 
    else { 
     newPage = velocity.x > 0 ? _currentPage + 1 : _currentPage - 1; 

     if (newPage < 0) 
      newPage = 0; 
     if (newPage > self.collectionView.contentSize.width/pageWidth) 
      newPage = ceil(self.collectionView.contentSize.width/pageWidth) - 1.0; 
    } 

    NSLog(@"Dragging - You will be on %i page (from page %i)", newPage, _currentPage); 

    *targetContentOffset = CGPointMake(newPage * pageWidth, targetContentOffset->y); 
} 

Oczywiście trzeba ustawić pagingEnabled = NIE. _currentPage jest klasą iVar. Dzięki http://www.mysamplecode.com/2012/12/ios-scrollview-example-with-paging.html za wskazanie właściwej drogi.

+6

To jest najlepsze rozwiązanie, które do tej pory znalazłem emulujące domyślną implementację (tylko przewijanie jednej strony na raz, obsługa powolnego przeciągania, itp.) –

+2

To działa, ale jeśli przeciągnięcie jest zakończone ze zbyt małą prędkością, to przesunie się zbyt wolno w stronę nowej strony. Wszelkie sugestie, jak to naprawić? – skagedal

+13

Aby odpowiedzieć na moje własne pytanie, ustaw self.scrollView.decelerationRate = UIScrollViewDecelerationRateFast i wszystko będzie świetnie! :) – skagedal

7

udało mi się przeprowadzić szybki test i dostaje to, aby poprawnie ogień i zrobić mój obiekt zatrzymania zgodnie z potrzebami. Zrobiłem to za pomocą następującego prostego testu:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset 
{ 
    targetContentOffset->x = scrollView.contentOffset.x - 10;  
} 

Wydaje się, że ta metoda może nie problem w kodzie, ale jest bardziej prawdopodobne, że „goodOffsetX” nie jest poprawnie obliczania poprawną wartość, aby zatrzymać się .

3

Swift 2.2:

extension SomeCollectionViewController { 

    override func scrollViewWillBeginDragging(scrollView: UIScrollView) { 
     let pageWidth = Float(collectionView!.frame.size.width) 
     let xCurrentOffset = Float(collectionView!.contentOffset.x) 
     currentPage = floor((xCurrentOffset - pageWidth/2)/pageWidth) + 1 
    } 

    override func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { 
     let pageWidth = Float(collectionView!.frame.size.width) 
     let targetXContentOffset = Float(targetContentOffset.memory.x) 
     let contentWidth = Float(collectionView!.contentSize.width) 

     var newPage = currentPage 
     if velocity.x == 0 { 
      newPage = floor((targetXContentOffset - pageWidth/2)/pageWidth) + 1 
     } else { 
      newPage = velocity.x > 0 ? currentPage + 1 : currentPage - 1 
      if newPage < 0 { 
       newPage = 0 
      } 
      if newPage > contentWidth/pageWidth { 
       newPage = ceil(contentWidth/pageWidth) - 1.0 
      } 
     } 
     targetContentOffset.memory.x = CGFloat(newPage * pageWidth) 
    } 
} 

użyłem również collectionView?.decelerationRate = UIScrollViewDecelerationRateFast jak sugeruje @skagedal poprawić szybkość strony.

6

SWIFT 3

Z demo tutaj https://github.com/damienromito/CollectionViewCustom

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { 

    let pageWidth = Float(itemWidth + itemSpacing) 
    let targetXContentOffset = Float(targetContentOffset.pointee.x) 
    let contentWidth = Float(collectionView!.contentSize.width ) 
    var newPage = Float(self.pageControl.currentPage) 

    if velocity.x == 0 { 
     newPage = floor((targetXContentOffset - Float(pageWidth)/2)/Float(pageWidth)) + 1.0 
    } else { 
     newPage = Float(velocity.x > 0 ? self.pageControl.currentPage + 1 : self.pageControl.currentPage - 1) 
     if newPage < 0 { 
      newPage = 0 
     } 
     if (newPage > contentWidth/pageWidth) { 
      newPage = ceil(contentWidth/pageWidth) - 1.0 
     } 
    } 
    let point = CGPoint (x: CGFloat(newPage * pageWidth), y: targetContentOffset.pointee.y) 
    targetContentOffset.pointee = point 
} 
+0

Warto zauważyć, że jeśli masz górną lub lewą wstawkę, musisz dodać ją do wartości punktu przed przypisaniem. – Sethmr

-1
public func scrollViewWillEndDragging(_ scrollView: UIScrollView ,withVelocity velocity: CGPoint, targetContentOffset: 
UnsafeMutablePointer<CGPoint>){ 

let pageWidth = Float(appWidth + itemSpacing) 
    let targetXContentOffset = Float(targetContentOffset.pointee.x) 
    var newPage = Float(currentPageIndex) 

    // I use this way calculate newPage: 
    newPage = roundf(targetXContentOffset/pageWidth); 

    //if velocity.x == 0 { 
    // newPage = floor((targetXContentOffset - Float(pageWidth)/2)/Float(pageWidth)) + 1.0 
    //} else { 
    // newPage = Float(velocity.x > 0 ? newPage + 1 : newPage - 1) 
    // if newPage < 0 { 
    //  newPage = 0 
    // } 
    // if (newPage > contentWidth/pageWidth) { 
    //  newPage = ceil(contentWidth/pageWidth) - 1.0 
    // } 
    //} 

    let targetOffsetX = CGFloat(newPage * pageWidth) 
    let point = CGPoint (x: targetOffsetX, y: targetContentOffset.pointee.y) 
    targetContentOffset.pointee = point 
} 
Powiązane problemy