2012-02-20 3 views
9

मेरे पास एक कस्टम UITableViewCell है कि मैं instantiateWithOwner:(id)owner options:(NSDictionary *)options का उपयोग कर निब से तत्काल हूं। जब निब को तुरंत चालू किया जाता है, तो मैं इसे अपने व्यू कंट्रोलर में परिभाषित आईबीओटलेट में सहेज रहा हूं, जिसे .xib फ़ाइल में फ़ाइल के स्वामी के रूप में सेट किया गया है। सब कुछ अच्छा काम कर रहा है।इंटरफ़ेस बिल्डर में फ़ाइल के मालिक के लिए आईडी <protocol> का उपयोग करना?

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

id <CustomCellOwner> 

:

तो आदर्श रूप में, मैं करने के लिए "फ़ाइल के मालिक" सेट करना चाहते हैं।

हालांकि, इंटरफ़ेस बिल्डर केवल आपको फ़ाइल के मालिक को एक ज्ञात वर्ग में सेट करने की अनुमति देता है, न कि प्रोटोकॉल को लागू करने वाली आईडी के लिए?

क्या ऐसा करने का कोई तरीका है? या, इस समस्या से संपर्क करने का एक आसान तरीका?

धन्यवाद!

+0

पूर्ण sidenote, क्या आप मुझे किसी प्रकार की मार्गदर्शिका या नमूना के बारे में बता सकते हैं कि आप यह कैसे कर रहे हैं क्योंकि यह बहुत अच्छा लगता है, वर्तमान में मुझे अपने कस्टम सेल में उपयोग करने के लिए उचित दृश्य खोजने के लिए एक निब के माध्यम से लूप करना है। यह आदर्श नहीं है। और ऐसा लगता है कि आपके पास एक अच्छा समाधान है। –

+0

क्या आप विस्तारित कर सकते हैं "ऐसा लगता है कि यह आपको फ़ाइल के मालिक को एक ज्ञात वर्ग में सेट करने की इजाजत देता है, न कि प्रोटोकॉल को लागू करने वाली आईडी के लिए?" क्या इसका मतलब अंतरफलक निर्माता है? – rooftop

+0

@rooftop हां, "यह" उस मामले में इंटरफ़ेस बिल्डर को संदर्भित करता है। फ़ाइल के मालिक ऑब्जेक्ट को संपादित/कॉन्फ़िगर करते समय, एक "क्लास" विकल्प होता है जो आपको फ़ाइल के स्वामी के वर्ग का चयन करने की अनुमति देता है। आईबी में वह बॉक्स मुझे आईडी <कुछ प्रोटोकॉल> प्रकार के रूप में दर्ज करने की अनुमति नहीं दे रहा है, और मैं सोच रहा हूं कि यह संभव है या नहीं। धन्यवाद! – thauburger

उत्तर

3

यह वह समाधान नहीं है जिसे आप पूछ रहे हैं, लेकिन आप UIViewController उप-वर्ग बना सकते हैं जिसे आप प्रत्येक दृश्य नियंत्रक के लिए उप-वर्ग बनाते हैं जिसे आपके निब का उपयोग करने की आवश्यकता होती है। की तरह कुछ:

@interface CustomCellOwnerViewController : UIViewController 
@property (nonatomic, strong) IBOutlet UIButton *someButton; 
-(IBAction)doSomething; 
@end 

और फिर उपयोग करें कि प्रत्येक के लिए आधार वर्ग के रूप में:

@interface FirstView : CustomCellOwnerViewController 

तो फिर तुम बस File's OwnerCustomCellOwnerViewController को कोई समस्या नहीं के साथ सेट कर सकते हैं।

बस एक विचार।

1

मैं आज इस में भाग गया और मुझे कोई अच्छा समाधान नहीं मिला। हालांकि मैंने इसे हैक किया ताकि ऐसा ठीक लगे। यह निश्चित रूप से एक हैक की तरह लगता है।

सबसे पहले मैं इस तरह एक "fakeOwner" श्रेणी का निर्माण:

@interface fakeOwner : NSObject 
@property (nonatomic, assign) IBOutlet MyBaseCell* itemTableCell; 
@end 

@implementation fakeOwner 
@synthesize itemTableCell; 
@end 

मैं तो fakeOwner रूप XIB में वस्तु के मालिक सेट और आउटलेट जुड़ा हुआ है। फिर प्रत्येक नियंत्रक इन कोशिकाओं का उपयोग करना चाहता है कि मैं एक ही संपत्ति जोड़ सकते हैं और इस तरह वर्ग बनाने के लिए:

[[NSBundle mainBundle] loadNibNamed:@"MyBaseCell" owner:self options:nil]; 
    MyBaseCell* itemCell = self.itemTableCell; 
    self.itemTableCell = nil; 

के बाद से fakeOwner और मेरे नियंत्रक एक ही IBOutlet है, मालिक कारणों के रूप में नियंत्रक के साथ सेल लोड हो रहा है कनेक्शन होने के बावजूद यह भी नहीं है कि एक्सआईबी में स्पष्ट रूप से सेट किया गया है।

अगर स्मृति प्रबंधन वर्तमान में सही है तो मुझे 100% नहीं है (मुझे लगता है कि यह ठीक है), लेकिन इसके अलावा यह बहुत अच्छा काम करता है। हालांकि मुझे ऐसा करने का बेहतर तरीका देखना अच्छा लगेगा।

