UIRefreshControl w UICollectionView działa tylko wtedy, gdy kolekcja wypełnia wysokość kontenera

142

Próbuję dodać a UIRefreshControldo UICollectionView, ale problem polega na tym, że formant odświeżania nie pojawia się, chyba że widok kolekcji wypełnia wysokość jego kontenera nadrzędnego. Innymi słowy, o ile widok kolekcji nie jest wystarczająco długi, aby wymagać przewijania, nie można go wyciągnąć w dół, aby wyświetlić widok kontrolki odświeżania. Gdy tylko kolekcja przekroczy wysokość swojego kontenera nadrzędnego, jest rozwijana w dół i ujawnia widok odświeżania.

Skonfigurowałem szybki projekt na iOS z tylko UICollectionViewwewnętrznym widokiem głównym, z wyjściem do widoku kolekcji, aby móc dodać UIRefreshControldo niego viewDidLoad. Istnieje również komórka prototypowa z identyfikatorem ponownego wykorzystaniacCell

To jest cały kod kontrolera, który całkiem dobrze pokazuje problem. W tym kodzie ustawiłem wysokość komórki na 100, co nie wystarczy do wypełnienia ekranu, dlatego widok nie może zostać wyciągnięty, a kontrolka odświeżania się nie pokaże. Ustaw go na coś wyższego, aby wypełnić ekran, a potem zadziała. Jakieś pomysły?

@interface ViewController () <UICollectionViewDelegateFlowLayout, UICollectionViewDataSource>
@property (strong, nonatomic) IBOutlet UICollectionView *collectionView;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
    [self.collectionView addSubview:refreshControl];
}

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
}

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return 1;
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    return [collectionView dequeueReusableCellWithReuseIdentifier:@"cCell" forIndexPath:indexPath];
}

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return CGSizeMake(self.view.frame.size.width, 100);
}
Merott
źródło
zobacz to na iOS 10 stackoverflow.com/questions/19483511/…
Anish Parajuli 웃
1
UżyjalwaysBounceVertical
onmyway133

Odpowiedzi:

395

Spróbuj tego:

self.collectionView.alwaysBounceVertical = YES;

Kompletny kod dla UIRefreshControl

UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
refreshControl.tintColor = [UIColor grayColor];
[refreshControl addTarget:self action:@selector(refershControlAction) forControlEvents:UIControlEventValueChanged];
[self.collectionView addSubview:refreshControl];
self.collectionView.alwaysBounceVertical = YES;
Larry
źródło
1
Niesamowite, ta linia jest dokładną poprawką, reszta kodu nie ma znaczenia. Niezły początek dla Ciebie w StackOverflow! Twoje zdrowie!
Merott
7
Nie ma problemu. To oczywiste, że jestem nowicjuszem, hę. W każdym razie okazuje się, że utknąłem w tej samej sytuacji, gdy zobaczyłem Twój post. Kiedy znalazłem rozwiązanie, pomyślałem, że zdecydowanie powinienem się nim podzielić. Pozdrawiam
Larry
6
Cóż, Juan, prawdopodobnie znalazłeś już odpowiedź na swoje pytanie. Aby jednak przywrócić sterowanie odświeżaniem do normalnego stanu po odświeżeniu, należy wywołać [refreshControl endRefreshing].
Merott
2
Niestety nie jest to już obsługiwane. UIRefreshControl może być używany tylko z UITableViewController i teraz jest ściśle wymuszany.
Luke Van W
3
W iOS 10 UIScrollView(nadzór UICollectionView) ma refreshControlteraz właściwość developer.apple.com/videos/play/wwdc2016/219/?time=2033
Streeter
29

Atrybuty / Przewijanie widoku / Odbijanie w pionie w Storyboard / Xib

wprowadź opis obrazu tutaj

avdyushin
źródło
23

Szybka odpowiedź Larry'ego:

    let refreshControl = UIRefreshControl()
    refreshControl.tintColor = UIColor.blueColor()
    refreshControl.addTarget(self, action: "refresh", forControlEvents: .ValueChanged)
    collectionView.addSubview(refreshControl)
    collectionView.alwaysBounceVertical = true

Swift 3:

    let refreshControl = UIRefreshControl()
    refreshControl.tintColor = .blue
    refreshControl.addTarget(self, action: #selector(refresh), for: .valueChanged)
    collectionView.addSubview(refreshControl)
    collectionView.alwaysBounceVertical = true
Andrew Schreiber
źródło
Const podaje błąd niezdefiniowanej zmiennej. jeśli ktoś napotka tę samą sytuację, po prostu zastąp ją UIColor.whiteColor()kolorem lub innym kolorem.
Faisal
1
Również do użytku Swift 2.2action: #selector(self.refresh)
Faisal
1

Jeśli Twój collectionviewrozmiar treści jest wystarczająco duży, aby przewijać w pionie, jest OK, ale w Twoim przypadku tak nie jest.

Musisz włączyć właściwość AlwaysBounceVertical, aby móc ustawićself.collectionView.alwaysBounceVertical = YES;

Nghia Luong
źródło
0

Ja też miałem do czynienia z tym samym problemem, nie mogłem korzystać z funkcji, UIRefreshControldopóki UICollectionViewrozmiar zawartości nie był wystarczająco duży, aby przewijać w pionie,

Ustawienie bounceswłaściwości UICollectionViewrozwiązało to

[self.collectionView setBounces:YES];
[self.collectionView setAlwaysBounceVertical:YES];
Saif
źródło
0

Dzwonię beginRefreshing()zaraz potem viewDidLoad(), ale na niektórych ekranach to nie działa. I tylko collectionView.layoutIfNeeded()w viewDidLoad()bardzo mi pomógł

Nikolai Ischuk
źródło
0

Musisz sprawdzić wywołanie interfejsu API, jeśli widok kolekcji jest w stanie odświeżania, a następnie zakończ odświeżanie, aby odrzucić kontrolę odświeżania.

private let refreshControl = UIRefreshControl()
 refreshControl.tintColor = .white
 refreshControl.addTarget(self, action: #selector(refreshData), for: .valueChanged)
 collectionView.addSubview(refreshControl)
 @objc func refreshData() {
    // API Call
 }
// Disable refresh control if already refreshing 
if refreshControl.isRefreshing {
    refreshControl.endRefreshing()
}
Asad Jamil
źródło
Należy zauważyć, że odbijanie przy przewijaniu jest włączone w moim pliku storyboardu.
Asad Jamil