UITextField के कर्सर को छिपाएं


137

मैं इसके लिए एक के UITextFieldसाथ प्रयोग कर रहा हूं , ताकि जब उपयोगकर्ता पाठ क्षेत्र पर टैप करे, तो एक पिकर को उनसे एक विकल्प चुनने के लिए बुलाया जाता है।UIPickerViewinputView

लगभग सब कुछ काम करता है, लेकिन मुझे एक समस्या है: कर्सर अभी भी पाठ क्षेत्र में चमकता है जब यह सक्रिय है, जो बदसूरत और अनुचित है, क्योंकि उपयोगकर्ता को फ़ील्ड में टाइप करने की उम्मीद नहीं है और कीबोर्ड के साथ प्रस्तुत नहीं किया गया है। मैं जानता हूँ कि मैं hackily सेट करके ऐसा समाधान कर सकता editingकरने के लिए NOपाठ क्षेत्र पर और उस पर नज़र रखने छूता है, या एक कस्टम स्टाइल बटन और इसकी जगह है, और कोड के माध्यम से पिकर आहूत द्वारा। हालाँकि, मैं UITextFieldDelegateटेक्स्ट फ़ील्ड पर सभी ईवेंट हैंडलिंग के तरीकों का उपयोग करना चाहता हूं और हैक जैसे टेक्स्ट फ़ील्ड को बटन के साथ बदलना इस दृष्टिकोण की अनुमति नहीं देता है।

मैं UITextFieldइसके बजाय बस कर्सर को कैसे छिपा सकता हूं ?

जवाबों:


277

बस उपवर्ग UITextField और ओवरराइड caretRectForPosition को ओवरराइड करें

- (CGRect)caretRectForPosition:(UITextPosition *)position
{
    return CGRectZero;
}

2
सुंदर! मेरे लिए एक आकर्षण की तरह काम करता है।
जो स्ट्रैट

1
@ जोसेफ चिउ यह बेहतरीन काम करता है। लेकिन आईओएस 4.3 के साथ नहीं। क्या आप इसमें मेरी मदद कर सकते हैं?
दिनेश राजा

सबसे साफ और सबसे छोटा तरीका जो एक दोहरे
उत्थान के

1
सिर्फ एक नोट। मेरे उपवर्ग में मैंने एक बूल को छिपाया था, फिर इस ओवरराइड में अगर यह सच है -> CGRectZero को वापस करें और सुपर का परिणाम लौटाएं।
WCByrne

6
बस इस बात से अवगत रहें कि बाहरी कीबोर्ड वाले उपयोगकर्ता कर्सर के छिपे होने पर भी टेक्स्ट फ़ील्ड का मान बदल सकते हैं और आप पिकर व्यू का उपयोग करते हैं।
मार्क

156

IOS 7 के रूप में आप अब केवल tintColor = [UIColor clearColor]टेक्स्टफिल्ड पर सेट कर सकते हैं और कैरेट गायब हो जाएगा।


1
यह फिलहाल काम करता है, हालांकि मैं इसे इस्तेमाल करने के खिलाफ सलाह दूंगा क्योंकि यह भविष्य में बदल सकता है। बल्कि caretRectForPosition:ओवरराइड समाधान का विकल्प चुनें।
लिपका

@ लिपका सच, यह शायद एक बेहतर तरीका है।
जाम

2
अभी के लिए काफी अच्छा है। कभी-कभी आपको बस एक त्वरित समाधान की आवश्यकता होती है।
स्वर्णज्योति

यह अब तक का सबसे आसान उपाय है!
जे। क्यू।

1
यह उत्तर iOS 7+
tryp

95

आप सिर्फ टेक्स्टफील्ड के टिंटकलर को साफ कर सकते हैं

self.textField.tintColor = [UIColor clearColor];

स्विफ्ट 3.0

self.textField.tintColor = .clear

यहाँ छवि विवरण दर्ज करें


सबसे आसान जवाब।
निक कोव

2
जैसा कि ऊपर उल्लेख किया गया है, टिंट का रंग साफ़ करना उपयोगकर्ताओं को बाहरी कीबोर्ड (iPad प्रो) के साथ पाठ को बदलने से नहीं रोकता है।
माइकल लॉन्ग

@MichaelLong यह उपयोगकर्ता को टेक्स्ट बदलने से रोकने के बारे में नहीं है, यह सिर्फ एक स्टाइलिंग विकल्प है।
JRam13

