iOS 7 - टेबल व्यू में जगह में तारीख लेने वाला कैसे प्रदर्शित किया जाए?


121

WWDC 2013 के वीडियो में, Apple ने iOS 7 में टेबल व्यू में जगह लेने वाले को प्रदर्शित करने का सुझाव दिया है। टेबल सेल सेल्स के बीच व्यू कैसे डालें और कैसे एनिमेट करें?

इस तरह, Apple कैलेंडर ऐप से:

इन-प्लेस डेट पिकर


यह कौन सा WWDC वीडियो है? मैं यह समझने की कोशिश कर रहा हूं कि यह iOS7- विशिष्ट क्यों है, और यदि कोई कारण है कि यह पहले के संस्करणों पर क्यों नहीं किया जा सकता है।
क्लाफौ

4
यह मिला, यह "iOS यूजर इंटरफेस डिजाइन में नया क्या है" (धन्यवाद ASCIIwwdc)। तर्क यह है कि पुरानी स्टाइल सही इनलाइन नहीं दिखती थी, लेकिन नया फ्लैट लुक देता है।
क्लाफौ

जवाबों:


102

IOS7 के साथ, Apple ने नमूना कोड जारी किया DateCell

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

उन मानों को संपादित करने के लिए तालिका कोशिकाओं में दिनांक ऑब्जेक्ट्स का प्रारूपित प्रदर्शन और UIDatePicker का उपयोग प्रदर्शित करता है। इस तालिका में एक प्रतिनिधि के रूप में, नमूना UIDatePicker नियंत्रण को खोलने के लिए "didSelectRowAtIndexPath" विधि का उपयोग करता है।

IOS 6.x और इससे पहले के लिए, UIViewAnimation का उपयोग UIDatePicker को ऑन-स्क्रीन और डाउन-स्क्रीन पर स्लाइड करने के लिए किया जाता है। IOS 7.x के लिए, UIDatePicker को टेबल व्यू में इन-लाइन जोड़ा जाता है।

UIDatePicker की कार्रवाई विधि सीधे कस्टम तालिका सेल की NSDate संपत्ति सेट करेगी। इसके अलावा, यह नमूना दिखाता है कि कस्टम सेल की दिनांक-स्वरूपित उपस्थिति को प्राप्त करने के लिए NSDateFormatter वर्ग का उपयोग कैसे करें।

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

आप यहाँ नमूना कोड डाउनलोड कर सकते हैं: DateCell


Apple के कोड में समस्याएं हैं। यदि आप अपना स्टेटिक टेबल व्यू रखना चाहते हैं तो मेरा जवाब नीचे देखें
आरोन ब्रेचर

1
@AaronBratcher मैं सिर्फ अपने उत्तर में डेटसेल का परिचय देता हूं और आपको कभी उम्मीद नहीं होती कि आपको सटीक कोड मिलेगा जो आप चाहते हैं। आपको अपनी आवश्यकता के अनुसार संशोधित और परिवर्तित करना होगा। आपका समाधान भी अच्छा है, लेकिन याद रखें कि आपको कभी भी सटीक नहीं मिलता कि आपको दूसरे कोड से क्या चाहिए।
नितिन गोहेल

3
सबसे भयानक नमूना कोड। कोड पूर्ण से एक विधि बनाने के लिए वे कुछ सलाह के साथ कर सकते थे
अनिरुद्ध अगाशे

2
वाह Apple कोड है .... ठीक है, कहने का मतलब है कि तालिका दृश्य प्रभाव पर ध्यान केंद्रित है। मुझे आशा है कि कोई भी इस नमूना परियोजना में उनके कोड से प्रेरित नहीं होगा: s
डैनियल

84

आप मेरे द्वारा पहले दिए गए उत्तर का उपयोग कर सकते हैं या स्विफ्ट में इस नई कक्षा का उपयोग कर सकते हैं मैंने इस कार्य को बहुत सरल और साफ करने के लिए बनाया है : https://github.com/AaronBratcher/TableViewHelper


मुझे लगता है कि Apple द्वारा प्रदान किए गए कोड को कुछ तरीकों से समस्याग्रस्त होना चाहिए:

  • आपके पास एक स्थिर तालिका दृश्य नहीं हो सकता क्योंकि वे तालिका दृश्य का उपयोग कर रहे हैं: cellForRowAtIndexPath विधि
  • यदि आपके पास अंतिम दिनांक पिकर सेल के नीचे अतिरिक्त पंक्तियाँ नहीं हैं, तो कोड क्रैश हो जाता है

