2009-07-02 21 views
8

मैं एक तालिका कक्ष में एक बटन जोड़ना चाहता हूं। "हटाएँ घटना" कैलेंडर अनुप्रयोग में मुझे प्रेरित ...UITableView सेल में UIButton जैसे "ईवेंट हटाएं"

के रूप में (एक समान मामला संपर्कों में "साझा करें संपर्क" है) अब,

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    //..yadayadayada 
    cell = [tableView dequeueReusableCellWithIdentifier:@"buttonCell"]; 
    if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"buttonCell"] autorelease]; 
    } 
    UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoDark]; 
    [button setBackgroundColor:[UIColor redColor]]; 
    button.titleLabel.text = @"Foo Bar"; 
    [cell.contentView addSubview:button]; 

जो एक बटन पैदा करता है वास्तव में। यह अभी तक नहीं दिखता है कि यह कैसे माना जाता है (यह स्पष्ट है कि मैंने कभी भी आईफ़ोन में बटनों का सामना नहीं किया है), लेकिन क्या यह कम से कम सही दृष्टिकोण है?

+0

क्या बटन की परिणामी कार्रवाई अलग-अलग पंक्ति के आधार पर भिन्न होगी? (उदाहरण के लिए इस पंक्ति में वर्तमान संपर्क को ईमेल करें, आदि ...) –

+0

यदि यह है, तो आप प्रत्येक सेल के बटन को टैग करने के लिए इंडेक्सपैथ पंक्ति कह सकते हैं, और उसके बाद प्रेषक के टैग को निष्पादित करने वाले चयनकर्ता को टैग पढ़ सकते हैं एक स्पर्श पर। – mmc

+0

ठीक है, जैसा कि "ईवेंट हटाएं" के साथ ही अंतिम पंक्ति में UI के नीचे मेरे पास केवल एक बटन होगा। –

उत्तर

1

हां, यह आम तौर पर सही दृष्टिकोण है।

एक टिप:

  • , अपने बटन घटनाओं के लिए कॉलबैक सेट करें कि यह वास्तव में जब क्लिक कुछ नहीं करता है।

    [myButton addTarget:self action:@selector(whatMyButtonShouldDo:) 
        forControlEvents:UIControlEventTouchUpInside]; 
    

संपादित: एक प्रणाली बटन, जो मैं क्या uneccessary लिखा था की एक बहुत कुछ renders का उपयोग कर के लिए समायोजित कोड।

+0

अपने उदाहरण कोड में, बटन को रिलीज़ करने की कोई आवश्यकता नहीं है, क्योंकि [UIButton बटन WithType:] एक ऑटोरेलेज्ड उदाहरण देता है। –

+0

आप बिल्कुल सही हैं, मैंने कॉपी किया है कि कोड * I * से मैंने अपने initWithFrame का उपयोग किया था। समायोजन। – mmc

+0

प्रतिक्रिया के लिए धन्यवाद। रिलीज/autorelease के साथ संकेत नोट किया गया था। क्या फ्रेम के साथ झुकाव करना वाकई आवश्यक है? मैं बस बटन को पूरे टेबल सेल को भरना चाहता हूं (यानी स्थिति और आकार के बारे में चिंता न करें); "ईवेंट हटाएं" यह अच्छी तरह से प्रदर्शित करता है। –

1

हां, आप सही रास्ते पर हैं, यह एक सेल में सबव्यूव जोड़ने का सबसे आसान तरीका है (दूसरा UITableViewCell उपclassing है)।

अधिक जानकारी के लिए Apple guide देखें।

19

आपके पास अब यह तरीका है कि जब भी कोई सेल दिखाया जाता है कि आप एक बटन आवंटित कर रहे हैं, अपना मूल्य निर्धारित कर रहे हैं, और इसे सेल की सामग्री में जोड़ रहे हैं। जब सेल का पुन: उपयोग किया जाता है (dequeueReusableCellWithIdentifier के माध्यम से) आप अन्य नया बटन बनायेंगे, इसे सेल (पुराने के शीर्ष पर) में जोड़कर यह तथ्य होगा कि यह addSubview के माध्यम से चला गया है लेकिन कोई स्पष्ट रिलीज़ नहीं है कि प्रत्येक बटन का रखरखाव गिनती शून्य पर कभी नहीं जाएगी, इसलिए वे सभी चारों ओर चिपके रहेंगे। सेल को ऊपर और नीचे स्क्रॉल करने के कुछ समय बाद सैकड़ों बटन सबव्यूज़ के साथ समाप्त हो जाएगा जो शायद आप नहीं चाहते हैं।

कुछ टिप्स:

  • कभी नहीं एक cellForRowAtIndexPath कॉल के अंदर सामान आवंटित जब तक जब dequeueReusableCellWithIdentifier शून्य लौट रहा है और आप सेल आरंभ कर रहे हैं यह किया है। अन्य सभी बाद के समय आपको कैश किए गए सेल को वापस सौंप दिया जाएगा जिसे आप पहले ही सेट कर चुके हैं, इसलिए आपको केवल लेबल या आइकन बदलना है। आप सेल आवंटन कोड के बाद if सशर्त दाएं अंदर सभी बटन आवंटन सामग्री को स्थानांतरित करना चाहते हैं।

  • बटन को एक स्थिति और इसके लिए एक लक्षित सेट की आवश्यकता है ताकि यह टैप होने पर कुछ करे। यदि प्रत्येक सेल में यह बटन होगा तो एक साफ चाल यह है कि वे सभी एक ही लक्ष्य विधि को इंगित करें, लेकिन बटन के tag को सेल के indexPath.row पर सेट करें (सेल आवंटन ब्लॉक के बाहर से प्रत्येक सेल के लिए भिन्न होता है)। बटन के लिए सामान्य टैप हैंडलर प्रेषक के टैग मान का उपयोग डेटा स्रोत सूची में अंतर्निहित डेटा को देखने के लिए करेगा।

  • करने के बाद बटन पर release पर कॉल करें। इस तरह बनाए रखने की गिनती शून्य हो जाएगी और जब माता-पिता को रिहा किया जाता है तो ऑब्जेक्ट वास्तव में रिलीज़ हो जाएगा।addSubview के माध्यम से बटन जोड़ने की

  • इसके बजाय, आप तो आप इसे स्थिति (जब तक आप पहले से ही कुछ और के लिए accessoryView उपयोग कर रहे हैं के बारे में चिंता करने की ज़रूरत नहीं accessoryView के रूप में यह लौट सकते हैं सेल के लिए - जैसे प्रकटीकरण बटन)।

