2009-09-29 22 views
20

तो, UITableView अनिवार्य रूप से "अनंत" स्क्रॉलिंग का समर्थन करता है। वहां एक सीमा हो सकती है लेकिन वह चूसने वाला एक looonnnggg समय के लिए स्क्रॉल कर सकते हैं। मैं इस व्यवहार को UIScrollView के साथ नकल करना चाहता हूं लेकिन दो मौलिक बाधाएं हैं:UIScrollView। "अनंत" स्क्रॉल/ज़ूम लागू करने पर कोई विचार?

1) scrollView.contentSize निर्माण समय पर तय किया गया है। 2) ज़ूमिंग किसी भी आलसी लोडिंग योजना को नरक में उड़ सकती है क्योंकि इससे इन्फिनेट डेटा विस्फोट हो सकता है।

क्या अन्य लोगों ने इस विचार पर विचार किया है? हाँ, मुझे पता है, हम अनिवार्य रूप से यहां Google मानचित्र को फिर से बनाने के बारे में बात कर रहे हैं। किसी भी अंतर्दृष्टि की सराहना की जाएगी।

चीयर्स, डौग

+0

क्या आपने MapKit को देखा है? –

+0

अच्छी तरह से UITableView UIScrollView –

उत्तर

10

हालांकि यह वास्तव में एक अनंत UIScrollView के लिए असंभव है, वहाँ कुछ सरल चाल आपको लगता है कि व्यवहार का अनुकरण करने के लिए उपयोग कर सकते हैं।

  1. हैंडलिंग तय contentSize: कुछ निश्चित-आकार दृश्य आपके स्क्रॉल दृश्य द्वारा नियंत्रित किया जाता है, और प्रक्षेपण या इन्स्टेन्शियशन पर, सामग्री ऑफसेट ताकि आप संभाला दृश्य के बीच दिखाई दे रहा है निर्धारित किया है। फिर सामग्री ऑफ़सेट (केवीओ या किसी अन्य विधि का उपयोग करके) देखें, और यदि आप किसी भी किनारे के पास हैं, तो सामग्री के नए सेट (उचित रूप से ऑफसेट) के साथ दृश्य की सामग्री अपडेट करें और स्क्रॉल व्यू की contentOffset प्रॉपर्टी को वापस रीसेट करने के लिए रीसेट करें मध्य।
  2. ज़ूमिंग को संभालना: कुछ ऐसा ही करें, केवल इस बार स्क्रॉल व्यू पर ज़ूम कारक देखें। जब भी यह किसी निश्चित बिंदु पर पहुंच जाता है, तो आप जो भी डेटा पेश कर रहे हैं उसमें कुछ हेरफेर करें ताकि यह ज़ूम हो जाए, फिर ज़ूम कारक को 1.0 पर रीसेट करें। उदाहरण के लिए, यदि आप किसी छवि को स्क्रॉल कर रहे हैं और यह दो बार बड़ा दिखाई देने के लिए ज़ूम किया जाता है, तो छवि को दो बार बड़ा बनाने के लिए प्रोग्रामेटिक रूप से किसी प्रकार का परिवर्तन लागू होता है, फिर स्क्रॉल व्यू के ज़ूम कारक को 1.0 पर रीसेट करें। छवि अभी भी ज़ूम इन दिखाई देगी, लेकिन स्क्रॉल व्यू ज़रूरी ज़ूमिंग जारी रखने में सक्षम होगा। (गूगल मैप्स इसे एक कदम आगे है, जहां यह आलसी-भार उपयोगकर्ता के रूप में और अधिक विस्तृत विचारों ज़ूम लेता है - आप या इसे लागू करने के लिए चुन नहीं हो सकता है।)
+2

का उप-वर्ग है, यहां एक लिंक है http://iphonedevelopment.blogspot.com/2009/02/kvo-and-iphone-sdk.html किसी के लिए केवीओ समझाते हुए जो यह नहीं जानता कि वह क्या है। जैसे मैंने नहीं किया। – Grumdrig

+4

इस समाधान के साथ समस्या यह है कि 'setContentOffset' जो भी स्क्रॉलिंग हो रहा है उसे रद्द करता है और गति अचानक बंद हो जाती है। मुझे दृश्य की गति को निर्धारित करने के तरीके के बारे में पता नहीं है, या अगर मैंने किया तो उस गति को पुनरारंभ कैसे करें। – Grumdrig

+0

लेकिन सामग्री ऑफसेट को बदलने में परेशानी क्यों है? इसे स्क्रॉल करने दें, बस सुनिश्चित करें कि आप उपयोगकर्ता के देखने के अनुरूप छवि दृश्यों को बनाए रखें और स्थानांतरित करें। –

0

शायद कुछ विशाल मूल्य के लिए contentSize करना और फिर एक सीमित चलती दृश्य स्थिति को ट्रैक करने के लिए चारों ओर अंतर्निहित विचारों की संख्या टाइलिंग नमूना में चाल चलती है।

अंत में किनारे तक पहुंचने की संभावना को कम करने और अचानक हाल ही में दृश्य (जो वर्तमान में गति में किसी भी स्क्रॉलिंग को रद्द करता है) को कम करने के लिए, दृश्य समय-समय पर स्थिर होने पर देखा जा सकता है।

वैसे भी, मैं यही करने की कोशिश कर रहा हूं।

+0