स्टैटिक सेल टेबल्स के लिए, मैं अपनी डेट पिकर सेल को अपनी डेट डिस्प्ले सेल के नीचे परिभाषित करता हूं और अगर मैं इसे संपादित कर रहा हूं तो एक ध्वज की पहचान है। यदि मैं कर रहा हूँ, तो मैं एक सेल ऊंचाई उपयुक्त है, अन्यथा मैं शून्य की एक सेल ऊंचाई वापस कर देता हूँ।

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0 && indexPath.row == 2) { // this is my picker cell
        if (editingStartTime) {
            return 219;
        } else {
            return 0;
        }
    } else {
        return self.tableView.rowHeight;
    }
}

जब दिनांक दिखाने वाली पंक्ति को क्लिक किया जाता है, तो मैं ध्वज को बदलता हूं और पिकर दिखाने के लिए अपडेट एनीमेशन करता हूं।

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0 && indexPath.row == 1) { // this is my date cell above the picker cell
        editingStartTime = !editingStartTime;
        [UIView animateWithDuration:.4 animations:^{
            [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:2 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
            [self.tableView reloadData];
        }];
    }
}

यदि मेरे पास एक ही तालिका में कई दिनांक / समय पिकर हैं, तो मैं क्लिक के अनुसार झंडे सेट करता हूं और उपयुक्त पंक्तियों को फिर से लोड करता हूं। मैंने पाया है कि मैं अपनी स्थिर तालिका रख सकता हूं, बहुत कम कोड का उपयोग कर सकता हूं, और यह समझना आसान है कि क्या हो रहा है।


यह मेरे लिए काम करता है, सिवाय इसके कि UITableView में एक बग प्रतीत होता है। पंक्ति की ऊंचाई मेरे तरीके से सही ढंग से लौटाई जा रही थी, लेकिन यह वास्तव में उस विपरीत ऊंचाई को टॉगल करता था जो मैं चाहता था। अगर मैंने दो बार पंक्तियों को पुनः लोड किया तो यह काम कर गया। (मैंने tableView reloadData का उपयोग नहीं किया क्योंकि मैं पूरी चीज़ को फिर से लोड नहीं करना चाहता था)। इसके अलावा एनीमेशन ब्लॉक आवश्यक नहीं था, यह अपने आप ही ठीक हो गया है।
क्रिस गैरेट

क्या किसी ने टेक्स्ट पिकर बनाने के लिए नमूने का उपयोग किया है? यदि हां, तो कैसे? धन्यवाद
TheGeezer

1
आपको एक पंक्ति प्रकट करने का मतलब है ताकि उपयोगकर्ता तिथि चुनने के बजाय पाठ दर्ज कर सके? यदि हां, तो कोड समान है। बस प्रकट पंक्ति की सामग्री अलग है।
हारून ब्रेकर

22
हमें iOS7.1 के साथ एक बग है जो सेल की सीमा से बाहर की वस्तुओं को दिखाता है - जैसे कि ऊँचाई 0 और अंदर पिकर। समाधान सेल के लिए एक आउटलेट प्राप्त करना और सेल सेट करना है ।clipsToBounds = YES;
एमिल्डो

1
@ डनकेन - ऊपर-ऊपर की गई टिप्पणी में एक समाधान का वर्णन किया गया है: stackoverflow.com/questions/18973573/… हालांकि पंक्ति की ऊंचाई शून्य है, सामग्री डिफ़ॉल्ट रूप से क्लिप नहीं की गई है, इसलिए आप उन्हें नीचे देख सकते हैं। निम्नलिखित पंक्ति।
क्रिस नोलेट

18

स्टोरीबोर्ड और एक स्थिर तालिका का उपयोग करके मैं निम्नलिखित कोड का उपयोग करके समान परिणाम प्राप्त करने में सक्षम था। यह एक महान समाधान है क्योंकि यदि आपके पास कई अजीब तरह की कोशिकाएं हैं या ऐसे कई सेल हैं जो गतिशील रूप से दिखाए गए हैं / छिपे हुए हैं तो यह कोड अभी भी काम करेगा।

@interface StaticTableViewController: UITableViewController

@property (weak, nonatomic) IBOutlet UITableViewCell *dateTitleCell; // cell that will open the date picker. This is linked from the story board
@property (nonatomic, assign, getter = isDateOpen) BOOL dateOpen;

@end


@implementation StaticTableViewController

