2012-02-23 98 views
7

我有一個UITableView,其中有8個單元格(部分),其中6個包含textFields作爲子視圖,2個包含按鈕,另一個包含文本視圖。現在我有一個問題在這裏,因爲我們都知道,當視圖只出現時,可見單元格加載。因此,當我的應用程序加載時,我能夠查看5個單元格,前4個包含文本字段和第5個單元格與按鈕。可以看到陣列計數爲4,當我顯示它通過測井控制檯即在滾動之前加載UITableView中的所有單元格

there are 4 objects in the array 

現在滾動表視圖後,我可以觀察到以下:

there are 6 objects in the array 

因此,發生了什麼是如果我要保存在表視圖中輸入的數據,或者說編輯以更改現有數據,我不得不滾動表視圖並在最後一個單元格中輸入值。對於用戶來說,情況並非如此,因爲我們不能指望他/她滾動表格視圖並輸入完整的表格/表格視圖單元格條目。他/她做出了什麼改變,只需點擊完成/保存了什麼它永遠是..!

更多我有一個選擇器視圖作爲包含文本字段作爲子視圖的最後一個單元格的輸入視圖。在我的選擇器視圖做選擇行方法我面臨着最後一個細胞/部分(textField作爲子視圖)選擇器視圖這裏是我的方法的代碼片段:

-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 
{ 

    switch (tagValues) 
    { 

     case 105: 
     { 
      self.textField = [self.fields objectAtIndex:3]; 
      self.textField.text = [self.reminder objectAtIndex:row]; 
     } 
      break; 

     case 107: 
     { 
      //Crash occurring in this case,sometimes its working wonder why 
      self.textField = [self.fields objectAtIndex:5]; 
      self.textField.text = [self.group objectAtIndex:row]; 
     } 
      break; 

    } 

} 

**Note**:I am using the same textField for adding as subview to all 6 cells,but each one with unique tags and own purpose,i.e. one for editing text using key board,one with date picker,one with general picker etc... 

我不知道爲什麼,從選擇器視圖(最後一節電池)選擇值後有時死機一些時間,有時效果fine.Some次崩潰在上述行註釋case 107,有時在主autorelease池中。有些時候線程如下圖所示:

enter image description here

那麼,有沒有我們可以加載所有細胞一下子讓所有的文本字段被添加到陣列之前scrolling.There不能有任何的問題,我相信

更多詳細編輯的代碼以任何方式對於理解:

- (UITableViewCell *)tableView:(UITableView *)atableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

    //NSString *identifier = @"UITableViewCell"; 

    NSString *cellIdentifierF = nil; 

    static NSString *firstCellIdentifier = @"FirstCell"; 
    static NSString *secondCellIdentifier = @"SecondCell"; 
    static NSString *thirdCellIdentifier = @"ThirdCell"; 
    static NSString *fourthCellIdentifier = @"FourthCell"; 
    static NSString *fifthCellIdentifier = @"FifthCell"; 
    static NSString *sixthCellIdentifier = @"SixthCell"; 
    static NSString *seventhCellIdentifier = @"SeventhCell"; 
    static NSString *eightCellIdentifier = @"EightCell"; 

    if(indexPath.section == 0 && indexPath.row == 0) 
    { 
     cellIdentifierF = firstCellIdentifier; 
    } 
    else if(indexPath.section == 1 && indexPath.row == 0) 
    { 
     cellIdentifierF = secondCellIdentifier; 
    } 
    else if(indexPath.section == 2 && indexPath.row == 0) 
    { 
     cellIdentifierF = thirdCellIdentifier; 
    } 
    else if(indexPath.section == 3 && indexPath.row == 0) 
    { 
     cellIdentifierF = fourthCellIdentifier; 
    } 
    else if(indexPath.section == 4 && indexPath.row == 0) 
    { 
     cellIdentifierF = fifthCellIdentifier; 
    } 
    else if(indexPath.section == 5 && indexPath.row == 0) 
    { 
     cellIdentifierF = sixthCellIdentifier; 
    } 
    else if(indexPath.section == 6 && indexPath.row == 0) 
    { 
     cellIdentifierF = seventhCellIdentifier; 
    } 
    else if(indexPath.section == 7 && indexPath.row == 0) 
    { 
     cellIdentifierF = eightCellIdentifier; 
    } 

    UITableViewCell *cell = (UITableViewCell *)[atableView dequeueReusableCellWithIdentifier:cellIdentifierF]; 

     atableView.backgroundColor = [UIColor clearColor]; 

     textField = [[[UITextField alloc]initWithFrame:CGRectMake(15, 12, 300, 24)]autorelease]; 
     textField.textColor = [UIColor whiteColor]; 
     textField.delegate = self; 
     tagValues = textField.tag; 

    switch (indexPath.section) 
    { 
     case 0: 
     { 
      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"buttonbg-1.png"]]; 

       //Only add content to cell if it is new 
       if([cellIdentifierF isEqualToString: firstCellIdentifier]) 
       { 
        textField.placeholder = @"Enter name"; 
        [self.textField setValue:[UIColor purpleColor] 
            forKeyPath:@"_placeholderLabel.textColor"]; 
        textField.tag = 101; 
        textField.text = reminderInstance.Name; 
        textField.autocorrectionType = UITextAutocorrectionTypeNo; 
        NSLog(@"Value = %@",textField.text); 
        [cell.contentView addSubview:textField]; 
        [self.fields addObject:textField]; 
       } 
      } 
     } 
      break; 

     case 1: 
     { 
      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"buttonbg-1.png"]]; 

       //Only add content to cell if it is new 
       if([cellIdentifierF isEqualToString: secondCellIdentifier]) 
       { 
        textField.tag = 102; 
        textField.text = reminderInstance.Event; 
        NSLog(@"Value = %@",textField.text); 
        [cell.contentView addSubview:textField]; 
        [self.fields addObject:textField]; 
       } 
      } 
     } 
      break; 

     case 2: 
     { 
      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"buttonbg-1.png"]]; 

       //Only add content to cell if it is new 
       if([cellIdentifierF isEqualToString: thirdCellIdentifier]) 
       { 
        textField.placeholder = @"Click here to set date and time"; 
        [self.textField setValue:[UIColor purpleColor] 
            forKeyPath:@"_placeholderLabel.textColor"]; 
        textField.inputView = self.datePicker; 
        textField.text = reminderInstance.Date; 
        textField.tag = 103; 
        NSLog(@"Value = %@",textField.text); 
        [cell.contentView addSubview:textField]; 
        [self.fields addObject:textField]; 
       } 
      } 
     } 
      break; 

     case 3: 
     { 
      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"buttonbg-1.png"]]; 

       //Only add content to cell if it is new 
       if([cellIdentifierF isEqualToString: fourthCellIdentifier]) 
       { 
        textField.tag = 105; 
        textField.text = reminderInstance.numDays; 
        textField.inputView = self.reminderPicker; 
        NSLog(@"Value = %@",textField.text); 
        [cell.contentView addSubview:textField]; 
        [self.fields addObject:textField]; 
       } 
      } 
     } 
      break; 

     case 4: 
     { 
      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"buttonbg-1.png"]]; 

       //Only add content to cell if it is new 
       if([cellIdentifierF isEqualToString: fifthCellIdentifier]) 
       { 
        checkboxButton = [[[UIButton alloc] initWithFrame:CGRectMake(16,1,120, 44)]autorelease]; 
        [checkboxButton setImage:[UIImage imageNamed:@"ewee.png"] forState:UIControlStateNormal]; 
        [checkboxButton addTarget:self action:@selector(toggleButton:) forControlEvents:UIControlEventTouchUpInside]; 

        NSString *one = reminderInstance.selString; 
        NSNumber* i = [NSNumber numberWithInt:[one intValue]]; 
        BOOL isOn = [i boolValue]; 

        if(isOn) 
        { 
         [checkboxButton setImage:[UIImage imageNamed:@"checkarrow.png"] forState:UIControlStateNormal]; 
        } 
        else 
        { 
         [checkboxButton setImage:[UIImage imageNamed:@"ewee.png"] forState:UIControlStateNormal]; 
        }    
        NSLog(@"String Val = %@",one); 

      [checkboxButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft]; 
      [checkboxButton setImageEdgeInsets:UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0)]; 
      [cell addSubview:checkboxButton]; 
      UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(55, 10, 225, 24)]; 
      label.text = @"Every Year"; 
      label.textColor = [UIColor whiteColor]; 
      label.backgroundColor = [UIColor clearColor]; 
      [cell addSubview:label]; 
      cell.textLabel.textColor = [UIColor whiteColor]; 
      [label release]; 
       } 
      } 

     } 
      break; 

     case 5: 
     { 
      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"buttonbg-1.png"]]; 

       //Only add content to cell if it is new 
       if([cellIdentifierF isEqualToString: sixthCellIdentifier]) 
       { 
        textField.placeholder = @"Enter the number here"; 
        [self.textField setValue:[UIColor purpleColor] 
            forKeyPath:@"_placeholderLabel.textColor"]; 
        textField.text = num; 
        textField.text = reminderInstance.number; 
        textField.tag = 106; 
        textField.userInteractionEnabled = YES; 
        textField.keyboardType = UIKeyboardTypeNumberPad; 
        NSLog(@"Value = %@",textField.text); 
        [cell.contentView addSubview:textField]; 
        [self.fields addObject:textField]; 
       } 
      } 
     } 
      break; 

     case 6: 
     { 
      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"reminderbuttonxl.png"]]; 

       //Only add content to cell if it is new 
       if([cellIdentifierF isEqualToString: seventhCellIdentifier]) 
       { 
        cell.backgroundColor = [UIColor clearColor]; 
        textView.clipsToBounds = YES; 
        textView = [[UITextView alloc]initWithFrame: CGRectMake(-2, -3, 307, 154)]; 
        UIImageView *imgView = [[[UIImageView alloc]initWithFrame: textView.frame]autorelease]; 
        imgView.image = [UIImage imageNamed: @"buttonbg_text.png"]; 
        [textView addSubview: imgView]; 
        [textView sendSubviewToBack: imgView]; 
        textView.backgroundColor = [UIColor clearColor]; 
        textView.delegate = self; 
        textView.tag = 11; 
        tagValues = textView.tag; 
        textView.textColor = [UIColor purpleColor]; 
        [cell.contentView addSubview:textView]; 
        textView.text = @"Your birthday wishes/other reminder body here"; 
        NSLog(@"Value = %@",textView.text); 
       } 
      } 
     } 
      break; 

     case 7: 
     { 
      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"buttonbg-1.png"]]; 

       //Only add content to cell if it is new 
       if([cellIdentifierF isEqualToString: eightCellIdentifier]) 
       { 
        textField.tag = 107; 
        textField.inputView = self.groupPicker; 
        tagValues = textField.tag; 
        textField.text = reminderInstance.remGroup; 
        NSLog(@"Value = %@",textField.text); 
        [cell.contentView addSubview:textField]; 
        [self.fields addObject:textField]; 
       } 
      } 
     } 
      break; 

     default: 
      break; 
    } 

    int size = [fields count]; 
    NSLog(@"there are %d objects in the array", size); 

    return cell; 
} 

