Próbuję zbudować złożony kontroler kontenera podzielonego widoku, który ułatwia dwa pojemniki o zmiennej wysokości, każdy z własnym zagnieżdżonym kontrolerem widoku. Na kontrolerze nadrzędnym istnieje globalny gest przesunięcia, który pozwala użytkownikowi przeciągnąć dowolne miejsce w kontenerze widoku i przesunąć "dzielnik" między widokami w górę iw dół. Ma też trochę inteligentną logikę wykrywania progowej pozycja, która będzie rozszerzać albo pogląd (lub wyzerowanie pozycji dzielnik):Przekazuj gest panoramowania kontenera nadrzędnego do zagnieżdżonego UICollectionView
to działa prawidłowo. Jest też sporo kodu do napisania, który chętnie udostępnię, ale nie sądzę, że jest to istotne, więc na razie pominę to.
mam teraz stara się komplikować dodając Zobacz kolekcję do dolnej widzenia:
udało mi się dogadać tak, że mogę przewinąć podział zobaczyć się z zdecydowany gest panoramy i przewijanie widoku kolekcji szybkim ruchem palca (gestem machnięcia, jak sądzę?), ale jest to naprawdę podporządkowane doświadczenie: nie można przesuwać widoku i przewijać kolekcji widok w tym samym czasie i oczekiwanie, że użytkownik konsekwentnie replikuje podobne, ale różne gesty, aby kontrolować widok, jest zbyt trudne do interakcji.
Aby rozwiązać ten problem, wypróbowałem kilka rozwiązań delegatów/protokołów, w których wykryłem pozycję dzielnika w widoku podziału i włącz/wyłącz canCancelTouchesInView
i/lub isUserInteractionEnable
w widoku kolekcji na podstawie tego, czy dno widok jest w pełni rozwinięty. Działa to do pewnego stopnia, ale nie w dwóch następujących scenariuszy:
- Gdy widok podzielonego rozdzielacz jest w pozycji domyślnej, jeśli patelnie użytkowników aż do miejsca, gdzie widok z dołu jest w pełni rozwinięty, a następnie utrzymuje się na przesuwanie się , widok kolekcji powinien zacząć się przewijać aż do zakończenia gestu.
- Jeśli dzielnik widoku dzielonego znajduje się u góry (widok dolnego kontenera jest w pełni rozwinięty), a widok kolekcji jest na górze , a nie, jeśli użytkownik się opuści, widok kolekcji powinien przewijać zamiast podziału dzielonego , dopóki widok kolekcji nie osiągnie najwyższej pozycji, wtedy widok podziału powinien powrócić do domyślnej pozycji.
Oto animacja ilustruje to zachowanie:
Biorąc pod uwagę to, zaczynam myśleć, że jedynym sposobem na rozwiązanie tego problemu jest stworzenie metody delegata na widoku podzielonego który mówi widok kolekcji, gdy widok z dołu jest na maksymalnej wysokości, który może następnie przechwycić gest panoramy rodzica lub przesunąć ekran do widoku kolekcji zamiast tego? Ale nie jestem pewien, jak to zrobić. Jeśli jestem na dobrej drodze z rozwiązaniem, moje pytanie brzmi po prostu: Jak mogę przekazać lub odrzucić gest panoramy do widoku kolekcji i czy widok kolekcji oddziałuje w taki sam sposób, jak w przypadku przechwycenia dotknięć przez to w pierwszej kolejności? Czy mogę zrobić coś metodami pointInside
lub touches____
?
Jeśli nie mogę tego zrobić w ten sposób, jak inaczej mogę rozwiązać ten problem?
Aktualizacja dla łowców nagród: Miałem pewne fragmentaryczne szczęścia tworząc metodę delegata na widoku zbiórki i wzywającą go na pojemniku widoku podzielonego ustawić właściwość shouldScroll
, przez który używam trochę pan kierunek i informacje o pozycji, aby określić, czy powinien przewijać się widok przewijania. Potem powrót tej wartości w UIGestureRecognizerDelegate
„s metody gestureRecognizer:shouldReceive touch:
Delegat:
// protocol delegate
protocol GalleryCollectionViewDelegate {
var shouldScroll: Bool? { get }
}
// shouldScroll property
private var _shouldScroll: Bool? = nil
var shouldScroll: Bool {
get {
// Will attempt to retrieve delegate value, or self set value, or return false
return self.galleryDelegate?.shouldScroll ?? self._shouldScroll ?? false
}
set {
self._shouldScroll = newValue
}
}
// UIGestureRecognizerDelegate method
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return shouldScroll
}
// ----------------
// Delegate property/getter called on the split view controller and the logic:
var shouldScroll: Bool? {
get {
return panTarget != self
}
}
var panTarget: UIViewController! {
get {
// Use intelligent position detection to determine whether the pan should be
// captured by the containing splitview or the gallery's collectionview
switch (viewState.currentPosition,
viewState.pan?.directionTravelled,
galleryScene.galleryCollectionView.isScrolled) {
case (.top, .up?, _), (.top, .down?, true): return galleryScene
default: return self
}
}
}
Działa OK gdy zaczniesz przesuwać, ale nie ma dobrze wykonywać raz przewijanie jest włączony na widok kolekcji, ponieważ prawie zawsze gest przewijania zastępuje gest panoramy. Zastanawiam się, czy mogę coś podłączyć do gestureRecognizer:shouldRecognizeSimultaneouslyWith:
, ale jeszcze mnie tam nie ma.
Czy możesz udostępnić swój kod, aby przetestować to zachowanie? W jednym z dwóch przypadków, o których wspomniałeś, wygląda na to, że collectionView powinien spożywać zdarzenia dotykowe, dopóki jego poziome przesunięcie nie przekroczy granic, co wydaje się dość proste. – Lukas
@Lukas Mogę, ale nie jestem pewien, czy to naprawdę pomoże rozwiązać problem - zarówno dlatego, że wiele jest zbudowanych w IB z ograniczeniami IB, a także dlatego, że już wiesz, że mam metody wykrywania delegatów, które strzelają dokładnie tak, jak ty "ve opisany:" gdy przesunięcie poziome osiągnie swoją górną granicę, collectionView powinien spożywać zdarzenia dotyku. " Mimo to, jeśli potrzebujesz jakiegoś kodu, mogę dodać trochę '¯ \ _ (ツ) _/¯' – brandonscript