2011-07-05 47 views
13

我差不多完成了一個UITableViewCell,其中有一個UITextField。而不是要通過CGRectMakeUITableViewCell.contentView我已經實現了它簡單的方法:UITableViewCell與UITextField失去選擇UITableView行的能力?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"Cell"]; 
    [cell setSelectionStyle:UITableViewCellSelectionStyleBlue]; 
    amountField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 190, 30)]; 
    amountField.placeholder = @"Enter amount"; 
    amountField.keyboardType = UIKeyboardTypeDecimalPad; 
    amountField.textAlignment = UITextAlignmentRight; 
    amountField.clearButtonMode = UITextFieldViewModeNever; 
    [amountField setDelegate:self]; 

    [[cell textLabel] setText:@"Amount"]; 
    [cell addSubview:amountField]; 
    return cell; 
} 

然後,我還實施了didSelectRow方法,辭職的文本框,讓顯示等領域投入了意見。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    ... 
    [amountField resignFirstResponder]; 
    ... 
} 

該工程進展順利,唯一的事情是有表中的其他行,當選擇那些別人都在整個小區被選擇並變成藍色,而一個與我的UITextField不,我的意思是場被選中,我可以輸入文本,但單元格未被選中。 我測試,並計算出的問題是在該行:

[cell addSubview:amountField]; 

看來,這打破了可選擇的細胞行爲,甚至將它添加到[cell contentView]不解決這個問題。我錯過了什麼?

回答

39

如果文本字段userInteractionEnabled設置爲YES ,它填補了整個小區,你不能讓細胞來聽碰。爲了讓單元格響應觸摸,您需要將文本字段的userInteractionEnabled設置爲

編輯:如果你想使文本字段可編輯的,當選擇單元格,在didSelectRowAtIndexPath方法添加以下代碼:方法,

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

    // get the reference to the text field 
    [textField setUserInteractionEnabled:YES]; 
    [textField becomeFirstResponder]; 
} 
+0

如果設置'userInteractionEnabled = NO;'這樣豈不呈現的UITextField不可編輯? –

+0

顯然不是:我遵循EmptyStack的建議並設置[amountField setUserInteractionEnabled:NO];在DidSelectRow方法的開始處,然後[amountField setUserInteractionEnabled:YES]僅當選定行是帶有文本字段的行時。選擇現在可以,但我必須在該行上點擊兩次以實際輸入文字... –

+0

@micpringle,Ofcourse。當文本字段填充單元格時,他不能同時使文本字段和單元格對觸摸作出響應。 – EmptyStack

6

您還沒有打破任何通過添加子視圖,而是UITextField捕獲在UITableViewCell之前的觸摸。您可以通過點擊UITextField的外部但在UITableViewCell的邊界內進行測試,您會發現它確實仍然按照您的預期進行選擇。

爲了解決這個問題,你可以繼承UITextField並添加一個UITableView屬性。在實例化UITextField並將其添加到單元格時設置該屬性。

amountField.tableView = tableView; 

然後,你需要重寫becomeFirstResponder在你的子類,並在方法獲得的行用的UITextField的單元格,然後選擇它手動

- (BOOL)becomeFirstResponder 
{ 
    // Get the rect of the UITextView in the UITableView's coordinate system 
    CGRect position = [self convertRect:self.frame toView:self.tableView]; 
    // Ask the UITableView for all the rows in that rect, in this case it should be 1 
    NSArray *indexPaths = [self.tableView indexPathsForRowsInRect:position]; 
    // Then manually select it 
    [self.tableView selectRowAtIndexPath:[indexPaths objectAtIndex:0] animated:YES scrollPosition:UITableViewScrollPositionNone]; 
    return YES; 
} 
+0

你是對的,我試過了,這是真的。謝謝。 –

+0

這也適用,但它需要很多額外的代碼,而設置文本字段userInteractionEnabled = NO,如下面的EmptyStack建議是幾行代碼....至少直到我找到其他問題:)謝謝儘管你的幫助,它使問題更清楚。 –

+0

這不是保留週期嗎? 'tableView' - >'visibleCells' - >'amountField' - >'tableView' – jakenberg

1

第一件事情就是你沒有使用可重複使用的單元格。您提供的編碼會導致大量內存。

接下來的事情是你可以通過觸摸除文本框以外的區域來選擇該行。您疑問句

一種解決方案是

在您的文本字段代表

UITableViewCell *cell = (UITableViewCell *)[textField superView]; 
cell.selected=YES; //I think this will call the didSelectRowATIndex; 

我不知道這會工作。但值得一試。

+0

除了這個表格只有4個單元的事實,因爲它是一個很好的輸入掩碼,所以內存不應該是一個大問題,但爲什麼你說我沒有使用可重用的單元格?我以爲我做到了。我現在要嘗試你的解決方案。謝謝。 –

+0

我認爲你誤解了可重用的概念..看到這裏http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html ...無論如何4單元格是好的,但與一排超過10會給你帶來問題。 – iPrabu

+0

我當然可能會誤解,但是當他們都有不同的控件時,重用細胞不應該被避免嗎?無論如何,感謝您的鏈接:) –

1

首先,你需要爲cellForRowAtIndexPath使用reuseIdentifier,如果你不使用reuseIdentifier的原因是:當你上下滾動時,它會一直分配新的單元格和新的textfields,所以你需要把cell == nil condition ,所以修改後的代碼是在這裏:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *reuseIdentifier = @"Cell"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; 
if (cell==nil) { 
    cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier] autorelease]; 

    UITextField *amountField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 190, 30)]; 
    amountField.placeholder = @"Enter amount"; 
    amountField.keyboardType = UIKeyboardTypeDecimalPad; 
    amountField.textAlignment = UITextAlignmentRight; 
    amountField.clearButtonMode = UITextFieldViewModeNever; 
    [amountField setDelegate:self]; 
    [cell.contentView addSubview:amountField]; 
} 
[cell setSelectionStyle:UITableViewCellSelectionStyleNone]; 
[[cell textLabel] setText:@"Amount"]; 

return cell; 
} 

在didSelect委託方法你可以在索引路徑做這樣

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [prevField resignFirstResponder]; 
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
    UIView *view = [[cell.contentView subviews] lastObject]; 
    if([view isKindOfClass:[UITextField class]]{ 
    currentField = (UITextField*)view; 
    } 
    [currentField becomeFirstResponder]; 
    prevField = currentField; 
} 
+0

夥計們,我感謝你的努力教Cocoa的最佳做法,但我試圖把那裏唯一相關的代碼,amountField沒有每次實例化,但只在視圖確實加載,檢查與!細胞在那裏,但我省略,因爲不相關對我的問題,我的表不滾動,因爲它只有4行。儘管你的其他評論非常有幫助。謝謝! –

1

在細胞內的行添加到這行,以粗體給出

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"Cell"]; 
    [cell setSelectionStyle:UITableViewCellSelectionStyleBlue]; 

    amountField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 190, 30)]; 
    amountField.placeholder = @"Enter amount"; 
    amountField.keyboardType = UIKeyboardTypeDecimalPad; 
    amountField.textAlignment = UITextAlignmentRight; 
    amountField.clearButtonMode = UITextFieldViewModeNever; 

    [amountField setDelegate:self]; 
    [[cell textLabel] setText:@"Amount"]; 

    **for (UIView *cellSubViews in cell.subviews) { 
      cellSubViews.userInteractionEnabled = NO; 
    }** 

    [cell addSubview:amountField]; 
    return cell; 
} 

試試這個,它會工作