11

Próbowałem się nauczyć UIPageViewController s i uderzyłem w problem, którego nie mogłem rozwiązać. To co próbowałem zrobić:ViewControllers with TextViews w UIPageViewController

  • Kroki:
    1. po prostu stworzony 2 Widok kontrolerów i kontroler widok w stronę storyboard.
    2. Następnie dodałem kod do Właściciela pliku PageViewController do zachowując się jak dataSource i delegate dla siebie.
    3. Kiedy biegałem, wszystko działało dobrze.
    4. Dodałem kilka przycisków i pól tekstowych do drugiego kontrolera widoku.
    5. Biegłem, działał dobrze.
    6. Teraz dodałem widok tekstowy do drugiego kontrolera widoku i uruchomiłem. Kiedy próbowałem coś napisać w widoku tekstowym, kontrolka strony zaatakowała i przeniesiona do pierwszego kontrolera widoku.

Czy ktokolwiek to przeżył?

@interface AMPageViewController : UIPageViewController <UIPageViewControllerDataSource, UIPageViewControllerDelegate> 

@end 

Realizacja:

#import "AMPageViewController.h" 

@interface AMPageViewController() 
{ 
    UIViewController *mainController; 
    UIViewController* socController; 
} 
@end 

@implementation AMPageViewController 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Custom initialization 
    } 
    return self; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" 
                  bundle: nil]; 

    mainController = (UIViewController*)[mainStoryboard instantiateViewControllerWithIdentifier: @"First"]; 
    socController = (UIViewController*)[mainStoryboard instantiateViewControllerWithIdentifier: @"Second"]; 
    [self setViewControllers:@[mainController] 
        direction:UIPageViewControllerNavigationDirectionForward 
        animated:NO 
        completion:nil]; 
    self.dataSource = self; 
    self.delegate = self; 
    // Do any additional setup after loading the view. 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController 
{ 
    if (viewController == socController) 
     return mainController; 
    else return nil; 
} 

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController 
{ 
    if (viewController == mainController) 
     return socController; 
    else return nil; 
} 

- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController 
{ 
    return 2; 
} 

- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController 
{ 
    return 0; 
} 


@end 

If you want to download and try the project

+0

widoku strony kontrolerów pozwala obrócić stronę albo przesuwając lub stukając w pobliżu jednej krawędzi. Zgaduję, że trafiasz w ten rozpoznawalny gest po lewej stronie. – rdelmar

+0

Nie sądzę. Proszę spojrzeć na załączony projekt https://dl.dropbox.com/u/62559842/PageViewcontrollerTest.zip – Bavan

+0

Tak, rozumiem co masz na myśli. Ma to coś wspólnego z przejściem przewijania. Jeśli zmienisz go na zwijanie, zachowuje się normalnie. – rdelmar

Odpowiedz

7

mam zbadane dużo w sprawie tego problemu. Wygląda na błąd związany z wewnętrznym (prywatnym) UIScrollView z UIPageViewController. Jeśli wyszukiwać StackOverflow znajdziesz wiele post z tym problemem i nie ma rozwiązania ...

I wydaje się, że UITextView (który jest AFAIR UIScrollView i ma wewnętrzną UIWebView), wysyła jakiś dziwny komunikat do łańcucha superwizyjnego, który sprawia, że ​​prywatny UIScrollView kontrolera UIPageViewController jest przewijany do lewego górnego rogu.

Próbowałbym zablokować tę wiadomość za pomocą metody swizzling, ale prawdopodobnie nie jest ona poprawna dla AppStore. Próbowałem więc innych rzeczy.

Ostateczne rozwiązanie jest bardzo proste: po prostu, umieść swój UITextView wewnątrz UIScrollView!

This is a link to your project updated

Jeśli tak, to w rozwiązaniu problemu!

Spróbuj i daj mi znać

EDIT:

Jak mogłem przybyć do tego rozwiązania:

intuicji.

Wiele śladów debugowania i stosu sprawiło, że pomyślałem, że problem był związany z błędem w systemie "zagnieżdżania UIScrollView" i wiadomości wysłanych z widoku wewnętrznego do jego superview.

UITextView dziedziczy z UIScrollView i ma wewnątrz UIWebDocumentView (prywatny), który jest innym UIScrollView. Podczas debugowania zobaczyłem wiele wiadomości (prywatnych metod), takich jak "przekaźnik superview" wysłanych do górnej UIScrollView. Z jakiegoś powodu wewnętrzny widok przewijania (UIWebDocumentView?) Wysyłał wiadomość/wydarzenie do jej widoku. Ten komunikat/zdarzenie (prawdopodobnie z powodu błędu) nie zatrzymywał się na zewnętrznym UITextView i został przekazany do UIScrollView obsługiwanego przez UIPageViewController.

Osadzanie UITextView wewnątrz prostego UIView nie było wystarczające, ponieważ UIView przekazuje wiadomość do jej superview, jeśli nie może obsłużyć. Pomyślałem: UIScrollView prawdopodobnie nie (w przeciwnym razie nie byłoby łatwe do zagnieżdżenia UIScrollViews), więc próbowałem i zadziałało.

To wszystko przypuszczenie, ponieważ przestałem sprawdzać, będę miał bardziej dogłębny wygląd w tym tygodniu.

+0

Tak. To działa. :) Dzięki. W każdym razie nie mam pojęcia, co mogło cię doprowadzić do znalezienia tego rozwiązania. Dzięki jeszcze raz. – Bavan

+0

Dodałem kilka szczegółów :-) – LombaX

0

nie zostały ustawione przed i po widoku kontrolerów, a także zajrzeć do pierwszego odpowiadającego za socController

1

Zbuduj system docelowy iOS-7.0.

Sztuczka z przewijaniem nie działa dla mnie. Próbowałem osadzić widok tekstowy w przewijanym widoku poprzez scenorys i kod, ale bez powodzenia.

Zrobiłem to po prostu opóźniając połączenie z tekstem. Niezbyt elegancko, ale to jedyna rzecz, do której do tej pory dotarłem.

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
     [self.textView becomeFirstResponder]; 
    }); 
} 

Testowany, działający na moim iPhone 5 i moim ultra-wolnym iPhone4. Chociaż jest całkowicie możliwe, że jakikolwiek szczegół implementacji umożliwia, aby tekst mógł stać się responderem, może zająć więcej czasu niż ustawiony. Pamiętaj, że to nie jest kuloodporne.

--EDIT--

Cóż ... to działa na moim iPhone 4 trzepak z opóźnieniem 0.0000000000000001

Powiązane problemy