सभी सबव्यू निकालें?


316

जब मेरा ऐप अपने रूट व्यू कंट्रोलर में वापस आ जाता है, तो viewDidAppear:विधि में मुझे सभी साक्षात्कारों को हटाने की आवश्यकता होती है।

मैं यह कैसे कर सकता हूँ?

जवाबों:


569

संपादित करें: करने के लिए धन्यवाद के साथ cocoafan : यह स्थिति ऊपर तथ्य यह है कि द्वारा अव्यवस्थित है NSViewऔर UIViewसंभाल कुछ अलग। केवल NSView(डेस्कटॉप मैक विकास के लिए), आप बस निम्नलिखित का उपयोग कर सकते हैं:

[someNSView setSubviews:[NSArray array]];

के लिए UIView(केवल iOS विकास), आप सुरक्षित रूप से उपयोग कर सकते हैं makeObjectsPerformSelector:क्योंकि subviewsसंपत्ति एक वापस आ जाएगी प्रति subviews के सरणी के:

[[someUIView subviews]
 makeObjectsPerformSelector:@selector(removeFromSuperview)];

यह इंगित करने के लिए कि यह संशोधित किया जा रहा है, जबकि सरणी को संशोधित करने के लिए प्रकट होता है, जो इंगित करने के लिए टॉमी के लिए धन्यवाद (जो इसके लिए नहीं, लेकिन )।makeObjectsPerformSelector:subviewsNSViewUIView

अधिक विवरण के लिए कृपया इस SO प्रश्न को देखें।

नोट: इन दोनों विधियों में से किसी एक का उपयोग करने से आपके मुख्य दृश्य में मौजूद हर दृश्य को हटा दिया जाएगा और उन्हें जारी कर दिया जाएगा , अगर वे कहीं और बनाए नहीं रखे जाते हैं। RemoveFromSuperview पर Apple के प्रलेखन से :

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


9
क्या आप सुनिश्चित हैं कि यह सुरक्षित है? यह पुनरावृति करते हुए सूची को बदल देता है, और मैं Apple के प्रलेखन में एक निश्चित विवरण नहीं पा रहा हूँ।
टॉमी

8
@ टॉमी: यह एक अच्छी बात है। कुछ Googling ने उत्तर दिया: परिवर्तनशील सरणी की UIViewएक प्रति लौटाता है subviews, इसलिए यह कोड बस काम करता है। डेस्कटॉप पर पूरी तरह से अलग कहानी, जहां एक ही कोड अपवाद फेंक देगा। देख stackoverflow.com/questions/4665179/...
e.James

3
UIView सेटब्यूस का जवाब नहीं देता :, क्या यह है?
कोकोफान

4
ज़मारिन रास्ता: someUIView.Subviews.All (p => p.emoveFromSuperview);
बेनोइट जादिनोन

3
@BenoitJadinon - संकलन नहीं होगा - आप सभी को ForEach प्रदर्शन करने के लिए गाली देते हुए प्रतीत होते हैं, इसलिए someUIView.Subviews.All( v => { v.RemoveFromSuperview(); return true; } );। IMHO क्लीनर कहने के लिए कि आपका क्या मतलब है someUIView.Subviews.ToList().ForEach( v => v.RemoveFromSuperview() );:।
टूलमेकरसैट

173

अपने रूट कंट्रोलर से सभी सबव्यू प्राप्त करें और प्रत्येक को एक निष्कासन भेजें:

NSArray *viewsToRemove = [self.view subviews];
for (UIView *v in viewsToRemove) {
    [v removeFromSuperview];
}

+1 और धन्यवाद। मुझे भी self.viewआपके जैसा होना चाहिए था।
ई। जनम

2
क्यों नहीं!? for (UIView *v in [self.view subviews])इसका आसान
फ्रॉड

4
@ यह बहुत स्पष्ट है और जिस तरह से उसने इसे किया है, उससे अधिक क्रिया।
क्रिया

33
@taylorcressy आपने कहा होगा कि "पठनीयता को बचाने के बजाय कीस्ट्रोक्स को बचाने की तुलना में पठनीयता अधिक महत्वपूर्ण है" और फिर आपकी टिप्पणी अधिक पठनीय होगी। :-)
अर्लोमेडिया

1
आइए इस तथ्य के बारे में न भूलें कि अगर [self.view सबवेज़] हुड के तहत कोई गणना करता है, तो इसे सीधे लूप में डालने से उन गणनाओं को बार-बार निष्पादित किया जा सकता है। लूप से पहले यह घोषित करना कि वे केवल एक बार प्रदर्शन कर रहे हैं।
ब्रायन सचेटा

116

में स्विफ्ट आप एक का उपयोग कर सकते कार्यात्मक दृष्टिकोण इस तरह:

view.subviews.forEach { $0.removeFromSuperview() }

तुलना के रूप में, अनिवार्य दृष्टिकोण इस तरह होगा:

for subview in view.subviews {
    subview.removeFromSuperview()
}

ये कोड स्निपेट केवल iOS / tvOS में काम करते हैं, हालांकि, चीजें macOS पर थोड़ी भिन्न होती हैं।


4
(subviews as [UIView]).map { $0.removeFromSuperview() }
डेफ्रैनजेड

8
यह कार्यात्मक नहीं है क्योंकि एक फ़ंक्शन एक मान लौटाता है और यह सिर्फ परिणाम का वर्णन करता है .map। यह एक शुद्ध साइड इफेक्ट है और इस तरह से बेहतर तरीके से नियंत्रित किया जाता है:view.subviews.forEach() { $0.removeFromSuperview() }
मार्टिन एलेस्टेन

1
आप सही हैं, मार्टिन, मैं आपसे सहमत हूं। मुझे अभी पता नहीं था कि Arrays पर एक forEach () विधि थी। इसे कब जोड़ा गया था या क्या मैंने इसकी देखरेख की थी? मैंने अपना उत्तर अपडेट कर दिया है!
18

1
मैं इतना आलसी हूं कि भले ही मुझे पता था कि साक्षात्कार कैसे पास करना है, फिर भी मैं यहां आपके स्निपेट को कॉपी / पेस्ट करने के लिए आया था और
विल्मीर

13

यदि आप अपने UIView (यहाँ yourView) पर सभी उपखंडों को हटाना चाहते हैं , तो इस कोड को अपने बटन पर क्लिक करें:

[[yourView subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];

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

5
यह स्वीकृत उत्तर की तुलना में अधिक मदद कैसे कर सकता है: यह समान है। यह क्यों लिखें?
रामबेटिनो

8

यह केवल OSX पर लागू होता है क्योंकि iOS में सरणी की एक प्रति रखी जाती है

सभी साक्षात्कारों को हटाते समय, सरणी के अंत में डिलीट करना शुरू करना एक अच्छा विचार है और शुरुआत तक पहुंचने तक हटाते रहें। इसे कोड की दो पंक्तियों के साथ पूरा किया जा सकता है:

for (int i=mySuperView.subviews.count-1; i>=0; i--)
        [[mySuperView.subviews objectAtIndex:i] removeFromSuperview];

स्विफ्ट 1.2

for var i=mySuperView.subviews.count-1; i>=0; i-- {
    mySuperView.subviews[i].removeFromSuperview();
}

या (कम कुशल, लेकिन अधिक पठनीय)

for subview in mySuperView.subviews.reverse() {
    subview.removeFromSuperview()
}

ध्यान दें

आपको सामान्य क्रम में साक्षात्कार नहीं हटाने चाहिए , क्योंकि इससे दुर्घटना हो सकती है यदि UIView उदाहरण से पहले हटा दिया जाएremoveFromSuperview संदेश के सभी ऑब्जेक्ट्स को भेजे जाने । (जाहिर है, अंतिम तत्व को हटाने से दुर्घटना नहीं होगी)

इसलिए, कोड

[[someUIView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];

नहीं चाहिएउपयोग किया ।

MakeObjectsPerformSelector के बारे में Apple प्रलेखन से उद्धरण :

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

(जो इस उद्देश्य के लिए गलत दिशा होगी)


क्या आप इस बात का उदाहरण बना सकते हैं कि आप किस विषय का उल्लेख कर रहे हैं? पता नहीं क्या आप "तत्व" के रूप में संदर्भित कर रहे हैं और कैसे हटाने के पहले इस तत्व को हटा दिया जाएगा।
रेवरेंड

लेकिन इस विधि को कॉल करते समय UIView का एक उदाहरण कैसे हटाया जा सकता है? क्या आपका मतलब सबव्यू ऐरे से हटा दिया गया है?
रेवरेंड

जब removeFromSuperviewखत्म हो जाता है, तो UIView को सरणी से हटा दिया जाएगा, और अगर UIView के साथ एक मजबूत संबंध के साथ कोई अन्य जीवित उदाहरण नहीं हैं, तो UIView को भी हटा दिया जाएगा। यह बाध्य अपवाद के कारण हो सकता है।
डैनियल

1
पकड़ लिया! धन्यवाद। मुझे लगता है कि आपको IOS पर साक्षात्कार सारणी की एक प्रति मिल रही है। किसी भी मामले में, यदि आप साक्षात्कार हटाना चाहते हैं, तो अपने आप को एक प्रतिलिपि बनाना अच्छा होगा।
रेवरेंड

@simplebus - क्या आपने स्वीकृत उत्तर पर 2011 में लिखी टिप्पणियों को पढ़ा है? उन टिप्पणियों के अनुसार, iOS पर, [yourView subviews]सरणी का एक COPY लौटाता है, इसलिए सुरक्षित है। (ध्यान दें कि OSX पर, आप जो कहते हैं वह सही है।)
टूलमेकरसैट

4

इस तरह से ट्राई करें 2.0

view.subviews.forEach { $0.removeFromSuperview() }

2
क्या आपको तारीख उत्तर देने की तारीख नहीं दिख रही है जो मैं पहले कर रहा हूँ? मेरे उत्तर की लिंक को उस उत्तर में क्यों नहीं पेस्ट करें?
विलियम हू

1
ठीक है ... जवाब आपके सामने पोस्ट किया गया था लेकिन forEachआपके बाद आधारित समाधान जोड़ा गया था, मुझे याद आया। क्षमा याचना।
क्रिश्चियन

4

सभी साक्षात्कारों को हटाने के लिए निम्नलिखित कोड का उपयोग करें।

for (UIView *view in [self.view subviews]) 
{
 [view removeFromSuperview];
}

2

स्विफ्ट UIViewएक्सटेंशन का उपयोग करना :

extension UIView {
    func removeAllSubviews() {
        for subview in subviews {
            subview.removeFromSuperview()
        }
    }
}

2

वस्तुनिष्ठ-सी में, आगे बढ़ें और उविवि वर्ग से एक श्रेणी विधि बनाएं।

- (void)removeAllSubviews
{
    for (UIView *subview in self.subviews)
        [subview removeFromSuperview];
}

2
view.subviews.forEach { $0.removeFromSuperview() }

2
हालांकि यह कोड प्रश्न का उत्तर दे सकता है, लेकिन यह समस्या का हल कैसे और / या इसके बारे में अतिरिक्त संदर्भ प्रदान करता है, इससे उत्तर के दीर्घकालिक मूल्य में सुधार होगा।
निक 3500

1

सभी सबटैक्स को हटाने के लिए सिंटैक्स:

- (void)makeObjectsPerformSelector:(SEL)aSelector;

उपयोग:

[self.View.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

यह विधि NSArray.h फ़ाइल में मौजूद है और NSArray (NSExtendedArray) इंटरफ़ेस का उपयोग करती है


1

यदि आप स्विफ्ट का उपयोग कर रहे हैं, तो यह उतना ही सरल है:

subviews.map { $0.removeFromSuperview }

यह makeObjectsPerformSelectorदृष्टिकोण के दर्शन के समान है , हालांकि थोड़ी अधिक प्रकार की सुरक्षा के साथ।


यह शब्दार्थिक रूप से गलत है, mapइसके दुष्प्रभाव नहीं होने चाहिए। इसके अलावा, एक ही परिणाम के माध्यम से प्राप्त किया जा सकता है forEach
क्रिश्चियन

0

Ios6 के लिए ऑटोलेयूट का उपयोग करके मुझे बाधाओं को हटाने के लिए थोड़ा सा कोड भी जोड़ना पड़ा।

NSMutableArray * constraints_to_remove = [ @[] mutableCopy] ;
for( NSLayoutConstraint * constraint in tagview.constraints) {
    if( [tagview.subviews containsObject:constraint.firstItem] ||
       [tagview.subviews containsObject:constraint.secondItem] ) {
        [constraints_to_remove addObject:constraint];
    }
}
[tagview removeConstraints:constraints_to_remove];

[ [tagview subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];

मुझे यकीन है कि ऐसा करने के लिए एक नीटर तरीका है, लेकिन यह मेरे लिए काम करता है। मेरे मामले में मैं एक प्रत्यक्ष का उपयोग नहीं कर सका [tagview removeConstraints:tagview.constraints]क्योंकि XCode में बाधाएं थीं जो साफ हो रही थीं।



-10

पर्यवेक्षण से सभी साक्षात्कारों को हटाने के लिए:

NSArray *oSubView = [self subviews];
for(int iCount = 0; iCount < [oSubView count]; iCount++)
{
    id object = [oSubView objectAtIndex:iCount];
    [object removeFromSuperview];
    iCount--;
}

@Pravin यहाँ प्रमुख गलतियों की जोड़ी। सबसे पहले, आपको UIView * के रूप में परिभाषित करने के लिए 'ऑब्जेक्ट' की आवश्यकता होगी अन्यथा आपको [ऑब्जेक्ट removeFromSuperview] के साथ एक कंपाइलर त्रुटि मिलेगी। दूसरा, लूप के लिए आपका आईकाउंट पहले से ही घट रहा है, इसलिए आप अपने आईकाउंट - लाइन के साथ एक अतिरिक्त को छोड़ रहे हैं। और अंत में, ऊपर दो कामकाजी और सही दृष्टिकोण हैं और आपका न तो अधिक सुरुचिपूर्ण है और न ही अधिक तेज़ है।
amergin

5
प्रत्येक पुनरावृत्ति आप करते हैं iCount++और iCount--, सूचकांक को एक ही छोड़ रहे हैं, इसलिए यह एक अनंत लूप होगा यदि [oSubView count]>0। यह निश्चित रूप से छोटी गाड़ी है और उपयोग करने योग्य कोड नहीं है
डेनियल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.