2015-03-05 25 views
8

Próbuję zaimplementować UIRefreshControl w moim projekcie na UICollectionView. Działa tak, jak zamierzono, ale muszę wyciągnąć UICollectionView około 3 razy tyle, co wysokość refreshControl, gdy się kręci (gdy użytkownik puści). Widziałem inne aplikacje, w których wystarczy pociągnąć do wysokości refreshControl, gdy się kręci. Jak zmienić kwotę, którą muszę usunąć?UIRefreshControl musi zostać rozebrany zbyt daleko

Kod:

(void)viewDidLoad { 
    [super viewDidLoad]; 

    [self.collectionView setBackgroundColor:[UIColor clearColor]]; 
    self.refreshControl = [UIRefreshControl new]; 
    [self.refreshControl addTarget:self action:@selector(refreshFavorites) forControlEvents:UIControlEventValueChanged]; 
    [self.collectionView addSubview:self.refreshControl]; 
    self.collectionView.alwaysBounceVertical = YES; 
} 

Dołączone są zdjęcia, które pomogą uzmysłowić, co mam na myśli. Mój collectionView ma jeden wiersz (jednolity czerwony). Przestrzeń między czerwonym a refreshControl jest po prostu przestrzenią, którą przeciągam, aby spróbować aktywować refreshControl.

Na tym obrazku prawie aktywowałem kontrolę i już ściągnąłem znaczną ilość na ekran.

enter image description here

W ten obraz mam aktywowane kontrolę i zaczyna ładować (po ~ 20-30 skacze pix, ale wciąż podkreśla, jak istotna jest to)

enter image description here

Ten obraz pokazuje kontrolkę w stanie "odpoczynku" po jej aktywacji i wykonuje animację.

enter image description here

Próbowałem ustawienie klatkę UIRefreshControl próbować kontrolować wysokość, ale to nie działa. Zmieniłem także rozmiar w rozmiarze collectionView:layout:sizeForItemAtIndexPath, który nie pomógł.

+1

Czy udało Ci się rozwiązać ten problem? Mając ten sam problem. – gmat1014

Odpowiedz

2

Jeśli UIRefreshControl wymaga zbyt dużego pobrania, aby uruchomić, może to być błąd SDK iOS.

Polecam rozwiązania tej sytuacji z pomocą kontrolera widoku za:

- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    // Force update the snapping height of refresh control. 
    [self.refreshControl didMoveToSuperview]; 
} 

Także, jeśli nie przeszkadza użytku prywatnego API i wymaga dokładniejszej kontroli, można napisać tak:

- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    @try { 
     [self.refreshControl setValue:@(60) forKey:@"_snappingHeight"]; 
    } 
    @catch (NSException *exception) { 
    } 
} 

Działa to w systemie iOS 7-10. Brak problemu z recenzją App Store.


zajrzeć

UIRefreshControl ma właściwość o nazwie snappingHeight. Ta właściwość kontroluje rozkład potrzeb użytkownika na odległość. Ale niestety ta wartość nie zawsze jest poprawnie ustawiona, zwłaszcza że masz niestandardową hierarchię widoków.

UIRefreshControl ma prywatną metodę wywoławczą _updateSnappingHeight, ta metoda jest również wywoływana w didMoveToSuperview. Dlatego wywołanie ręczne może zaktualizować błędną wartość przyciągania.

+0

Świetne, dzięki za napisanie też. – Mardoxx

0

mieliśmy problem z tym w iOS 10,2 Więc dla każdego, kto boryka się z tym, że znalazł sposób, aby to zrobić bez konieczności dotykania prywatnych metod API (chociaż to nie rozwiąże problemu, jak również).

Znalazłem problem z urządzeniem obracającym się na iPadzie. UIRefreshControl zachowywał się poprawnie w trybie portretowym, ale zaczynał działać nieprawidłowo po obróceniu urządzenia. Po tym nie miało znaczenia, w jakiej orientacji było, zawsze trzeba było przeciągnąć zbyt daleko, niż wymagało aktywacji.

Moje rozwiązanie oparto na tej odpowiedzi: Offsetting UIRefreshControl

Próbowałem ustawienie klatkę UIRefreshControl gdy urządzenie obraca się i to zadziałało. Nie jest idealny, ponieważ nie korzysta z AutoLayout, ale jest nieco czystszy niż w przypadku prywatnych interfejsów API.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil]; 

-(void)didRotate:(NSNotification *)notification { 

    [self.refreshControl setFrame:CGRectMake(0, 0, 20, 20)]; 
    [self.refreshControl setNeedsLayout]; 

} 
0

Dla osób wciąż szukających odpowiedzi na to pytanie. Mam określony i najlepszą możliwą odpowiedź do tej pory ...

SWIFT 3:

Wewnątrz viewDidLoad():

self.refresher = UIRefreshControl() 
self.refresher.tintColor = UIColor.red 
self.scrollView.addSubview(self.refresher) 

Następny Jeśli View jest ViewController - Wdrożenie ScrollViewDelegate tak:

class YourViewController: UIViewController, UIScrollViewDelegate 

Gdy masz Scrollview @IBOulet związane ... Śmiało i ustawić delegata Scrollview do siebie wewnątrz viewDidLoad() tak:

self.scrollView.delegate = self 

Następnie, skoro masz delegaci ustawić, skonfigurować funkcję scrollViewDidScroll i wdrożyć go, aby sprawdzić, czy dana osoba rozebrany przeszedł -90 tak:

func scrollViewDidScroll(_ scrollView: UIScrollView) { 
    if scrollView == self.scrollView 
    { 
     if scrollView.contentOffset.y < -90 && !self.refresher.isRefreshing{ 
      self.refresher.beginRefreshing() 
      self.Refresh() 
      print("zz refreshing") 
     } 
    } 
} 

Teraz zawiadomienie nie mają

self.refresher.addTarget(self, action: #selector(self.Refresh()), for: UIControlEvents.valueChanged) 

i nie musimy go wcale. Zamiast tego wywołujemy funkcję beginRefresh(), po której następuje faktyczna funkcja ... Po prostu upewnij się, że wywołujesz endRefresh() gdzieś, gdzie chcesz ją zakończyć.

Powiązane problemy