21

आप उपयोगकर्ता को किसी भी पाठ को चुनने, कॉपी करने या चिपकाने से रोकना चाह सकते हैं ताकि केवल पाठ इनपुट पिकर दृश्य से आए।

- (CGRect) caretRectForPosition:(UITextPosition*) position
{
    return CGRectZero;
}

- (NSArray *)selectionRectsForRange:(UITextRange *)range
{
    return nil;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    if (action == @selector(copy:) || action == @selector(selectAll:) || action == @selector(paste:))
    {
        returnNO;
    }

    return [super canPerformAction:action withSender:sender];
}

http://b2cloud.com.au/tutorial/disabling-the-caret-and-text-entry-in-uitextfields/


15

प्रोटोकॉल की संपत्ति selectedTextRange की जांच करें , जिसमें वर्ग के अनुरूप है। कुछ! यह वस्तु-उन्मुख कार्यक्रम में एक सबक है। UITextInput UITextField

कैरेट छिपाएं

कैरेट को छिपाने के लिए, टेक्स्ट फ़ील्ड की चयनित टेक्स्ट रेंज को शून्य करें।

textField.selectedTextRange = nil; // hides caret

अनहाइड केयर

यहां कैरेट को अनहाइड करने के दो तरीके दिए गए हैं।

  1. दस्तावेज़ के अंत में टेक्स्ट फ़ील्ड की चयनित टेक्स्ट रेंज सेट करें।

    UITextPosition *end = textField.endOfDocument;
    textField.selectedTextRange = [textField textRangeFromPosition:end
                                                        toPosition:end];
  2. कैरट को उसी स्थान पर रखने के लिए, पहले, टेक्स्ट फ़ील्ड की चयनित टेक्स्ट रेंज को इंस्टेंस चर पर संग्रहीत करें।

    _textFieldSelectedTextRange = textField.selectedTextRange;
    textField.selectedTextRange = nil; // hides caret

    फिर, जब आप कैरेट को अनहाइड करना चाहते हैं, तो बस टेक्स्ट फ़ील्ड की चयनित टेक्स्ट रेंज को वापस सेट करें जो मूल रूप से थी:

    textField.selectedTextRange     = _textFieldSelectedTextRange;
    _textFieldLastSelectedTextRange = nil;

3
यह विशेष समाधान मेरे कार्यान्वयन के लिए काम नहीं किया। कर्सर अभी भी झपकाता है।
कला गीगेल

ठीक है, तो, शायद आपको bugreport.apple.com पर एक बग दर्ज करना चाहिए क्योंकि iOS डॉक्स कहते हैं: "यदि पाठ सीमा की लंबाई है, तो यह वर्तमान में चयनित पाठ को इंगित करता है। यदि इसकी लंबाई शून्य है, तो यह कैरेट (सम्मिलन) को इंगित करता है। बिंदु)। यदि टेक्स्ट-रेंज ऑब्जेक्ट शून्य है, तो यह इंगित करता है कि कोई वर्तमान चयन नहीं है। "
ma11hew28

4
मुझे रिपोर्ट दर्ज करने के लिए पर्याप्त परवाह नहीं है। यदि अन्य लोग आपके "समाधान" का उपयोग करते हैं और यह काम नहीं कर रहा है तो मैं चाहता था कि वे यह जानें कि वे अकेले नहीं हैं।
आर्ट गीगेल

@ ArtGeigel की टिप्पणियों के बावजूद, यह मेरे लिए पूरी तरह से काम करता है। हालांकि, मैं ओवरराइडिंग से जुड़े समाधान को पसंद करता हूं caretRectForPosition। यह अधिक स्पष्ट है कि यह क्या कर रहा है, और आपके द्वारा उद्धृत डॉक्स यह स्पष्ट नहीं करते हैं कि कार्यवाहक का व्यवहार तब क्या होना चाहिए जब 'कोई वर्तमान चयन न हो'। यदि @ ArtGeigel का दावा है कि यह काम नहीं कर रहा था, तो सही था (जो कि यह नहीं है, कम से कम जहां तक ​​मैं देख सकता हूं) यह स्पष्ट नहीं होगा कि यह एक बग था।
मार्क अमेरी

मेरे लिए भी काम नहीं किया। कैरेट अभी भी है और निमिष है।
CW0007007

11