+1

मूल्यवान संकेतों और स्पष्टीकरण के लिए धन्यवाद। एक आईफोन प्रोग्रामिंग नौसिखिया मुझे यकीन है कि इसकी सराहना करता है। टिप 4 के लिए, "ईवेंट हटाएं"/"संपर्क साझा करें" के साथ, मेरे पास केवल अंतिम पंक्ति में यूआई के नीचे एक बटन होगा। इसलिए, यह accessoryView नहीं हो सकता है, लेकिन इसे पूरी पंक्ति भरनी है। मैं अभी भी इसके साथ संघर्ष कर रहा हूँ। –

+2

# 3 के संबंध में, बटन जारी करने से आपका एप्लिकेशन क्रैश हो जाएगा। वह इसे आवंटित नहीं कर रहा है। – DougW

+0

अच्छा रामिन लिखो! – Jordan

7

मैंने कैलेंडर ऐप में 'ईवेंट हटाएं' बटन के बराबर बनाने के लिए एक अलग दृष्टिकोण लिया। एक सबव्यूव के रूप में एक बटन जोड़ने के बजाय, मैंने कोशिकाओं को दो पृष्ठभूमि दृश्य (लाल और गहरे लाल, अच्छे ग्रेडियेंट के साथ) जोड़ा और फिर कोनों से गोल किया और सीमा को भूरे रंग में सेट किया।

नीचे दिया गया कोड एक पुनः उपयोग करने योग्य सेल (सामान्य फैशन में) बनाता है। ('RedUp.png' और 'redDown.png') को संदर्भित दो छवियों को कैलेंडर के 'ईवेंट हटाएं' बटन के स्क्रीनशॉट से लिया गया था। (यह प्रोग्रामेटिक रूप से ग्रेडियेंट बनाने से तेज़ी से लग रहा था।) कैलेंडर की 'डिलीट इवेंट' उपस्थिति के करीब पहुंचने के लिए थोड़ा और अधिक अच्छा ट्यूनिंग का दायरा है, लेकिन यह बहुत करीब है।

बटन की कार्रवाई तालिका द्वारा ट्रिगर की गई है प्रतिनिधि प्रतिनिधि तालिका तालिका दृश्य: didSelectRowAtIndexPath: विधि।

// create a button from a table row like the Calendar's 'Delete Event' button 
// remember to have an #import <QuartzCore/QuartzCore.h> some above this code 

static NSString *CellWithButtonIdentifier = @"CellWithButton"; 

UITableViewCell *cell = [self dequeueReusableCellWithIdentifier:CellWithButtonIdentifier]; 
if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellWithButtonIdentifier] autorelease]; 
    [[cell textLabel] setTextAlignment: UITextAlignmentCenter]; 

    UIImageView* upImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"redUp.png"]]; 
    UIImageView* downImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"redDown.png"]]; 

    [cell setBackgroundView: upImage]; 
    [cell setSelectedBackgroundView: downImage]; 

    [[upImage layer] setCornerRadius:8.0f]; 
    [[upImage layer] setMasksToBounds:YES]; 
    [[upImage layer] setBorderWidth:1.0f]; 
    [[upImage layer] setBorderColor: [[UIColor grayColor] CGColor]]; 

    [[downImage layer] setCornerRadius:8.0f]; 
    [[downImage layer] setMasksToBounds:YES]; 
    [[downImage layer] setBorderWidth:1.0f]; 
    [[downImage layer] setBorderColor: [[UIColor grayColor] CGColor]]; 

    [[cell textLabel] setTextColor: [UIColor whiteColor]]; 
    [[cell textLabel] setBackgroundColor:[UIColor clearColor]]; 
    [cell setBackgroundColor:[UIColor clearColor]]; // needed for 3.2 (not needed for later iOS versions) 
    [[cell textLabel] setFont:[UIFont boldSystemFontOfSize:20.0]]; 

    [upImage release]; 
    [downImage release]; 
} 
return cell; 
+2

आपको '[cell.textLabel setShadowColor: [UIColor BlackColor]] जोड़ना चाहिए; [cell.text लेबल सेटशैडोऑफसेट: CGSizeMake (0, -1)]; कोड के लिए। यह पाठ को थोड़ा उभरा प्रभाव देता है, इसलिए यह देशी बटन की तरह दिखता है। – Greg

0

स्थिति से बचने के लिए और स्मृति प्रबंधन रुकावटों को आप एक XIB के लिए एक विशेष सेल वर्ग और लिंक बना सकते हैं। यह मेरे लिए सबसे साफ दृष्टिकोण की तरह लगता है। यहां लिंक है: http://icodeblog.com/2009/05/24/custom-uitableviewcell-using-interface-builder/

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