-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{

    // This is the index path of the date picker cell in the static table
    if (indexPath.section == 1 && indexPath.row == 1 && !self.isDateOpen){
        return 0;
    }
    return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}

-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
    [tableView beginUpdates];
    if (cell == self.dateTitleCell){
        self.dateOpen = !self.isDateOpen;
    }
    [tableView reloadData];
    [self.tableView endUpdates];
}

क्या यहाँ कुछ और याद आ रहा है? कोशिकाओं की ऊंचाई बदल रही है :)
DevC

2
आईओएस 7.1 के बाद से आपको अटेंडेस इंस्पेक्टर में "क्लिप टू सबवूक्स" भी चुनना होगा - जो कि मुझे याद आ रहा था :)
DevC

इसके अलावा, लाइन "self.dateOpen =! Self.isDateOpen;" शुरू में "self.isDateOpen =" पढ़ना चाहिए, न कि "self.dateOpen ="
पीटर जॉनसन

2
[tableView reloadData];कॉल की आवश्यकता नहीं है। वर्तमान में यह पंक्ति चयन को निष्क्रिय कर देता है, लेकिन पंक्ति को इस तरह से अलग करना बेहतर है:[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
बैरी हैनस्ट्रा

मेरे पास अजीब एनीमेशन प्रभाव थे जैसे डेट सेल "खुलने" के बाद खाली हो जाएगा लेकिन शुरुआत और एंडूपडेट्स के उपयोग से यह हल हो गया। अब अच्छा और चिकना। धन्यवाद आभारी!
nh32rg

5

मैंने Apple से DateCell स्रोत लिया है, और स्टोरीबोर्ड फ़ाइल को हटा दिया है।

यदि आप स्टोरीबोर्ड के बिना एक चाहते हैं, तो एक नज़र डालें: https://github.com/ajaygautam/DateCellWithoutStoryboard


धन्यवाद @ अजय, मैंने आपके संशोधित कोड का उपयोग किया और उसके UIDatePickerसाथ प्रतिस्थापित करना चाहता हूं UIPickerView। मैंने कुछ चीजों की कोशिश की और pickerViewप्रत्येक सेल पर दिखाने में सक्षम है लेकिन यह प्रत्येक सेल के साथ अपडेट नहीं होता है। मैंने अपना प्रश्न और कोड यहाँ पोस्ट किया है । कृपया एक नज़र डालें और यह बहुत अच्छा होगा यदि आप मुझे कोई समाधान सुझा सकते हैं।
मुघेस मुसद्दिक

मैंने आपका प्रश्न देखा ... इसकी बहुत अधिक जानकारी है, और यह वास्तव में ज्यादा व्याख्या नहीं करता है। शायद आप अपना कोड अपलोड कर सकते हैं / मेरे लिए कहीं और देख लें। मैं इसे डीबग कर सकता हूं - अगर मैं कोड चला सकता हूं ...
अजय गौतम

धन्यवाद, मैं किसी तरह UIDatePickerसे UIPickerViewलेकिन कीड़े के जोड़े के साथ बदलने में कामयाब रहा । 1. जब आप UIPickerViewटेबल को खोलते और स्क्रॉल करते हैं तो यह क्रैश हो जाता है । 2. यह स्वचालित रूप UILabelसे तालिका की निचली पंक्तियों में मूल्यों का विवरण देता है जब मूल्यों को शीर्ष पंक्तियों पर विवरण लेबल को सौंपा जा रहा है। यहाँ मेरा कोड है
मुगदीस मुसद्दिक

क्या आप टेस्टप्रोजेक्ट, किसी भी भाग्य को खोजने में सक्षम हैं ??
मुगदीस मुदादिक

क्षमा करें, मैं थोड़ा व्यस्त हो गया। अभी भी इस के साथ मदद की ज़रूरत है?
अजय गौतम

5

इसके बारे में सबसे अच्छे ट्यूटोरियल में से एक iOS 7 इन-लाइन UIDatePicker - भाग 2 है । मूल रूप से यहां मैं स्थिर तालिका दृश्य कोशिकाओं का उपयोग करता हूं और कुछ अतिरिक्त विधियों को लागू करता हूं। मैंने इसके लिए Xamarin और C # का उपयोग किया:

आपको सक्रिय होना पड़ेगा Clip Subviews

ऊँचाई सेट करना:

public override float GetHeightForRow (UITableView tableView, NSIndexPath indexPath)
{
    if (indexPath.Row == 4) {
        return (datePickerIsShowing) ? 206f : 0.0f;
    }

    return base.GetHeightForRow(tableView,indexPath);
}

एक वर्ग चर की तुलना में: private bool datePickerIsShowing = false;

दिनांक पिकर दिखाएँ:

private void showDatePickerCell(){
    datePickerIsShowing = true;
    this.TableView.BeginUpdates ();
    this.TableView.EndUpdates ();
    this.datePicker.Hidden = false;
    this.datePicker.Alpha = 0.0f;

    UIView.Animate (0.25, animation:
        () => {
            this.datePicker.Alpha = 1.0f;
        }
    );
} 

तिथि पिकर छिपाएँ:

private void hideDatePickerCell(){
    datePickerIsShowing = false;
    this.TableView.BeginUpdates ();
    this.TableView.EndUpdates ();

    UIView.Animate (0.25,
        animation: () => {
            this.datePicker.Alpha = 0.0f;
        },
        completion: () => {
            this.datePicker.Hidden = true;
        }
    );
} 

और इस कार्य को कॉल करना:

public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
    if (indexPath.Row == 3) {
        if (datePickerIsShowing) {
            hideDatePickerCell ();
        } else {
            showDatePickerCell ();
        }
    }

    this.TableView.DeselectRow (indexPath, true);
}