ओपी द्वारा प्रदान किया गया उत्तर, अनुत्तरित प्रश्नों की बढ़ती पूंछ को साफ करने में मदद करने के लिए प्रश्न निकाय से कॉपी किया गया।

मुझे एक और समाधान मिला: UIButtonइन विधियों को उपवर्ग और ओवरराइड करें

- (UIView *)inputView {
    return inputView_;
}

- (void)setInputView:(UIView *)anInputView {
    if (inputView_ != anInputView) {
        [inputView_ release];
        inputView_ = [anInputView retain];
    }
}

- (BOOL)canBecomeFirstResponder {
    return YES;
}

अब बटन, के रूप में UIResponder, की तुलना में एक समान व्यवहार है UITextFieldऔर एक कार्यान्वयन बहुत सीधा है।


5
यह वास्तव में एक महान समाधान नहीं है। इस जवाब को नीचे देखें: stackoverflow.com/a/13660503/1103584
DiscDev

2
यह एक महान समाधान क्यों नहीं है? यह इच्छित प्रभाव को प्राप्त करता है और एक वर्ग को कार्यक्षमता प्रदान करता है जो पहले नहीं था। यह भी हैक नहीं है। मुझे लगता है कि यह वास्तव में अच्छा है। तो इसमें गलत क्या है?
ब्रेडिकलएमडी

2
@BreadicalMD सबसे बड़ी समस्या जो मैं देख सकता हूं, वह यह है कि आप इसके UITextFieldDelegateसाथ एडिटिंग इवेंट्स को शुरू करने और समाप्त करने के लिए उपयोग नहीं कर सकते । इसके बजाय - जब तक कि उन घटनाओं को संभालने का कोई तरीका नहीं है जिनके बारे में मुझे नहीं पता है - आपको ओवरराइड becomeFirstResponderऔर resignFirstResponderबटन उपवर्ग में करने की आवश्यकता होगी , और संभवतः अपना स्वयं का प्रतिनिधि प्रोटोकॉल बनाएं, एक delegateसंपत्ति में जोड़ें , और उपरोक्त से प्रतिनिधि को बुलाएं। तरीकों। यह सब उपवर्ग caretRectForPositionमें बस ओवरराइड करने की तुलना में अधिक काम है UITextField
मार्क अमेरी

1
@BreadicalMD ने कहा कि जोसफ चिउ का जवाब किसी भी व्यावहारिक दृष्टिकोण से बेहतर होने के बावजूद, मैं अभी भी आपके साथ सहमत हूं कि यह बहुत सेक्सी है। मैंने पहले कभी UIResponderक्लास रेफरेंस को ध्यान से नहीं देखा था, और मुझे इस बात का अंदाजा नहीं था कि इस तरह की ट्रिक संभव है।
मार्क अमेरी

पार्टी के लिए देर से, लेकिन मुझे लगता है कि यह एक बहुत अच्छा समाधान है और यह UITextFieldकर्सर का उपयोग करने और छुपाने की तुलना में बहुत अधिक उपयुक्त और हैक की तुलना में कम महसूस करता है, जो मूल रूप से एक हैक है क्योंकि हम तब टेक्स्ट फ़ील्ड का उपयोग लेबल के रूप में कर रहे हैं की किसी भी कार्यक्षमता का उपयोग नहीं कर रहा है UITextField
रूपर्ट

7

नेट के पोस्ट का 5 संस्करण स्विफ्ट

  override func caretRect(for position: UITextPosition) -> CGRect {
    return .zero
  }
  
  override func selectionRects(for range: UITextRange) -> [UITextSelectionRect] {
    return []
  }
  
  override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    return false
  }

मेरे मामले में यह काम किया। स्विफ्ट 4 का उपयोग करके इन तरीकों के साथ UITextField का एक उपवर्ग जोड़ा गया। धन्यवाद!
जे। फ़ेडज़

3

रंग साफ करने के लिए tintColor सेट करें

textfield.tintColor = [UIColor clearColor];

और आप इंटरफ़ेस बिल्डर से भी सेट कर सकते हैं


2
आपने अभी 2 साल पहले के उत्तर की प्रतिलिपि बनाई है।
एशले मिल्स

1
माफ करना, मेरे दोस्त, लेकिन मैंने कुछ भी कॉपी नहीं किया।
अहमद अल-अतल

