एक वास्तविक परियोजना में लियांग-नॉट एल्गोरिथ्म, या मैंने iOS के लिए पाठक कैसे किया

सभी को नमस्कार! इस बार मैं बताना चाहता हूं कि मैंने iBooks के विकल्प को कैसे लागू किया। अपनी पिछली पोस्ट में, मैंने पाठ में सॉफ्ट हाइफ़न की व्यवस्था के लिए एल्गोरिथ्म के बारे में लिखा था। यह सिर्फ तब उपयोगी था जब आप अपना पाठक बना रहे हों, आप इसके काम का मूल्यांकन आवेदन में कर सकते हैं । लेकिन इसके अलावा, परियोजना के कार्यान्वयन के दौरान मुझे कई अन्य दिलचस्प चीजों के साथ आना पड़ा, जैसे कि सीएसएस के साथ HTML को पार्स करना और प्रदान करना, कस्टम डिजाइन नियंत्रणों का कार्यान्वयन, आदि। हमारे डिजाइनर रशपास्ता मुझे एक तरह के गैर-मानक इंटरफ़ेस के साथ समस्याओं को फेंकना पसंद करते हैं जिन्हें कलमों के साथ लागू करने की आवश्यकता है, लेकिन पहले कुछ चीजें।

यूआई (या टैम्बोरिन के साथ नृत्य)


परियोजना में यूआई के संदर्भ में, क्षैतिज पेजिंग के साथ ग्रिड टेबल बनाना आसान काम नहीं था। हमेशा की तरह, तैयार किए गए समाधानों की तलाश में, मैं stackoverflow.com पर चढ़ गया, लेकिन अफसोस, मैं जो कुछ भी करता था वह एक डिग्री या किसी अन्य अनुपयोगी था।
AQGridView के लिए उच्च उम्मीदें थीं , लेकिन जैसा कि यह निकला, क्षैतिज भरने और पेजिंग से केवल खाली स्टब्स हैं। यह उसे दूसरा मौका देने और तालिका 90 डिग्री के रोटेशन के साथ एक परिचित चाल को लागू करने का निर्णय लिया गया था। सबसे पहले, यह विकल्प काम करने के लिए और अधिक या कम स्वीकार्य लग रहा था, लेकिन यहां भी पत्थर थे।

AQGridView में और मानक UIScrollView में कीड़े ने मुझे इस घटक का उपयोग करने से हतोत्साहित किया। कुछ स्थितियों में, ग्रिड लगातार टूट गया: कुछ कोशिकाएं गिर गईं और क्रम लगातार भाग गया। मेरी वक्रता के बारे में संदेह को दूर करने के लिए, मैंने किट से डेमो पर समस्या को पुन: उत्पन्न करने की कोशिश की - बग की पुष्टि की गई।
UIScrollView और इसके व्युत्पन्न के लिए - यहाँ मैंने पहली बार AQGridView पर पाप किया था , लेकिन जब मैंने UITableView का उपयोग करना शुरू किया, तो समस्या दोहराई गई। बग का सार यह है कि जब UIScrollView को परिवर्तन के माध्यम से चालू किया जाता है, तो उछाल प्रभाव गिर गया, जो कि iOS के लिए बहुत बदसूरत और अप्राकृतिक था।

जाहिर है, यह पता चला है कि डिवाइस को घुमाए जाने पर UIScrollView का आकार बदलना और स्थानांतरित करना था, जो कि लेआउटब्यूडर हैंडलर के माध्यम से आपके हाथों से किया गया था। अपने शर्मनाक तमाशबीनों को लेते हुए, मुझे पता चला कि सब कुछ केंद्र की संपत्ति के माध्यम से घुमाए गए UIScrollView की स्थिति को तोड़ता है। शायद कुछ अन्य शर्तें थीं, लेकिन इतने सारे विकल्प आजमाए गए हैं कि आप अब याद नहीं रख सकते।

यह सब लंबा इतिहास अच्छा पुराने UITableView के साथ विकृत होने के लिए समाप्त हो गया। मैंने बाउंस को ठीक किया, और रोटेशन के साथ समस्या हल हो गई। उसने टेबल सेल को एक पेज का आकार बनाया और उसमें कई उप-कोशिकाएँ थीं, जिनमें से प्रत्येक को एक अलग वर्ग के उदाहरण के रूप में लागू किया गया। यह इस तरह निकला:



HTML और Liang-Knuth एल्गोरिथ्म के साथ काम करें।