2
यदि आप डाउनवोट करते हैं, तो शायद आप समझा सकते हैं कि आप डाउनवोट क्यों हैं। साइटों के लिंक पोस्ट करने के बजाय मैंने कुछ कोड भी शामिल किए। मेरे मामले में यह C # है। पता नहीं इसमें क्या गड़बड़ है।
परीक्षण

3

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

आप इसे एक उदाहरण परियोजना के साथ यहां पा सकते हैं जो यह दर्शाता है कि इसका उपयोग कैसे किया जाता है: https://github.com/ale84/ALEInlineDatePickerViewController


3

मुझे ऐप्पल की तारीख के उदाहरण में एक दोष का जवाब मिला, जहां आपके पास अंतिम तिथि के नीचे एक पंक्ति होनी चाहिए या आपको एक त्रुटि मिल सकती है। CellForRowAtIndexPath विधि में आइटम के साथ आइटम को बदलें

NSArray *itemsArray = [self.dataArray objectAtIndex:indexPath.section];
NSDictionary *itemData = nil;

if(![indexPath isEqual:self.datePickerIndexPath])
    itemData = [itemsArray objectAtIndex:modelRow];

नमूना कोड की जगह लेने के बाद मैं अब एक डेटपिकर सेल प्रदर्शित कर सकता हूं, उसके नीचे कोई सेल नहीं है।

मैं सिर्फ स्टैक्वेरफ्लो में शामिल हुआ, अगर यह गलत जगह पर है या कहीं और है तो मैं माफी मांगता हूं।


3

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

मैंने संपादित किया :SelectRowAtIndexPath:

// Return Data to delegate: either way is fine, although passing back the object may be more efficient
// [_delegate imageSelected:currentRecord.image withTitle:currentRecord.title withCreator:currentRecord.creator];
// [_delegate animalSelected:currentRecord];
if (indexPath.section == 1 && indexPath.row == 0) { // this is my date cell above the picker cell
    editingStartTime = !editingStartTime;
    [UIView animateWithDuration:.4 animations:^{
        int height = 0;
        if (editingStartTime) {
            height = 162;
        }
        UITableViewCell* temp = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:1]];
        [temp setFrame:CGRectMake(temp.frame.origin.x, temp.frame.origin.y, temp.frame.size.width, height)];
        for (int x = 2; x < [tableView numberOfSections]; x++) {
            for (int y = 0; y < [tableView numberOfRowsInSection:x]; y++) {
                UITableViewCell* temp = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:y inSection:x]];
                int y_coord = temp.frame.origin.y-162;
                if (editingStartTime) {
                    y_coord = temp.frame.origin.y+162;
                }
                [temp setFrame:CGRectMake(temp.frame.origin.x, y_coord, temp.frame.size.width, temp.frame.size.height)];
            }
        }
    }completion:^(BOOL finished){
        [self.tableView reloadData];
    }];
}

