IOS 6 UITableView dequeueReusableCellWithIdentifier: forIndexPath का उपयोग करते समय UITableViewCell की शैली सेट करना:


82

मैं यह जानने की कोशिश कर रहा हूं कि UITableViewCellStyleiOS 6 में नए तरीकों का उपयोग करते समय कैसे सेट किया जाए UITableView

इससे पहले, जब UITableViewCellमैं I UITableViewCellStyleबना रहा था initWithStyle:, तो कॉल करते समय विभिन्न प्रकार की डिफ़ॉल्ट सेल बनाने के लिए enum को बदल देगा, लेकिन जो मैं इकट्ठा कर सकता हूं, वह अब ऐसा नहीं है।

UITableViewराज्यों के लिए Apple प्रलेखन :

रिटर्न वैल्यू : संबंधित पुनः उपयोग पहचानकर्ता के साथ एक UITableViewCell ऑब्जेक्ट। यह विधि हमेशा एक मान्य सेल लौटाती है।

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

महत्वपूर्ण : आपको registerNib का उपयोग करके एक वर्ग या नीब फ़ाइल पंजीकृत करनी चाहिए: forCellReuseIdentifier: या registerClass: forCellReuseIdentifier: इस विधि को कॉल करने से पहले विधि।

यदि आपने निर्दिष्ट पहचानकर्ता के लिए एक वर्ग पंजीकृत किया है और एक नया सेल बनाया जाना चाहिए, तो यह विधि सेल को उसके initWithStyle: reuseIdentifier: पद्धति से कॉल करके आरंभ करती है। निब आधारित कोशिकाओं के लिए, यह विधि प्रदान की गई निब फ़ाइल से सेल ऑब्जेक्ट को लोड करती है। यदि कोई मौजूदा सेल पुन: उपयोग के लिए उपलब्ध था, तो यह विधि इसके बजाय सेल की तैयारफोररियस विधि को कॉल करती है।

cellForRowAtIndexPathनए तरीकों को लागू करने के बाद यह मेरा नया रूप है:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"cell_identifier";

    [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellIdentifier];

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    return cell;
}

मेरे पास अब तक का कोड ठीक काम करता है लेकिन हमेशा डिफ़ॉल्ट शैली देता है। मैं इसे कैसे बदल सकता हूं ताकि मैं अन्य शैलियों जैसे , और UITableViewCellStyleDefault, के साथ सेल बना सकूं ?UITableViewCellStyleValue1UITableViewCellStyleValue2UITableViewCellStyleSubtitle

मैं उप-वर्ग नहीं करना चाहता UITableViewCell, मैं सिर्फ डिफ़ॉल्ट प्रकार को बदलना चाहता हूं जैसा कि मैं iOS 6 से पहले कर सकता था। यह अजीब लगता है कि ऐप्पल अपने कार्यान्वयन का समर्थन करने के लिए बढ़ाया तरीके प्रदान करेगा लेकिन न्यूनतम प्रलेखन के साथ।

क्या किसी को इसमें महारत हासिल है, या इसी तरह की समस्या में भागना है? मैं किसी भी उचित जानकारी को पाने के लिए संघर्ष कर रहा हूँ।

जवाबों:


106

मुझे पता है कि आपने कहा था कि आप एक उपवर्ग नहीं बनाना चाहते हैं, लेकिन यह अपरिहार्य लगता है। IOS 6.0 सिम्युलेटर में परीक्षण करते समय असेंबली कोड के आधार पर, प्रदर्शन करके (या उसके उपवर्ग) के UITableViewनए उदाहरण बनाता हैUITableViewCell

[[<RegisteredClass> alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:<ReuseIdentifier>]

दूसरे शब्दों में, भेजी गई शैली UITableViewCellStyleDefaultहार्ड-कोडित प्रतीत होती है। इसके आस-पास जाने के लिए, आपको एक उपवर्ग बनाने की आवश्यकता होगी जो डिफ़ॉल्ट इनिशियलाइज़र को ओवरराइड करता है initWithStyle:reuseIdentifier:और उस शैली को पास करता है जिसे आप उपयोग करना चाहते हैं:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    // ignore the style argument, use our own to override
    self = [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier];
    if (self) {
        // If you need any further customization
    }
    return self;
}

इसके अलावा, यह भेजने के लिए बेहतर हो सकता है registerClass:forCellReuseIdentifier:में viewDidLoadबजाय यह हर बार एक सेल अनुरोध किया जाता है ऐसा करने का,:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.tableView registerClass:<RegisteredClass> forCellReuseIdentifier:<ReuseIdentifier>];
}

4
मैं यह मानने लगा था कि वास्तव में यही होगा। यह एक बड़ी समस्या नहीं है, लेकिन UITableViewCellअन्य डिफ़ॉल्ट शैलियों को प्राप्त करने के लिए उपवर्ग होना एक दर्द है क्योंकि यह सिर्फ अनावश्यक फ़ाइलों को बनाता है। आपकी टिप्पणी के लिए धन्यवाद और मेरे संदेह की पुष्टि।
CaptainRedmuff

11
मत भूलो कि उपवर्ग के बजाय, आप पुराने iOS5 विधि का उपयोग कर सकते हैं, जो अभी भी मान्य है। इस तरह आप किसी भी प्रकार की सेल शैली को आरंभ कर सकते हैं जिसे आप स्वयं चाहते हैं। अन्य उत्तर देखें।
स्पैसरीकोचेट

60

dequeueReusableCellWithIdentifierपदावनत नहीं किया जाता है, इसलिए आपको नए का उपयोग करने की आवश्यकता नहीं है dequeueReusableCellWithIdentifier:forIndexPath:

यदि आप एक कस्टम सेल क्लास का उपयोग कर रहे हैं, तो उपयुक्त रजिस्टर विधि (viewDidLoad) के साथ नए तरीके का उपयोग करें, लेकिन यदि आप UITableViewCellStyle एनम का उपयोग करना चाहते हैं तो पुराने तरीके का उपयोग करें।


1
इंगित करने के लिए कि आपको फैंसी नए तरीकों का उपयोग करने की आवश्यकता नहीं है । केवल तभी जब वे आपके उद्देश्य के अनुरूप हों या यदि विकल्प हटाए गए हों।
SpacyRicochet

यदि आप विशेष रूप से उत्सुक हैं, तो dequeueReusableCellWithIdentifier:forIndexPath:कुछ पहचानकर्ताओं को पुराने तरीके से कोशिकाओं को बनाने (और उन्हें वापस करने) के लिए प्रदान करना ओवरराइड करना ठीक है । अन्य पहचानकर्ता सुपर को कॉल करेंगे और वापस लौटेंगे। इस तरह NSDictionaryके पहचानकर्ता के लिए कंस्ट्रक्टर ब्लॉक के लिए पहचानकर्ताओं का होना समझ में आता है ।
बेन्जोन

11

आप स्टोरीबोर्ड इंटरफ़ेस बिल्डर का उपयोग करके एक बाहरी उपवर्ग से बच सकते हैं:

  1. स्टोरीबोर्ड दृश्य में, तालिका दृश्य सेल प्रोटोटाइप सेल (तालिका दृश्य पर) का चयन करें
  2. उपयोगिताएँ दृश्य में, गुण निरीक्षक में, शैली मान को संशोधित करें
  3. (वैकल्पिक रूप से) चयन और सहायक जैसे अन्य मूल्यों को संशोधित करें

नया iOS 6.0 dequeueReusableCellWithIdentifier:forIndexPath:उन मानों का उपयोग करता है जब नई कोशिकाओं को आवंटित करते हैं और उन्हें वापस करते हैं। (Xcode 4.5.2 का उपयोग करके iOS 6.0 संकलन पर परीक्षण किया गया)


7

एक अन्य विकल्प जो एक फ़ाइल को बचाता है वह है निब बनाना और registerNib:forCellReuseIdentifier:इसके बजाय उपयोग करना।

निब बनाना आसान है: इंटरफ़ेस बिल्डर में एक नई .xib फ़ाइल बनाएँ। डिफ़ॉल्ट दृश्य हटाएं। एक टेबल व्यू सेल ऑब्जेक्ट जोड़ें। गुण निरीक्षक का उपयोग करना, सेल के लिए शैली बदलना। (यहां आपके पास अन्य विशेषताओं को समायोजित करके सेल को आगे अनुकूलित करने का अवसर भी है।)

फिर अपने टेबल व्यू कंट्रोलर की viewDidLoadविधि में कुछ इस तरह से कॉल करें:

[self.tableView registerNib:[UINib nibWithNibName:@"StyleSubtitleTableCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"Cell"];

initWithStyle: reuseIdentifier को नहीं कहा जाता है।
थियरीब

0

बोल्ट का जवाब सही है। सरल और आपको कोई भी XIB फ़ाइल बनाने की आवश्यकता नहीं है।

मैं सिर्फ उद्देश्य-सी के बजाय स्विफ्ट का उपयोग करते हुए जो भी कर रहा हूं, उसके जवाब को अपडेट करना चाहता था:

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: .value1, reuseIdentifier: reuseIdentifier)
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

-5

मेरे initWithStyle: reuseIdentifier:द्वारा इसका उपयोग करने के बाद मुझे इसका समाधान करना है [self.tableView dequeueReusableCellWithIdentifier:@"cellId" forIndexPath:indexPath]। सब के बाद, initबस एक और चयनकर्ता है, और संकलक इसे पहले से ही प्रारंभिक ऑब्जेक्ट पर कॉल करने पर कोई प्रतिबंध नहीं लगाता है। हालांकि यह कॉल इनिट के परिणाम का उपयोग नहीं करने के बारे में शिकायत करेगा, इसलिए मैं करता हूं:

UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"cellId" forIndexPath:indexPath];
cell = [cell initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cellId"];

मुझे लगता है कि यह स्विफ्ट में काम नहीं करेगा ...


सबसे सुरुचिपूर्ण समाधान imo। उम्मीद है कि initWithStyle की हिम्मत फिर से सब कुछ नहीं बनाती है।
स्कॉट बिर्कस्टेड

2
ठीक है, मुझे लगता है कि अगर आप इसे इस तरह कर रहे हैं, तो आप पूरी तरह से घटते हुए सामान को गिरा सकते हैं ...
stk

1
पुन: उपयोग कर रहे सेल एक महत्वपूर्ण UITableView के लिए महत्वपूर्ण है। आपका समाधान कोशिकाओं का पुन: उपयोग नहीं करने का सुझाव देता है।
बेरिक जूल

2
जब आप initWithStyle: reuseIdentifierदूसरी बार कॉल करते हैं, तो आप वास्तव में एक नए बनाए गए ऑब्जेक्ट के साथ सेल को ओवरराइट कर रहे हैं। हां, मेमोरी का आवंटन पहले से ही किया गया था, और नई सेल उसी मेमोरी लोकेशन को अधिलेखित करने जा रही है, लेकिन जब आप इसे फिर से शुरू करते हैं तो आप वास्तव में एक पूरी तरह से नई ऑब्जेक्ट बना रहे होते हैं। यह उन सभी अनुकूलन को नकार देता है जो पहली जगह में पुन: उपयोग करने वाली कोशिकाओं के पूरे बिंदु हैं।
एंथनीएमडीईवी

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