4
यह दिलचस्प है, "मेरा दोस्त"। आपका उत्तर 1 मई 15 से @ बूढ़े के उत्तर के काफी करीब लग रहा है। क्या आप मुझे बता सकते हैं कि आपका स्वभाव कैसा है?
एशले मिल्स

1
जैसा कि ऊपर उल्लेख किया गया है, टिंट का रंग साफ़ करना उपयोगकर्ताओं को बाहरी कीबोर्ड (iPad प्रो) के साथ पाठ को बदलने से नहीं रोकता है।
माइकल लॉन्ग

समर्थक उपयोगकर्ता वह कर सकते हैं जो वे चाहते हैं। वे
अभियोग

2

यदि आप कर्सर को छिपाना चाहते हैं, तो आप आसानी से इसका उपयोग कर सकते हैं! इसने मेरे लिए काम किया ।।

[[textField valueForKey:@"textInputTraits"] setValue:[UIColor clearColor] forKey:@"insertionPointColor"]

3
जहां तक ​​मुझे पता है, यह अनिर्दिष्ट है। यह संभव है कि यदि आप इसे ऐप स्टोर में जमा करते हैं, तो निजी एपीआई को कॉल करने के लिए आपके ऐप को अस्वीकार कर दिया जाएगा, हालांकि मुझे यह अनुमान नहीं है कि इसका उपयोग उस अटकलें का परीक्षण करने के लिए किया गया है। यह अफ़सोस की बात है, क्योंकि इस समस्या को बिना उप-समाधान के हल करने में सक्षम होना अच्छा होगा, और यह जवाब सक्षम बनाता है।
मार्क अमेरी

1

ओपी द्वारा प्रदान किया गया उत्तर, अनुत्तरित प्रश्नों की बढ़ती पूंछ को साफ करने में मदद करने के लिए प्रश्न निकाय से कॉपी किया गया।

मुझे लगता है कि मेरे पास सही समाधान है लेकिन अगर इसमें सुधार किया जा सकता है तो इसका स्वागत किया जाएगा :) खैर, मैंने UITextField का एक उपवर्ग बनाया और उस विधि को अधिरोहित किया जो सीमा के लिए CGRect लौटाती है

-(CGRect)textRectForBounds:(CGRect)bounds {
    return CGRectZero;
}

समस्या? पाठ प्रदर्शित नहीं होता है क्योंकि आयत शून्य है। लेकिन मैंने नियंत्रण के उप-भाग के रूप में एक UILabel जोड़ा और सेटटेक्स्ट विधि को ओवरराइड किया, जैसा कि हम हमेशा की तरह एक पाठ दर्ज करते हैं, पाठ फ़ील्ड पाठ शून्य है और वह लेबल है जो पाठ दिखाता है

- (void)setText:(NSString *)aText {
    [super setText:nil];

    if (aText == nil) {
        textLabel_.text = nil;
    }

    if (![aText isEqualToString:@""]) {
        textLabel_.text = aText;
    }
}

इसके साथ ही यह चीज़ उम्मीद के मुताबिक काम करती है। क्या आप इसे सुधारने का कोई तरीका जानते हैं?


यह उत्तर मूल रूप से अब व्यर्थ है कि जोसेफ चीयू का वैकल्पिक दृष्टिकोण बहुत समान है लेकिन बहुत सरल है। क्या मैं इसे हटाने की सलाह दूंगा?
मार्क अमेरी

1

कर्सर और मेनू दोनों को अक्षम करने के लिए मैं इन 2 विधियों के साथ उपवर्ग का उपयोग करता हूं:

- (CGRect)caretRectForPosition:(UITextPosition *)position {
    return CGRectZero;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    [UIMenuController sharedMenuController].menuVisible = NO;
    self.selectedTextRange = nil;

    return NO;
}

0

मैं बस उपवर्ग UITextField, और ओवरराइड layoutSubviewsइस प्रकार है:

- (void)layoutSubviews
{
    [super layoutSubviews];
    for (UIView *v in self.subviews)
    {
        if ([[[v class] description] rangeOfString:@"UITextSelectionView"].location != NSNotFound)
        {
            v.hidden = YES;
        }
    }
}

यह एक गंदा हैक है, और भविष्य में विफल हो सकता है (जिस बिंदु पर कर्सर फिर से दिखाई देगा - आपका ऐप क्रैश नहीं होगा), लेकिन यह काम करता है।


-1

