2012-08-28 12 views
7

के अंत में स्थानांतरित करने का कारण बनता है मुझे सबक्लास अपने NSTextStorage प्रतिनिधि के रूप में कार्य कर रहा है। कुछ मायनों NSTextStorage को संशोधित करने से प्रविष्टि बिंदु

  • पाठ मूल्यांकन में

    1. हाइलाइट पाठ और उसके बाद TextView का जवाब संलग्न: मैं 2 काम करने की कोशिश कर रहा हूँ।

    मैं इसे दो अलग-अलग तरीकों से कर रहा हूं, दोनों - (void)textStorageWillProcessEditing:(NSNotification *)notification प्रतिनिधि कॉलबैक द्वारा आमंत्रित किए गए हैं।

    मैं सिंटैक्स को ठीक से हाइलाइट कर सकता हूं, लेकिन जब मेरा जवाब जोड़ने की बात आती है, प्रविष्टि बिंदु के अंत तक कूदता है और मुझे वास्तव में क्यों पता नहीं है। मेरे विधि का मूल्यांकन निम्न जैसा दिखाई देता:

    NSString *result = ..; 
    NSRange lineRange = [[textStorage string] lineRangeForRange:[self selectedRange]]; 
    NSString *line = [[textStorage string] substringWithRange:lineRange]; 
    line = [self appendResult:result toLine:line]; // appends the answer 
    
    [textStorage replaceCharactersInRange:lineRange withString:line]; 
    

    ऐसा करने से ठीक मेरी परिणाम में संलग्न कर देगा, लेकिन समस्या, के रूप में उल्लेख किया है, सम्मिलन बिंदु को समाप्त करने के कूदता है।

    मैं कोशिश की है:

    1. उन रैपिंग ऊपर [textStorage beginEditing] और -endEditing में कहता है।
    2. पाठ संग्रहण को बदलने से पहले चयन श्रेणी (यानी, सम्मिलन बिंदु) सहेजना ताकि मैं इसे बाद में रीसेट कर सकूं, लेकिन कोई पासा नहीं।

    क्या मैं यह सही कर रहा हूं? मैं इसे कम से कम हैकिश तरीके से करने की कोशिश कर रहा हूं, और मैं भी अनिश्चित हूं कि यह मेरी पार्सिंग/हाइलाइटिंग करने का आदर्श स्थान है। दस्तावेज़ मुझे विश्वास करने के लिए नेतृत्व करते हैं, लेकिन शायद यह गलत है।

  • +0

    लाइनफॉरेंज क्या है, मुझे दस्तावेज़ों में यह विधि नहीं मिली है? यदि आपका मतलब lineRangeForRange है, तो यह आपकी समस्या हो सकती है। क्या आप लाइन के अंत में, या अपने चयन के अंत में शामिल होने की कोशिश कर रहे हैं? – rdelmar

    +0

    हाँ यह एक टाइपो है। – jbrennan

    +0

    मेरे प्रश्न के दूसरे भाग के बारे में कैसे? यह स्पष्ट नहीं है कि आप अपना टेक्स्ट जोड़ने का प्रयास कर रहे हैं। जब आप कहते हैं कि प्रविष्टि बिंदु रेखा के अंत तक चलता है, तो क्या आपका मतलब आपके सम्मिलन या पहले के बाद होता है? – rdelmar

    उत्तर

    0

    यह आसान है! मैंने इस समस्या को 2 भागों में तोड़ दिया। मैं अभी भी textStorage प्रतिनिधि कॉलबैक के परिणामस्वरूप मेरा वाक्यविन्यास हाइलाइटिंग करता हूं, लेकिन अब मैं अपना मूल्यांकन करता हूं और कहीं और जोड़ता हूं।

    मैंने -insertText: और -deleteBackwards: दोनों को ओवरराइड करना समाप्त कर दिया (मैं भी -deleteForwards: के लिए भी ऐसा करना चाहता हूं)। दोनों ओवरराइड निम्नलिखित की तरह लग रहे:

    - (void)insertText:(id)insertString { 
        [super insertText:insertString]; 
        NSRange selectedRange = [self selectedRange]; 
        [self doEvaluationAndAppendResult]; 
        [self setSelectedRange:selectedRange]; 
    } 
    

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

    +0

    यह पोस्ट-फ़िक्स, सम्मिलन बिंदु को स्थानांतरित करने पर, केवल तभी काम करेगा जब प्रभावित सीमा स्क्रॉलिंग का कारण नहीं था - या उपयोगकर्ता को स्क्रॉल बार फ्लिकर जल्द ही दिखाई देगा और सम्मिलन बिंदु की रेखा टेक्स्ट व्यू के बीच की ओर स्क्रॉल हो जाएगी। ऐसा तब होता है जब 'doEvaluation औरAppendResult' सामान स्क्रॉल हो जाता है ताकि 'setSelectedRange:' दृश्यमान रेक्ट के बाहर एक सीमा पर सेट हो। – ctietze

    4

    मुझे पता है कि यह प्रश्न लंबे समय से उत्तर दिया गया है, हालांकि मेरे पास बिल्कुल एक ही समस्या थी। मेरी NSTextStorage उपवर्ग में मैं कर रहा था निम्नलिखित:

    - (void)processEditing { 
        //Process self.editedRange and apply styles first 
        [super processEditing]; 
    } 
    

    हालांकि, ऐसा करने का सही बात यह है: सम्मिलन बिंदु के लिए

    - (void)processEditing { 
        [super processEditing]; 
        //Process self.editedRange and apply styles after calling superclass method 
    } 
    
    +1

    धन्यवाद, जिसने मेरी समस्या हल की। यदि आप NSTextStorageDelegate का उपयोग करते हैं और आप इस समस्या का अनुभव करते हैं, तो टेक्स्टस्टॉरेजडिडप्रोसेस एडिटिंग का उपयोग करें: टेक्स्टस्टॉरेज WillProcessEditing के बजाय:। टेक्स्टस्टॉरेज को एक असंगत स्थिति में छोड़ने के बारे में प्रलेखन चेतावनियां पढ़ें, हालांकि। –

    +0

    शीर्ष पर है: हालांकि यह काम करता है, आपको सावधान रहना होगा कि प्रक्रिया में 'NSLayoutManager' के साथ बहुत गड़बड़ न करें, क्योंकि माता-पिता की' प्रक्रिया संपादन 'को कॉल करने से गुणों को ठीक किया जाता है और प्रारंभ/समाप्ति संपादन के अंत को चिह्नित किया जाता है, इसलिए आप नियमित संपादन संलग्नक के बाहर हाइलाइट विशेषताओं को सेट कर रहे हैं। – ctietze

    1

    कारण

    ताज्जुब की बात है स्थानांतरित करने के लिए, मैं कभी नहीं मिली इन सुझावों का काम (या नहीं) काम करने के लिए एक वास्तविक स्पष्टीकरण।

    इसे में खुदाई, सम्मिलन बिंदु को स्थानांतरित करने के लिए कारण है: .editedCharacters (NSTextStorageEditedCharacters ObjC में) NSLayoutManager.processEditing(from:editedMask:...) से सम्मिलन बिंदु की स्थिति को प्रभावित करता है।

    यदि केवल .editedAttributes/NSTextStorageEditedAttributes भेजा जाता है, तो सम्मिलन बिंदु स्पर्श नहीं किया जाएगा। जब आप हाइलाइट करते हैं तो आप यही हासिल करना चाहते हैं: केवल गुण बदलें।

    क्यों हाइलाइटिंग सम्मिलन बिंदु को प्रभावित करता है

    यहाँ पर प्रकाश डाला साथ समस्या यह है कि एक भी NSTextStorage प्रसंस्करण चलाने के दौरान सभी edited कॉल एकत्र करता है और, पर्वतमाला को जोड़ती है उपयोगकर्ता के संपादित परिवर्तन के साथ शुरू (है जैसे प्रविष्टि जब टाइपिंग), फिर इस के एक संघ का गठन और addAttributes(_:range:) द्वारा रिपोर्ट की गई सभी श्रेणियां। इसका परिणाम कॉल में एक editedMask दोनों के साथ [.editedCharacters, .editedAttributes] में होता है।

    तो तुम पर प्रकाश डाला श्रेणियों के लिए .editedAttributes भेज लेकिन .editedCharacters बजाय साथ एक संघ बनाने अंत में चाहते । वह संघ सम्मिलन बिंदु waaaaaaayay आगे बढ़ता है जहां इसे जाना चाहिए।

    सुपर पहले कामों को कॉल करने के लिए processEditing में ऑर्डर बदलना क्योंकि लेआउट प्रबंधक को एक पूर्ण संपादन के बारे में अधिसूचित किया जाएगा। लेकिन यह दृष्टिकोण अभी भी कुछ किनारे के मामलों के लिए तोड़ देगा, जिसके परिणामस्वरूप आप बहुत बड़े अनुच्छेदों में टाइप करते समय अमान्य लेआउट या जिगलिंग स्क्रॉल दृश्य देख सकते हैं।

    This is true for hooking into NSTextStorageDelegate, वैसे भी, वैसे भी। कॉलबैक में

    हुक के बाद लेआउट वास्तव में समाप्त हो गया है processEditing

    एकमात्र समाधान है कि मजबूती के साथ कोको ढांचे के लिए निहित कारणों के आधार पर काम करेगा के बजाय प्रकाश डाला लेआउट प्रसंस्करण के बाद विशेष रूप से textDidChange(_:) से प्रकाश डाला प्रदर्शन करने के लिए, यानी है को गति प्रदान करने वास्तव में समाप्त हो गया है। NSTextDidChangeNotification की सदस्यता लेना भी ठीक है।

    डाउनसाइड: आपको अंतर्निहित स्ट्रिंग में प्रोग्रामेटिक परिवर्तनों के लिए हाइलाइटिंग पास ट्रिगर करना होगा क्योंकि ये textDidChange(_:) कॉलबैक का आह्वान नहीं करेंगे।


    मामले में आप समस्या के स्रोत के बारे में अधिक जानना चाहते हैं, मैं और मेरे अनुसंधान, अलग दृष्टिकोण है, और संदर्भ के लिए एक बहुत लंबे समय तक ब्लॉग पोस्ट में समाधान का ब्यौरा डाल दिया। यह पोस्ट अभी भी स्वयं में एक स्वयं निहित समाधान है: http://christiantietze.de/posts/2017/11/syntax-highlight-nstextstorage-insertion-point-change/

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