धन्यवाद @ तिमाह, मुझे अनुभाग एनीमेशन कटा हुआ भी मिला। मैंने अपने पहले स्विफ्ट ऐप में आपके समाधान का सफलतापूर्वक उपयोग किया है! मैंने पाया कि cellForRowAtIndexPath शून्य देता है जहाँ कोशिकाएँ ऑफ-स्क्रीन होती हैं। इससे बचने के लिए मैंने अपने सभी कोशिकाओं से युक्त एक IB आउटलेट-संग्रह जोड़ा, जो पिकर सेल के बाद आया, और आपके नए y_coord के माध्यम से उनके माध्यम से पुनरावृत्त हुआ। यह अनम्य लगता है, हालांकि जब मुझे नई कोशिकाओं को जोड़ना होता है तो मुझे संग्रह को अद्यतन रखना पड़ता है।
जोश

आप सही हे। वास्तव में, मैंने इस मुद्दे को ठीक कर दिया था, लेकिन स्टैक ओवरफ्लो मुझे उस कोड को संपादित नहीं करने देगा जो मैंने वहां रखा था।
टिमोथी लोगान

3

पिछले उत्तरों में जोड़ना,

मैंने @datinc और @Aaron Bratcher दोनों तरह के समाधानों को आज़माया, दोनों ने बहुत अच्छा काम किया लेकिन एनीमेशन एक समूहबद्ध स्थिर तालिका दृश्य में इतना साफ नहीं था।

इसके साथ खेलने के बाद मैं थोड़ा इस कोड के लिए गया जो मेरे लिए साफ और महान काम करता है -

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0 && indexPath.row == 1)
    {
        if (self.isPickerOpened)
        {
            return 162;
        }
        else
        {
            return 0;
        }
    }
    else
    {
        return [super tableView:tableView heightForRowAtIndexPath:indexPath];
    }
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0 && indexPath.row == 0) {
        [tableView beginUpdates];
        self.isPickerOpened = ! self.isPickerOpened;
        [super tableView:tableView heightForRowAtIndexPath:indexPath];
        [self.tableView endUpdates];
    }
}

मुख्य परिवर्तन का उपयोग करना है -

        [super tableView:tableView heightForRowAtIndexPath:indexPath];

पंक्ति को अद्यतन करने के लिए, इस तरह से तालिका अनुभागों और कोशिकाओं के बाकी हिस्से एनिमेट नहीं कर रहे हैं।

आशा है कि यह किसी की मदद करता है।

शनि


इससे काफी मदद मिली; धन्यवाद! विशेष रूप से [सुपर टेबल व्यू] पहलू, आरोन ब्रेचर के पोस्ट के साथ बंडल किया गया, मुझे मुझे iOS 9.2 पर आवश्यक परिणाम मिले। फिर से धन्यवाद!
टेरेंस शॉ

2

पिछले उत्तर और @Aaron Bratcher समाधान में जोड़ना ...

IOS 9 के बाद से मुझे तड़का हुआ एनिमेशन मिल रहा था, और टेबल को लोड होने में थोड़ा समय लग रहा था, और परेशान होने के लिए पर्याप्त था। मैंने स्टोरीबोर्ड से लोड होने की तिथि लेने वालों को धीमा कर दिया। स्टोरीबोर्ड में प्रोग्रामर के बजाय पिकर जोड़ने से लोडिंग प्रदर्शन में सुधार हुआ, और उप-उत्पाद के रूप में, एनीमेशन चिकनी है।

स्टोरीबोर्ड से डेट पिकर निकालें और एक खाली सेल लें, जिसे आपने पिछले उत्तरों की तरह ऊँचाई पर सेट किया है, और फिर viewDidLoad पर एक इनिशियल कॉल करें:

- (void)initialiseDatePickers
{
    self.isEditingStartTime = NO;
    self.startTimePickerCell.clipsToBounds = YES;

    UIDatePicker *startTimePicker = [[UIDatePicker alloc] init];
    [startTimePicker addTarget:self action:@selector(startTimePickerChanged:) forControlEvents:UIControlEventValueChanged];
    [self.startTimePickerCell addSubview:startTimePicker];
}

फिर क्रिया को लागू करें उदा

- (IBAction)startTimePickerChanged:(id)sender
{
    NSLog(@"start time picker changed");
}

यह तालिका को पहले की तुलना में बहुत तेज लोड करता है। आप एनीमेशन लाइन को भी हटा देते हैं didSelectRowAtIndexPathक्योंकि यह इसके बिना सुचारू रूप से एनिमेट करता है (ymmv)।

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0 && indexPath.row == 1) { // this is my date cell above the picker cell
        editingStartTime = !editingStartTime;
    }
}

1