लोकप्रिय ई-बुक प्रारूपों को प्रस्तुत करना और प्रस्तुत करना एक और कहानी है। HTML सिद्धांत रूप में मुश्किल नहीं है, libxml ने बहुत अच्छा काम किया। HTML फ़ाइल को पुनरावर्ती रूप से संसाधित किया जाता है, पाठ के ब्लॉक में विभाजित होता है, प्रत्येक ब्लॉक के लिए संबंधित विशेषताएँ निर्धारित की जाती हैं। यह CoreText से एक फ्रेमसेट्टर में ड्राइव करने के लिए बनी हुई है और आप कर चुके हैं। लेकिन वहाँ यह था! चौड़ाई में हाइफ़नेशन और संरेखण बनाने के लिए आवश्यक है। मुझे एक स्तर नीचे जाना था और फ्रेमसेट्टर नहीं, बल्कि टाइपसेट्टर का उपयोग करना था। इसका उपयोग करके, आप पाठ को लाइनों में, उदाहरण के लिए, फ़ंक्शन के साथ काट सकते हैं

CFIndex CTTypesetterSuggestClusterBreak( CTTypesetterRef typesetter, CFIndex startIndex, double width); 

लाइनों में तोड़ने की प्रक्रिया में, आपको अंतराल की जगह निर्धारित करने की आवश्यकता है। यदि किसी शब्द के बीच में अंतराल होता है, तो आपको सही ढंग से हाइफ़न लगाने की आवश्यकता है। यह वह जगह है जहां उपरोक्त लिआंग-नॉट एल्गोरिथ्म का कार्यान्वयन बचाव के लिए आता है।

रेंडर (या उपयोगकर्ता प्रतीक्षा न करें!)


जो कुछ बचा है वह पृष्ठों में पाठ की पंक्तियों के परिणामी पर्वत को काटने के लिए है और आप प्रस्तुत कर सकते हैं। जाहिर है, यह पता चला है कि प्रतिपादन से पहले पाठ प्रसंस्करण कार्यों के इस सभी गुच्छा समय की एक पूरी गुच्छा लेता है। प्रोफाइलर से, मुझे एहसास हुआ कि हाइफ़नेशन को दोष देना था। मैंने पुस्तक की गणना को पृष्ठभूमि में और एक अलग धागे में निकाल दिया - यह तेजी से काम करना शुरू कर दिया।

केवल नकारात्मक यह है कि जबकि प्रतिपादन प्रगति पर है, आप रिवाइंड स्लाइडर का उपयोग नहीं कर सकते। यदि किसी ऐसे अध्याय में जाना आवश्यक है जिसे अभी तक संसाधित नहीं किया गया है, तो इसे स्क्रीन पर जल्दी से जल्दी प्रदर्शित करने के लिए इसे प्रसंस्करण कतार में पहले रखें।

नतीजतन, यह बहुत अच्छा निकला, और iPad पर पुस्तकों को बहुत तेज़ी से संसाधित किया जाता है (यह देखते हुए कि यह मक्खी पर एक रेंडर है)।

यहाँ प्रस्तुत पृष्ठ विभिन्न स्क्रीन ओरिएंटेशन में दिखते हैं:



HTTP AFNetworking पर काम करने के लिए, हमेशा की तरह, अत्यधिक अनुशंसित था। सच है, मेमोरी लीक के लिए आवेदन का विश्लेषण करते समय एक "लेकिन" था, परिपत्र लिंक के साथ जुड़े फ़ाइल डाउनलोड प्रगति के प्रदर्शन के साथ एक समस्या सामने आई थी। SetDownloadProgressBlock विधि में इस तरह एक ब्लॉक था :

 if ([self.progressDelegate respondsToSelector:@selector(fileDownloadRequest:progressBytes:withTotalBytes:)]) { [self.progressDelegate fileDownloadRequest:self progressBytes:alreadyDownloadedBytes+totalBytesRead withTotalBytes:alreadyDownloadedBytes+totalBytesExpectedToRead]; } 

ब्लॉक के कोड में स्वयं की उपस्थिति एक चक्रीय निर्भरता का कारण बनी। यह एक अलग स्थानीय चर बनाकर हल किया जाता है जिसमें प्रतिनिधि को सूचक की प्रतिलिपि बनाई जाती है, और यह चर पहले से ही ब्लॉक में उपयोग किया जाता है। यह इस तरह बन गया:

 id<FileDownloadProgressDelegate> progress = self.progressDelegate; [self.request setDownloadProgressBlock:^(NSInteger bytesRead, NSInteger totalBytesRead, NSInteger totalBytesExpectedToRead) { if ([progress respondsToSelector:@selector(fileDownloadRequest:progressBytes:withTotalBytes:)]) { [progress fileDownloadRequest:self progressBytes:alreadyDownloadedBytes+totalBytesRead withTotalBytes:alreadyDownloadedBytes+totalBytesExpectedToRead]; } }]; 

भविष्य में, जैसा कि मेरे पास खाली समय है, मैं iOS के लिए अपने विकास के अनुभव का वर्णन करना जारी रखूंगा, लेकिन अब मैं आपको टिप्पणियों में अपने काम के परिणाम पर चर्चा करने के लिए आमंत्रित करता हूं।

Source: https://habr.com/ru/post/In144942/


All Articles