2013-12-18 8 views
8

मैं UIPageViewController सेट अप करने का प्रयास कर रहा हूं जो NSUrlConnection डेटा पुल के माध्यम से पृष्ठ दृश्यों को गतिशील रूप से लोड करके अनन्त रूप से स्क्रॉल कर सकता है। मैं 3 विचारों से शुरू करता हूं: पिछला, curr, अगला; और pageData सरणी में पहला या अंतिम दृश्य पहुंचने पर अतिरिक्त दृश्य लोड करें।असीमित स्क्रॉल UIPageViewController

समस्या यह है कि मैं viewControllerBeforeViewController या viewControllerAfterViewController में अतिरिक्त दृश्य लोड करता हूं। ऐसा लगता है कि पृष्ठों के बीच एक ही स्वाइप करते समय इन विधियों को 2-3 बार कहा जा सकता है। उन्हें अर्ध-स्वाइप के दौरान भी बुलाया जा सकता है जो पेज संक्रमण को कभी खत्म नहीं करता है। इसका मतलब यह हो सकता है कि कई प्रीलोड लोड समय से पहले शुरू हो जाते हैं। फिर किसी भी तरह pageViewController वर्तमान स्थान भूल जाता है।

[self.pageViewController setViewControllers:@[[self.pageData objectAtIndex:gotoIdx]] direction:direction animated:NO completion:nil]; 

इस रेखा से नीचे pageViewController में डेटा की एक अतिरिक्त के संकेत देने के लिए, और हाँ उपयुक्त दृश्य पर जाने के लिए प्रयोग किया जाता है। जब मैं इसका उपयोग करना शुरू करता हूं, तो स्वाइप के साथ पिछली/अगली दृश्य पर जाने के बजाय, यह यादृच्छिक दृश्यों पर कूदना शुरू कर देता है। एक बार जब मैं पीछे की ओर स्वाइप करते समय आगे बढ़ना शुरू कर दिया ...

क्या प्रीलोड लोड करने के लिए एक और उचित जगह है जिसे केवल पृष्ठ संक्रमण पूरा होने के बाद बुलाया जाता है? और, क्या ऊपर की रेखा को बुलाया जाना है, या यह सुनिश्चित करने के लिए एक और विश्वसनीय तरीका है कि यह सही पृष्ठ पर जाता है? यहां इसे तार करने की कोशिश कर निराशाजनक लग रहा है।

// the init line, somewhere early on. uses Scoll style 
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationVertical options:nil]; 

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController { 
    NSUInteger index = [self.pageData indexOfObject:viewController]; 
    if(index == 1){ 
     // if loading last one on start, preload one more in advance 
     [self loadSecondaryCalData:-1 endView:[[self viewControllerAtIndex:index-1] retain]]; 
    } else if ((index == 0) || (index == NSNotFound)) { 
     return nil; 
    } 

    index--; 
    return [self viewControllerAtIndex:index]; 
} 

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController { 

    NSUInteger index = [self.pageData indexOfObject:viewController]; 
    if(index == [self.pageData count]-2){ 
     [self loadSecondaryCalData:1 endView:[[self viewControllerAtIndex:index+1] retain]]; // if last one, preload one more in advance 
    } else if (index == NSNotFound) { 
     return nil; 
    } 

    index++; 
    if (index == [self.pageData count]) { 
     return nil; 
    } 
    return [self viewControllerAtIndex:index]; 
}  


- (void)loadSecondaryCalData:(int)howMany endView:(CalendarViewController*)endView { 
    // initiate NSURLConnection async request for view data 
} 

- (void)loadSecondaryCals: (NSDictionary*)data { 
    // callback for async request 

    // ... process view, cal 

    // add new object to page data, at start or end 
    if(next){ 
     [self.pageData addObject:cal]; 
     gotoIdx = [self.pageData count]-2; 
     direction = UIPageViewControllerNavigationDirectionForward; 
    } else { 
     [self.pageData insertObject:cal atIndex:0]; 
     gotoIdx = 1; 
     direction = UIPageViewControllerNavigationDirectionReverse; 
    } 

    [self.pageViewController setViewControllers:@[[self.pageData objectAtIndex:gotoIdx]] direction:direction animated:NO completion:nil]; 

// alternate method to above line 
/* 
__block CalendarPageViewViewController *blocksafeSelf = self; 
__block int blocksafeGotoIdx = gotoIdx; 
__block UIPageViewControllerNavigationDirection blocksafeDirection = direction; 
[self.pageViewController setViewControllers:@[[self.pageData objectAtIndex:gotoIdx]] direction:direction animated:YES completion:^(BOOL finished){ 
    if(finished) 
    { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [blocksafeSelf.pageViewController setViewControllers:@[[blocksafeSelf.pageData objectAtIndex:blocksafeGotoIdx]] direction:blocksafeDirection animated:NO completion:nil]; 
     }); 
    } 
}]; 
*/ 


} 

अद्यतन:

नीचे तेजी से प्रतिक्रिया के लिए धन्यवाद, एक महान समारोह मैं के बारे में पता नहीं था संदर्भित। यहां प्रीलोड विधि है जो पूरी तरह से संक्रमण के पूरा होने पर केवल एक बार बुलाया जाता है। ऐसा लगता है कि विचारों के आस-पास अविश्वसनीय कूद और स्थान भूलने से काफी हद तक साफ हो गया है। धन्यवाद @sha!

// function to detect if we've reached the first or last item in views 
// detects for full completion only 
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed { 

    if(completed == TRUE && [previousViewControllers count] > 0 && [pageData count] > 1){ 
     CalendarViewController *firstCal = [pageData objectAtIndex:0]; 
     CalendarViewController *lastCal = [pageData objectAtIndex:([pageData count]-1)]; 

     CalendarViewController *prevCal = [previousViewControllers objectAtIndex:0]; 
     CalendarViewController *currCal = [[pageViewController viewControllers] objectAtIndex:0]; 

     NSLog(@"transition completed: %@ -> %@", prevCal.week_day_date, currCal.week_day_date); 
     if(currCal == firstCal){ 
      // preload on begining 
      [self loadSecondaryCalData:-1 endView:firstCal]; 
     } else if(currCal == lastCal){ 
      // preload to end 
      [self loadSecondaryCalData:1 endView:lastCal]; 
     } 
    } 
} 

उत्तर

5

मुझे लगता है कि आपको pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted: हैंडलर के अंदर अपनी लोडिंग कॉल करने की आवश्यकता है। एनीमेशन समाप्त होने पर नया तरीका कंट्रोलर बन जाएगा और नया व्यू कंट्रोलर सक्रिय हो जाएगा।

+0

धन्यवाद, यह बहुत अच्छा काम किया! समाधान के लिए ऊपर अद्यतन देखें। इस समारोह में इतना साफ है। – Miro

+0

स्विफ्ट 3: func pageViewController (_ पृष्ठ दृश्य नियंत्रक: UIPageViewController, didFinishAnimating समाप्त: बूल, पिछला दृश्य नियंत्रक: [UIViewController], संक्रमण पूर्ण पूर्ण: बूल) –

संबंधित मुद्दे