IOS 8.1 में एनीमेशन के बिना इस जवाब का उपयोग करना सही ढंग से काम करता है। मैंने इसे नीचे स्विफ्ट में बदल दिया है:

import UIKit

class TableViewController: UITableViewController {

    var editingCell: Bool = false

    @IBOutlet weak var myCell: UITableViewCell!

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

        // Change the section and row to the title cell the user taps to reveal 
        // the cell below
        if (indexPath.section == 0 && indexPath.row == 2 && !editingCell) {
            return 0
        } else {
            return self.tableView.rowHeight
        }
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        self.tableView.deselectRowAtIndexPath(indexPath, animated: false);

        var cell = tableView.cellForRowAtIndexPath(indexPath)

        self.tableView.beginUpdates()
        if (cell == self.myCell) {
            editingType = !editingType;
        }
        self.tableView.endUpdates()
    }
}

1

स्थैतिक स्थिर संख्याओं के बिना समस्या को हल करने का एक और तरीका यहां दिया गया है। सभी कोशिकाओं का उपयोग स्थिर और गतिशील तालिका विचारों में किया जा सकता है। यह विधि दोनों शीर्षक और तारीख पिकर के लिए एकल सेल का उपयोग करती है!

Btw आप अपनी इच्छा के रूप में अपनी मेज में कई तारीख पिकर हो सकता है!

UITableViewCell उपवर्ग बनाएं :

आपकी सभी तालिका दृश्य कोशिकाएं इस वर्ग से विरासत में मिली हैं और आपको प्रत्येक पंक्ति के लिए सेल की ऊंचाई मैन्युअल रूप से सेट करनी होगी।

//
//  CPTableViewCell.h
//
//  Copyright (c) CodePigeon. All rights reserved.
//

@class CPTableViewCell;

#define kUIAnimationDuration 0.33f

@protocol CPTableViewCellDelegate <NSObject>

@required
- (void)tableViewCellDidChangeValue:(CPTableViewCell *)cell;
@optional
- (void)tableViewCellDidBecomeFirstResponder:(CPTableViewCell *)cell;
- (void)tableViewCellResignedFirstResponder:(CPTableViewCell *)cell;
@end

@interface CPTableViewCell : UITableViewCell

@property (nonatomic, weak) IBOutlet UITableView *tableView;
@property (nonatomic, weak) IBOutlet CPTableViewCell *nextCell;
@property (nonatomic, weak) IBOutlet id<CPTableViewCellDelegate> delegate;

@property (nonatomic, copy) IBInspectable NSString *dataBindKey;
@property (nonatomic) IBInspectable CGFloat height;

@property (nonatomic, readonly) BOOL isFirstResponder;
@property (nonatomic) BOOL isEnabled;

- (void)commonInit;

- (id)value;
- (void)setValue:(id)value;

@end

//
//  CPTableViewCell.m
//
//  Copyright (c) CodePigeon. All rights reserved.
//

#import "CPTableViewCell.h"

@interface CPTableViewCell ()
@end

@implementation CPTableViewCell

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (!self)
        return nil;

    [self commonInit];

    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];

    if (!self)
        return nil;

    [self commonInit];

    return self;
}

- (void)commonInit
{
    _isFirstResponder = NO;
    _isEnabled = YES;
}

- (BOOL)canBecomeFirstResponder
{
    return _isEnabled;
}

- (BOOL)becomeFirstResponder
{
    if ([_delegate respondsToSelector:@selector(tableViewCellDidBecomeFirstResponder:)])
        [_delegate tableViewCellDidBecomeFirstResponder:self];

    return _isFirstResponder = YES;
}

- (BOOL)resignFirstResponder
{
    if (_isFirstResponder)
    {
        if ([_delegate respondsToSelector:@selector(tableViewCellResignedFirstResponder:)])
            [_delegate tableViewCellResignedFirstResponder:self];

        _isFirstResponder = NO;
    }

    return _isFirstResponder;
}

- (id)value
{
    [self doesNotRecognizeSelector:_cmd];

    return nil;
}

- (void)setValue:(id)value
{
    [self doesNotRecognizeSelector:_cmd];
}

@end

हमारे CPTableViewCell से CPDatePickerTableViewCell क्लास बनाएं

//
//  CPDatePickerTableViewCell.h
//
//  Copyright (c) CodePigeon. All rights reserved.
//

#import "CPTableViewCell.h"

@interface CPDatePickerTableViewCell : CPTableViewCell