我曾幾次試圖找出究竟是怎麼了?也是我查了一些問題herethere。但找不到任何EFFIC ient/APPR。回答或解決我的問題。

所以,任何人都可以幫助我提供寶貴的建議或示例代碼片段。

感謝所有提前:)

+0

我不相信有可能加載不可見的單元格。該表將從數據源中提取數據並僅加載可見單元格。其他單元格將在您滾動時加載,並且它們將變爲可見。 – 2012-02-23 14:19:52

+0

你在哪裏製作新單元如果它不存在 – fibnochi 2012-02-23 14:26:14

+0

@BillBurgess謝謝布爾吉斯先生據我所知還知道你在說什麼..但是我面臨很多問題,因爲這樣做是因爲沒有做出任何改變或觸摸最後一個如果用戶進入表格視圖,填入在該時間點輸入的數據,然後說出用戶是否隨意修改了前2個單元格並單擊完成然後它將最後一個字段(不可見)值視爲零,即使有值。 – 2012-02-23 14:26:17

回答

4

它將使意義會有很多從正在構建的形式(這實際上就是這種情況) 是我一直在做我自己的方式來問題當我需要構建一個這樣的表單時,就是使用所有的控件構建一個普通的視圖,無論它長什麼樣,並且在滾動視圖中都有這種形式,並將其內容大小設置爲視圖的大小。這可以讓你更好地控制你想要表單的外觀。 ,我不認爲我已經看到一個應用程序使用tableview的表單條目。(只需在Xcode上作弊並使主視圖和滾動視圖足夠大,以便您可以看到構建器上的所有內容,然後在完成後將其大小調整爲適當的大小);可以使用界面構建器來構建表單

+0

非常感謝Mr.Ehab Amer,但我不知道如何實現你所說的。可以給我一個建議教程或示例代碼,我可以把它作爲參考和實施相同,在此先感謝:) – 2012-02-23 14:39:49

+2

+1指出問題的真正原因。 – lawicko 2012-02-23 14:50:41

+0

您可以提供關於您嘗試構建的表單的更多信息嗎?我會嘗試一步一步來。 如果您不熟悉界面構建器,則可以在Google上搜索「界面構建器教程」。 – 2012-02-23 14:59:34

0

會發生什麼情況是UITableView只加載可見單元格,並且在UITableView滾動的所有時間,調用回調cellForRowAtIndexPath:。但讓我明白這一點。爲什麼你需要一個UITableView來創建表單?正如我所看到的,您每節加載一個單元格...而且,您只是初始化單元格。你應該做什麼。子類UITableViewCell並在那裏創建對象。

然後調用這樣的:

cell = [[[MyCustomCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 

然後就可以調用正是你想要的控制器。當你滾動時,你必須控制你的UITableView的行爲。像這樣:

case 7: 
     { 
      if (cell == nil) 
      { 
       cell = [[[MyCustomCellEigth alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"buttonbg-1.png"]]; 

       /*this should be done in the Custom Cell init method 
       if([cellIdentifierF isEqualToString: eightCellIdentifier]) 
       { 
        textField.tag = 107; 
        textField.inputView = self.groupPicker; 
        tagValues = textField.tag; 
        textField.text = reminderInstance.remGroup; 
        NSLog(@"Value = %@",textField.text); 
        [cell.contentView addSubview:textField]; 
        [self.fields addObject:textField]; 
       } 
       */ 
      } 
      else 
      { 
       //Control content 
       ((MyCustomCell*)cell).myTextField.text = @"SOME TEXT"; 
      } 
     } 
     break; 

關於選取器。它可能只在滾動所有表後才起作用,因爲它引用了一個textField,只有當通訊單元變爲可見時纔會將其添加到數組中。

沒有太多的事情要做。但按照這個,你應該沒問題。首先,子類UITableViewCell。您可以通過編程或使用xib自行創建控件。這會讓你更好地控制細胞本身。關於選擇器,不是用控件創建數組,而是用它應該有的值創建它。一旦有人輸入了某些內容,請使用UITextFieldDelegate進行保存。 希望它有幫助。

編輯:

您必須創建的UITableViewCell的子類。在Xcode上,創建一個新文件。選擇objective-c類。在下一個屏幕上,選擇UITableViewCell的字段子類並相應地命名您的單元格。這將創建一個將覆蓋initWithStyle:reuseIdentifier:方法的類。在這個方法裏面,你應該放入你的init代碼。

這樣的:

#import <UIKit/UIKit.h> 

@interface MyCustomCellOne : UITableViewCell 
{ 
    UITextField *textField; 

} 
@end 

#import "MyCustomCellOne.h" 

@implementation MyCustomCellOne 

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{ 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
    if (self) { 
     // Initialization code 
        textField = [[UITextField alloc] initWithFrame:"YOUR FRAME"]; 
        textField.tag = 107; 
        textField.text = @"SOME TEXT"; 

        [self addSubview:textField];   
    } 
    return self; 
} 
+0

謝謝拉斐爾艾爾斯,但我不完全瞭解「/ *這應該在自定義單元初始化方法中完成」可以編輯我的帖子相應請,謝謝:) – 2012-02-23 14:46:11

+0

更改我的答案顯示您如何創建自定義單元格。 – 2012-02-23 15:09:58

+0

Oh k Mr.Raphael,感謝所有的關注,但只是一個小小的懷疑,在編輯部分的ur答案中實現相同的代碼片段後,除了init方法中的更改外,上面的其餘實現仍保持相同。 。對? – 2012-02-23 15:14:36

1

這聽起來像你可能會關閉不使用表格視圖可言,但使用滾動視圖,而不是更好。如果你確實有一些固定數量的東西要顯示,那麼你可以將它們放在滾動視圖上作爲視圖(而不是表格單元格),代碼將變得更簡單。

如果您希望從表格視圖中只顯示外觀,您可以簡單地使用看起來像您想要的方式的背景圖片,並將視圖和控件覆蓋在該背景上。你應該可以在Interface Builder中完成所有這些。

如果你採取這種方法,你的視圖控制器中的代碼現在就是你需要處理文本輸入和按鈕按下的事情,而且你不需要擔心表視圖委託或數據源。

+0

哦,我已經使用滾動視圖做了它。但許多人已經建議這是一種糟糕的編程方法,並說「使用表視圖而不是「。因此,我把我的編碼方法從UIScrollView切換到UITableView.So,因爲你說我會實施相同的方式並回復給你,非常感謝 – 2012-02-23 14:49:02

+0

您好Mr.Mike我無法理解wh我的滾動視圖不滾動。我已經實現了你所建議的一樣,並且在這個鏈接中也實現了相同的代碼:http://www.roseindia.net/tutorial/iphone/tutorial/iphone/UIScrollView-Example-iPhone。 HTML。但問題出現時,當搜索問題關於相同的前:http://stackoverflow.com/questions/3608949/iphone-uiscrollview-not-scrolling-when-adding-item-via-ib,什麼建議是設置內容大小,即使那樣我無法實現滾動。可以請你告訴我什麼是錯的! – 2012-02-24 12:47:27

1

雖然這似乎已經解決了,但是做一個「骯髒的黑客攻擊」可能會使整個表格滾動到底部,然後再執行任何操作。類似於[myTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];這樣就會強制加載所有的UITableCellView。請記住,這不是首選方式,但可以在需要更改代碼的情況下工作。

相關問題