आप संबंधित वस्तुओं के माध्यम से एक श्रेणी में एक BOOL cursorlessसंपत्ति जोड़ सकते हैं UITextField

@interface UITextField (Cursorless)

@property (nonatomic, assign) BOOL cursorless;

@end

फिर उपयोग करने के लिए विधि स्विज़लिंग का उपयोग करें, caretRectForPosition:एक ऐसी विधि के साथ स्वीज़ करें जो कि उपयोग करने के बीच CGRectZeroऔर उसके डिफ़ॉल्ट मान के साथ टॉगल करता है cursorless

यह ड्रॉप-इन श्रेणी के माध्यम से एक सरल इंटरफ़ेस की ओर जाता है। यह निम्न फ़ाइलों में प्रदर्शित किया जाता है।

सीधे शब्दों में उन्हें ड्रॉप करें और इस सरल इंटरफ़ेस का लाभ प्राप्त करें

UITextFieldश्रेणी: https://github.com/rexmas/RexDK/blob/master/RexDK/UI/UITextField%2BRXCursorless.h https://github.com/rexmas/RexDK/rlob/master/RexDK/UI/UITextField%2BRXCursorless ।म

विधि स्विज़लिंग: https://github.com/rexmas/RexDK/blob/master/RexDK/Foundation/NSObject%2BRXRuntimeAdditions.h https://github.com/rexmas / RexDK/blob/master/RexDK/Foundation/NSObject%ject 2BRXRuntimeAdditions.m


कई स्तरों पर एक बुरा समाधान! शुरुआत के लिए: कभी श्रेणियों में तरीकों को ओवरराइड न करें। जब तक आप वास्तव में विधि स्विज़इलिंग से बचें, वास्तव में इसकी आवश्यकता है (अन्य इस प्रश्न के अच्छे समाधान के साथ आए हैं)। यह आपके कोड को और अधिक जटिल बनाता है।
EsbenB

यदि आप वास्तव में उस कोड को देखते हैं जो आपको पता चलेगा कि कोई भी विधि श्रेणी में ओवरराइड नहीं है और विधि स्विज़लिंग को सही तरीके से लागू किया गया है। मैं बिना किसी असफलता के वर्षों से इस कार्यान्वयन का उपयोग कर रहा हूं।
विस्मय-ओ

यह भी बताएं कि एक निरंतर आवर्ती समस्या को स्थायी रूप से हल करने के लिए ~ 150 लाइनों के एक पृथक कोड आधार को जोड़ने के बारे में क्या जटिल है? न केवल यह आपके कोडबेस को जटिल करेगा, बल्कि यह सबसे सरल संभव इंटरफ़ेस प्रदान करता है; कार्यक्षमता को निर्धारित करने के लिए एक एकल बूलियन।
विस्मय-ओ

विशेष रूप से डीबगिंग पर विधि swizzling stackoverflow.com/questions/5339276/… के बारे में इस उत्कृष्ट चर्चा पर एक नज़र डालें । विधि स्विज़लिंग एक अद्भुत विशेषता है, लेकिन आईएमएचओ का उपयोग केवल तब किया जाना चाहिए जब जरूरत हो। यह समस्या यहां दिए गए सुझावों में से किसी एक का उपयोग करके हल करना आसान है, और अन्य प्रोग्रामर के लिए कोड को बनाए रखने और पढ़ने में आसान प्रदान करेगा।
एसेनबी

मैंने पढ़ा है कि पहले और मैंने शुद्धता के लिए मेरे कार्यान्वयन में सभी उल्लिखित दिशानिर्देशों का पालन किया। तर्क के तौर पर, यह एक ठोस उदाहरण है जब विधि स्वीजिंग जीत जाती है। यह एक अलग, फिर भी, सामान्य मामला है जहां बुनियादी पुस्तकालयों को एक सरल तरीके से प्लेटफार्मों में व्यापक रूप से आवश्यक सुविधा को लागू करने में विफल रहता है। सुझाए गए अन्य उदाहरणों में शब्दार्थ टेक्स्टफील्ड को शब्दार्थ रूप से परिभाषित नहीं किया गया है, वे केवल इसे कर्सर के फ्रेम के स्थिरीकरण या रंग के माध्यम से करते हैं। एक नए प्रोग्रामर के लिए, यह इंटरफ़ेस पढ़ने में सबसे आसान है और यह वही करता है जो इससे अपेक्षित है।
विस्मयकारी- o
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.