@property (nonatomic, copy) IBInspectable NSString *dateFormat;

@property (nonatomic, weak) IBOutlet UILabel *titleLabel;
@property (nonatomic, weak) IBOutlet UILabel *dateLabel;

@property (nonatomic, weak) IBOutlet UIDatePicker *datePicker;

@end

//
//  CPDatePickerTableViewCell.m
//
//  Copyright (c) CodePigeon. All rights reserved.
//

#import "CPDatePickerTableViewCell.h"

#define kCPDatePickerTableViewCellPickerHeight 162.f

@interface CPDatePickerTableViewCell () <UITextFieldDelegate, UIPickerViewDelegate>
{
    NSDateFormatter *_dateFormatter;
    BOOL _isOpen;
}
@end

@implementation CPDatePickerTableViewCell

- (void)awakeFromNib
{
    [super awakeFromNib];

    _dateFormatter = [NSDateFormatter new];
    [_dateFormatter setDateFormat:_dateFormat];

    self.selectionStyle = UITableViewCellSelectionStyleNone;

    _dateLabel.text = [_dateFormatter stringFromDate:_datePicker.date];
    _datePicker.alpha = 0.f;
    _isOpen = NO;
}

- (BOOL)becomeFirstResponder
{
    if (_isOpen == NO)
    {
        self.height += kCPDatePickerTableViewCellPickerHeight;
    }
    else
    {
        self.height -= kCPDatePickerTableViewCellPickerHeight;
    }

    [UIView animateWithDuration:kUIAnimationDuration animations:^{
        _datePicker.alpha = _isOpen ? 0.0f : 1.0f;
    }];

    [self.tableView beginUpdates];
    [self.tableView endUpdates];

    _isOpen = !_isOpen;

    [self.tableView endEditing:YES];

    return [super becomeFirstResponder];
}

- (BOOL)resignFirstResponder
{
    if (_isOpen == YES)
    {
        self.height -= kCPDatePickerTableViewCellPickerHeight;

        [UIView animateWithDuration:kUIAnimationDuration animations:^{
            _datePicker.alpha = 0.0f;
        }];

        [self.tableView beginUpdates];
        [self.tableView endUpdates];

        _isOpen = NO;
    }

    return [super resignFirstResponder];
}

- (id)value
{
    return _datePicker.date;
}

- (void)setValue:(NSDate *)value
{
    _datePicker.date = value;
    _dateLabel.text = [_dateFormatter stringFromDate:_datePicker.date];
}

- (IBAction)datePickerValueChanged:(UIDatePicker *)sender
{
    [_dateLabel setText:[_dateFormatter stringFromDate:_datePicker.date]];

    [self.delegate tableViewCellDidChangeValue:self];
}

@end

आपके विचार में नियंत्रक इन दो प्रतिनिधि विधियों को लागू करते हैं

#pragma mark - UITableViewDelegate methods

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CPTableViewCell *cell = (CPTableViewCell *)[super tableView:tableView cellForRowAtIndexPath:indexPath];

    return [cell height];
}

- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    CPTableViewCell *cell = (CPTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];

    if ([cell canBecomeFirstResponder])
    {
        [cell becomeFirstResponder];
    }

    if (cell != _selectedCell)
    {
        [_selectedCell resignFirstResponder];
    }

    _selectedCell = cell;

    return YES;
}

इंटरफ़ेस बिल्डर में बाधाओं को कैसे सेट करें, उदाहरण

इंटरफ़ेस बिल्डर

इसके अतिरिक्त मैंने UITextField और UITextView के लिए कस्टम सेल कक्षाएं लिखी हैं जहाँ tableView: didSelectRowAtIndexPath: सेल चुने जाने पर कहा जाता है!

CPTextFieldTableViewCell

//
//  CPTextFieldTableViewCell.h
//
//  Copyright (c) CodePigeon. All rights reserved.
//

#import "CPTableViewCell.h"

@interface CPTextFieldTableViewCell : CPTableViewCell

@property (nonatomic, weak) IBOutlet UITextField *inputTextField;

@end

//
//  CPTextFieldTableViewCell.m
//
//  Copyright (c) CodePigeon. All rights reserved.
//

#import "CPTextFieldTableViewCell.h"

@interface CPTextFieldTableViewCell () <UITextFieldDelegate>
@end

@implementation CPTextFieldTableViewCell

- (void)awakeFromNib
{
    [super awakeFromNib];

    self.selectionStyle = UITableViewCellSelectionStyleNone;

    _inputTextField.userInteractionEnabled = NO;
    _inputTextField.delegate = self;
}