+0

दिलचस्प काम-आसपास। इनपुट के लिए धन्यवाद! – thauburger

1

नकली मालिक बनाना काम करेगा; हालांकि, ऐसा समाधान नाजुक और अतुलनीय हो सकता है। एक मायने में, सेल स्वयं का मालिक है, लेकिन यह भी तकनीकी रूप से गलत है। सच्चाई यह है कि UITableViewCell के मालिक नहीं हैं।

कस्टम तालिका दृश्य कक्षों को लागू करने का उचित तरीका पहले UITableViewCell का एक कस्टम उप-वर्ग बनाना है।इस कक्षा में आप सभी आईबीओटलेट्स और सेल के लिए परिभाषित करेंगे। यहाँ एक हेडर फाइल का एक नमूना है:

+ (id)cellForTableView:(UITableView *)tableView reuseIdentifier:(NSString *)reuseID fromNib:(UINib *)nib { 

    if (!reuseID) 
     reuseID = [self cellIdentifier]; 

    id cell = [tableView dequeueReusableCellWithIdentifier:reuseID]; 

    if (!cell) { 

     NSArray * nibObjects = [nib instantiateWithOwner:nil options:nil]; 

     // Sanity check. 
     NSAssert2(([nibObjects count] > 0) && 
        [[nibObjects objectAtIndex:0] isKindOfClass:[self class]], 
        @"Nib '%@' does not appear to contain a valid %@", 
        [self nibName], NSStringFromClass([self class])); 

     cell = [nibObjects objectAtIndex:0]; 
    } 

    return cell; 
} 

इस विधि निर्माण कोड के सभी समाहित:

@interface RBPersonCell : UITableViewCell 

@property (nonatomic, strong) IBOutlet UILabel * nameLabel; 
@property (nonatomic, strong) IBOutlet UILabel * ageLabel; 

- (void)setupWithPerson:(Person *)person; 

@end 

वहाँ से, मुझे लगता है कि निब से सेल बनाता है एक सुविधा की विधि, यदि आवश्यक हो तो है इसलिए मुझे इसे कभी नहीं देखना है या इसे फिर से लिखना है। यह मानता है कि कस्टम सेल निब में पहला रूट दृश्य है। यह एक काफी सुरक्षित धारणा है क्योंकि आपके पास केवल रूट सेल के रूप में कस्टम सेल होना चाहिए।

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

कस्टम तालिका दृश्य कक्षों के बारे में मैंने जो कुछ सीखा है, वह iOS Recipes व्यंजनों 15-16 से आता है। से सीधे free extract है। आप अधिक जानकारी के लिए उस पुस्तक को देख सकते हैं।

संपादित करें:

मैं अंत में मेरी RBSmartTableViewCell वर्ग सोर्सिंग को खोलने के लिए चारों ओर हो गया। आप इसे मेरे GitHub पर पा सकते हैं। आपको आईओएस व्यंजनों से सीधे कोड की तुलना में इस वर्ग को अधिक उपयोगी पाया जाना चाहिए, क्योंकि मेरी कक्षा सभी कोशिकाओं को समान रूप से मानती है, भले ही वे XIBs, UIStoryboard, या कोड का उपयोग करके बनाए गए हों। इस रेपो में काम करने वाले नमूने भी शामिल हैं।

1

आईओएस 5.0 में अब registerNib:forCellReuseIdentifier: विधि UITableView पर है जो मुझे विश्वास है कि एक ही समस्या को हल करने का प्रयास करता है।

प्रलेखन से:

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

यह आपकी आवश्यकताओं के आधार पर एक वैकल्पिक दृष्टिकोण हो सकता है।

1

एक और विकल्प हल्का वजन 'फैक्ट्री' ऑब्जेक्ट बनाना है जो आपके लिए कोशिकाओं के निर्माण को संभालता है। rootObject आउटलेट उचित रूप से सेट के साथ इंटरफ़ेस बिल्डर में यह ऑब्जेक्ट FilesOwner होगा।

@interface NibLoader : NSObject 

@property (nonatomic, strong) UINib  * nib; 
@property (nonatomic, strong) IBOutlet id rootObject; 

- (id)initWithNibName:(NSString *)name bundle:(NSBundle *)bundleOrNil; 
- (id)instantiateRootObject; 

@end 


@implementation NibLoader 

@synthesize nib, rootObject; 

- (id)initWithNibName:(NSString *)name bundle:(NSBundle *)bundleOrNil { 
    self = [super init]; 
    if (self) { 
     self.nib = [UINib nibWithNibName:name bundle:bundleOrNil]; 
    } 
    return self; 
} 

- (id)instantiateRootObject { 
    self.rootObject = nil; 
    [self.nib instantiateWithOwner:self options:nil]; 
    NSAssert(self.rootObject != nil, @"NibLoader: Nib did not set rootObject."); 
    return self.rootObject; 
} 

@end 
दृश्य नियंत्रकों में

तब:

NibLoader *customCellLoader = [[NibLoader alloc] initWithNibName:@"CustomCell" bundle:nil]; 
self.customCell = customCellLoader.instantiateRootObject; 

मैं स्पष्ट रूप से जड़ वस्तु की स्थापना पसंद करते हैं बजाय सरणी के माध्यम से instantiateWithOwner:options: से लौटे क्योंकि मैं इस सरणी में वस्तुओं की स्थिति पता खोज में बदल गया है भूतकाल।

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