यह ठीक काम करता है, एफवाईआई। मैं 4 निहित दृश्यों का उपयोग उसी आकार के रूप में कर रहा हूं जिसमें स्क्रॉलिंग के साथ मार्च शामिल है। मैंने स्क्रॉलिंग नमूना (ऊपरी भाग) के ऊपर अपना कोड आधारित किया है। – Grumdrig

+0

आधिकारिक ऐप्पल अनंत-स्क्रॉल उदाहरण प्रोजेक्ट इस विधि का उपयोग करने का सुझाव देता है। – zakdances

13

मैंने अभी मेरे लिए इन्फिटिन स्क्रॉल को लागू करना समाप्त कर दिया है। मेरे कार्यान्वयन में मेरे पास स्क्रॉल व्यू और नेविगेशनबटन के साथ UITableViewCell है। स्क्रॉल व्यू में एक ही चौड़ाई वाले एक्स दृश्य होते हैं। विचार क्षैतिज रूप से पंक्तिबद्ध हैं और पेजिंग सक्षम है।

scrollView.clipsToBounds = YES; 
scrollView.scrollEnabled = YES; 
scrollView.pagingEnabled = YES; 
scrollView.showsHorizontalScrollIndicator = NO; 

मेरे codelogic निम्नलिखित की तरह है:

  1. मेरी प्रारंभ समारोह में मैं
    • सभी दृश्यों (scrollview के लिए) और बनाने
    • उन्हें एक सरणी और
    • में डाल दिया
    • उन्हें स्क्रॉल में जोड़ें
  2. फिर मैं एक फ़ंक्शन को कॉल करता हूं जो प्रत्येक दृश्य के लिए लूप में गणना करता है (प्रत्येक बार जब आप स्क्रॉल का पता लगाते हैं तो इस फ़ंक्शन को भी कॉल करने की आवश्यकता होगी)। यह हमेशा सरणी का पहला तत्व लेता है और फ्रेम को (0,0, ..., ...) पर सेट करता है, दूसरा (i * width, 0, ...., ....) और इसलिए पर। समारोह कहा जाता beeing इस तरह दिखता है:

    - (void)updateOffsetsOfViews{ 
        int xpos = 0; 
        for (int i=0; i<[views count]; i++) { 
         UIImageView *_view = [views objectAtIndex:i]; 
         CGRect aFrame = _view.frame; 
         aFrame.origin.x = xpos; 
         aFrame.origin.y = 0.0; 
         _view.frame = aFrame; 
         xpos += viewWidth; 
        } 
        float center = 0; 
        if(fmod([views count],2) == 1){ 
         center = viewWidth * ([views count]-1)/2; 
        }else { 
         center = viewWidth * [views count]/2; 
        } 
        [scrollView setContentOffset:CGPointMake(center, 0)]; 
        lastOffset = center; 
    } 
    
  3. तो (अब भी आरंभीकरण प्रक्रिया में) मैं एक पर्यवेक्षक

    [scrollView addObserver:self forKeyPath:@"contentOffset" options:0 context:nil]; 
    

    जोड़ें ताकि scrollview परिवर्तन मैं (observeValueForKeyPath) पाने में हर बार कुछ - समारोह कहा जाता है, जो इस प्रकार है:

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
    { 
        UIImageView *_viewFirst = (UIImageView *)[views objectAtIndex:0]; 
        if (fmod([scrollView contentOffset].x,viewWidth) == 0.0) { 
         if ([scrollView contentOffset].x > lastOffset) { 
          [views removeObjectAtIndex:0]; 
          [views addObject:_viewFirst];     
          [self updateOffsetsOfViews];  
         }else if ([scrollView contentOffset].x < lastOffset) { 
          UIImageView *_viewLast = (UIImageView *)[views lastObject]; 
          [views removeLastObject]; 
          [views insertObject:_viewLast atIndex:0];    
          [self updateOffsetsOfViews]; 
         } 
        } 
    } 
    
  4. और dealloc या viewDidUnload में (आप इसे कैसे लागू पर निर्भर करता है) के लिए मत भूलना रेमो को पर्यवेक्षक है।

    [scrollView removeObserver:self forKeyPath:@"contentOffset"]; 
    

आशा इस मदद करता है, तो आप कुछ भूमि के ऊपर ध्यान दे सकते हैं, लेकिन मेरे कार्यान्वयन में मैं भी 5 पृष्ठ (ठीक है ... असीमित) एक बार में स्क्रॉल तरह का समर्थन और स्क्रॉल autoanimated आदि ताकि आप कुछ देख सकते हैं जिसे फेंक दिया जा सकता है।

+1

काफी अच्छा समाधान है, लेकिन == का उपयोग कर फ्लोटिंग पॉइंट तुलना नहीं करते हैं, यह टूट जाएगा। –

+0

मैंने आपके कोड की कोशिश की।लेकिन जब मैं जल्दी से 2 पेज स्क्रॉल करता हूं, तो कोड ठीक से संभाल नहीं पाएगा। – jeswang

2

ध्यान रखें कि स्क्रॉल एनिमेटेड होने पर, contentOffset कई बार बदलता है, न केवल पृष्ठ द्वारा पृष्ठ पर, बल्कि एनीमेशन में प्रत्येक चरण के साथ।

4

StreetScroller ऐप्पल से नमूना प्रोजेक्ट दर्शाता है कि UIScrollView में अनंत स्क्रॉलिंग कैसे करें।

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