- (BOOL)becomeFirstResponder
{
    _inputTextField.userInteractionEnabled = YES;

    [_inputTextField becomeFirstResponder];

    return [super becomeFirstResponder];
}

- (BOOL)resignFirstResponder
{
    _inputTextField.userInteractionEnabled = NO;

    return [super resignFirstResponder];
}

- (void)setIsEnabled:(BOOL)isEnabled
{
    [super setIsEnabled:isEnabled];

    _inputTextField.enabled = isEnabled;
}

- (id)value
{
    return _inputTextField.text;
}

- (void)setValue:(NSString *)value
{
    _inputTextField.text = value;
}

#pragma mark - UITextFieldDelegate methods

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    [self.delegate tableViewCellDidChangeValue:self];
}

@end

CBTextViewTableViewCell

सेल ऊंचाई गतिशील है और पंक्ति तब बढ़ेगी जब टेक्स्ट नई लाइन से लिपटा हो!

//
//  CBTextViewTableViewCell.h
//
//  Copyright (c) CodePigeon. All rights reserved.
//

#import "CPTableViewCell.h"

@interface CPTextViewTableViewCell : CPTableViewCell

@property (nonatomic, weak) IBOutlet UITextView *inputTextView;

@end

//
//  CBTextViewTableViewCell.m
//
//  Copyright (c) CodePigeon. All rights reserved.
//

#import "CPTextViewTableViewCell.h"

@interface CPTextViewTableViewCell () <UITextViewDelegate>
{
    UITextView *_heightTextView;
}

@end

@implementation CPTextViewTableViewCell

@synthesize height = _height;

- (void)awakeFromNib
{
    [super awakeFromNib];

    self.selectionStyle = UITableViewCellSelectionStyleNone;

    _inputTextView.userInteractionEnabled = NO;
    _inputTextView.delegate = self;
    _inputTextView.contentInset = UIEdgeInsetsZero;
    _inputTextView.scrollEnabled = NO;
}

- (CGFloat)height
{
    if (!_heightTextView)
    {
        CGRect frame = (CGRect) {
            .origin = CGPointMake(0.f, 0.f),
            .size = CGSizeMake(_inputTextView.textInputView.frame.size.width, 0.f)
        };

        _heightTextView = [[UITextView alloc] initWithFrame:frame];
        _heightTextView.font = [UIFont systemFontOfSize:_inputTextView.font.pointSize];
        _heightTextView.textColor = UIColor.whiteColor;
        _heightTextView.contentInset = UIEdgeInsetsZero;
    }

    _heightTextView.text = _inputTextView.text;

    CGSize size = [_heightTextView sizeThatFits:CGSizeMake(_inputTextView.textInputView.frame.size.width, FLT_MAX)];

    return size.height > _height ? size.height + _inputTextView.font.pointSize : _height;
}

- (BOOL)becomeFirstResponder
{
    _inputTextView.userInteractionEnabled = YES;

    [_inputTextView becomeFirstResponder];

    return [super becomeFirstResponder];
}

- (BOOL)resignFirstResponder
{
    _inputTextView.userInteractionEnabled = NO;

    return [super resignFirstResponder];
}

- (void)setIsEnabled:(BOOL)isEnabled
{
    [super setIsEnabled:isEnabled];

    _inputTextView.editable = isEnabled;
}

- (id)value
{
    return _inputTextView.text;
}

- (void)setValue:(NSString *)value
{
    _inputTextView.text = value;

    [_inputTextView setNeedsLayout];
    [_inputTextView layoutIfNeeded];
}

#pragma mark - UITextViewDelegate methods

- (void)textViewDidChange:(UITextView *)textView
{
    [self.delegate tableViewCellDidChangeValue:self];

    [self.tableView beginUpdates];
    [self.tableView endUpdates];
}

@end

0

स्विफ्ट संस्करण में DateCell का उपयोग करने का सबसे आसान तरीका: इस उदाहरण का उपयोग करें

  1. इस उदाहरण को खोलें और इसका परीक्षण करें (मेक एक्सकोड टू कन्वर्ट स्विफ्ट 2)
  2. अपनी परियोजना के लिए " DateCellTableViewController.swift " कक्षा खींचें ।

  3. "Main.storyboard" खोलें और " DateCell " ViewController Object को कॉपी करें और इसे अपने स्टोरीबोर्ड में पेस्ट करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.