2008-12-08 100 views
18

我有一個問題,當在UITableViewCell中點擊textField時,方法tableView:didSelectRowAtIndexPath:不會被調用。問題是,我需要將我的tableView滾動到正確的位置,否則鍵盤會直接通過第一響應者。點擊UITableViewCell中的UITextField

我必須再移動這樣的代碼:

[[self tableView] scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

到我的兩個tableView委託方法,在我的UITextField委託方法,textFieldDidBeginEditing:

創建一個新方法,傳遞給它的單元格/文本字段的索引路徑並從tableView委託和UITextField委託中調用方法是最好的方法嗎?更好的方式去做呢?

回答

6

您可以將控制器作爲您的UITextField的委託,然後在調整表視圖無論是textFieldDidBeginEditing:textFieldShouldBeginEditing:

+0

八月,這就是我目前正在做的。問題在於,滾動需要在兩個地方發生。在tableView:didSelectRowAtIndexPath:方法和textFieldDidBeginEditing:方法中。直接點擊UITextField不會冒泡,因此無法在一個地方處理。 – Coocoo4Cocoa 2008-12-08 21:20:23

+0

您應該讓UITextFieldDelegate方法調用tableView:didSelectRowAtIndexPath:如果兩種情況下的scrollng都相同。這是唯一合理的方法,因爲UITableView被UITextField遮擋。 – 2008-12-08 22:11:38

0

註冊UIKeyboardWillShowNotification和UIKeyboardWillHideNotification,然後調整通知處理程序需要您的觀點。其中一個示例應用程序顯示瞭如何執行此操作,但我忘記了...... SQLiteBooks或EditableDetailView。

9

有幾種方法可以解決這個問題。會發生什麼是tableViewCell委託觸摸事件的子視圖導致文本字段處理觸摸而不是您的單元格。當你得到didSelectRowAtIndexPath方法的消息重新啓用userInteractionEnabled並調用文本字段的becomeFirstResponder

  • 設置的UITextField的userinteractionEnabled屬性爲NO,那麼:

    爲了解決這個問題。在v2.2上,你甚至不需要設置userInteractionEnabled標誌,我沒有用其他版本測試過,但是文檔很清楚你應該啓用它。在tableViewController中,只需要保存indexpath直到獲得UIKeyboardDidShow消息

  • 爲UITextField創建一個委託,該委託報告給您的tableViewController,以便您可以從那裏設置滾動偏移量。

  • 註冊鍵盤事件,然後通過檢查在編輯模式下什麼文本框計算出scrolloffset

0

我這個同樣的問題,在那裏我有UITableViewCells內UITextFields並不能掙扎獲取視圖以在編輯時滾動到該字段。我的解決方案的核心在下面。

此代碼的關鍵是創建UITextField的行。它不是在CGRectMake()函數中對x和y值進行硬編碼,而是使用放置它的單元格的x和y(+/-單元邊緣所需的任何偏移量,如下所示)。在UITextField *中硬編碼的x和y值給每個單元格相同的 x,y每個UITextField *的幀位置(當它顯示時它顯然被單元格框架覆蓋),所以當你調用'scrollRectToVisible'似乎沒有它應該滾動的正確座標。

1)創建細胞,並利用細胞的幀x和y值添加的UITextField *到細胞(我包括這裏偏移,其是可選的

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

    UITableViewCell* cell; 
    cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"]; 
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"UITableViewCell"] autorelease]; 

    //this is the critical part: make sure your UITextField* frame is based on the frame of the cell in which it's being placed. 
    UITextField* txtField = [[UITextField alloc] initWithFrame:CGRectMake(cell.frame.origin.x+20, cell.frame.origin.y+9, 280, 31)]; 
    txtField.delegate = self; 

    [cell addSubview:txtField]; 
    return cell; 
} 

2)在textFieldDidBeginEditing

調整滾動視圖
-(void) textFieldDidBeginEditing:(UITextField *)textField { 

    CGRect textFieldRect = [textField frame]; 
    [self.tableView scrollRectToVisible:textFieldRect animated:YES]; 
} 
+0

除非我遺漏了一些東西,否則只要選擇一個單元格,它就會滾動到表格的頂部。此外,如果您從中滾動,則以前的條目會消失。 – cannyboy 2010-05-11 17:42:04

3

我沒有找到任何解決方案,在我的網絡工作。經過幾天的谷歌搜索和實驗,我終於有了這個發行很好的釘。這是蘋果iPhone的一個複雜的錯誤,你會在這篇文章的最後看到。

如果你遇到了一個問題,像我這樣如下:

  • 有tableviewcell大於iPhone屏幕的一半(不要與蘋果的UICatalog的例子並不糊塗有一個短暫的tableview的小於50點,在這裏不適用。),

  • 具有在細胞中或的UITextField和在細胞中的UITextView或UIWebView中的組合多於一個uitexfields,

  • uitextfields和的UITextView或uiweb之間攻絲細胞查看滾動位置不可預知的結果,或者單擊的uitextfield跳出視圖或被keybaord覆蓋。它只在鍵盤出現在tableviewcell中時才起作用,隨後不能正常工作。

  • 我有過重大突破閱讀類似這樣的帖子後:http://alanduncan.net/old/index.php?q=node/13他們並沒有完全得到它的權利無論是。這種痛苦是由UIKeyboard事件中的一個錯誤引起的。當鍵盤第一次出現時,它會發出一個UIKeyboardWillShowNotification和UIKeybaordDidShowNotification。 Theree是iPhone中的一個錯誤,第一個UIKeyboardWillShowNotification與後續的UIKeyboardWillShowNotification不同。解決方案是OBSERVE UIKeyboardDidShowNotification。所以,當你的電池會出現,添加以下代碼

    NSNotificationCenter*nc=[NSNotificationCenter defaultCenter]; 
        [nc addObserver:self selectorselector(keyboardDidShow name:UIKeyboardDidShowNotification object:self.window]; 
    

    在keyboardDidShow功能,我們需要滾動tableview中,而不是tableviewcell在上面的帖子建議。或者你可能會看到各種各樣的物體,而不是一起滾動。

    (void)keyboardDidShow:(NSNotification *)notif 
    { 
        //1. see which field is calling the keyboard 
        CGRect frame; 
        if([textField_no1 isFirstResponder]) 
        frame=textField_no1.frame; 
        else if([textField_no2 isFirstResponder]) 
        frame=textField_no2.frame; 
        else if([textField_no3 isFirstResponder]) 
        frame=textField_no3.frame; 
        else if([textView isFirstResponder]) 
        frame=textView.frame; 
        else return; 
        CGRect rect=self.superview.frame; 
    
        //2. figure out how many pixles to scroll up or down to the posistion set by theKeyBoardShowUpHorizon. 
    
        //remove the complexity when the tableview has an offset 
        [((UITableView*)[self.superview).setContentOffset:CGPointMake(0,0) animated:YES]; 
    
        int pixelsToMove=rect.origin.y+ frame.origin.y-theKeyBoardShowUpHorizon; 
    
        //3. move the uitableview, not uitableviewcell 
        [self moveViewUpOrDownByPixels:pixelsToMove]; 
    
    } 
    
    - (void)moveViewUpOrDownByPixels:(int)pixels 
    { 
    
        [UIView beginAnimations:nil context:NULL]; 
        [UIView setAnimationDuration:0.6]; 
    
        //find the position of the UITableView, the superView of this tableview cell. 
        CGRect rect=self.superview.frame; 
    
        //moves tableview up (when pixels >0) or down (when pixels <0) 
        rect.origin.y -= pixels; 
        rect.size.height += pixels; 
        self.superview.frame = rect; 
        [UIView commitAnimations]; 
    } 
    

    要恢復的tableView回來,你需要在UIKeyboardDidHideNotification添加觀看者(未UIKeyboardWillHideNotification通過其他職位的建議,以避免閃爍),您tableviewcell每次出現,把後面的實現代碼如下它在哪裏。

    [nc addObserver:self selectorselector(keyboarDidHide) name:UIKeyboardDidHideNotification object:nil]; 
    
    - (void)keyboardDidHideNSNotification*)notif 
    { 
        //we have moved the tableview by number of pixels reflected in (self.superview.frame.origin.y). We need to move it back 
        [self moveViewUpOrDownByPixels:self.superview.frame.origin.y]; 
    } 
    

    不要忘記將observesr的同時刪除當你的電池由[NSNotificationCenter defaultCenter] removeObserver消失:...

    這是所有需要。我希望有一天蘋果iPhone團隊能夠解決這個問題,也許在幾個月內就會達到4.0。

    3

    我找到了解決方案。

    1. 在界面構建器中打開.xib文件。
    2. 選擇表視圖
    3. 從IB菜單中選擇工具 - >尺寸檢查 在滾動查看尺寸部分,修改鑲嵌 - >底值至100,150,250這取決於你有多大的表視圖。

    代碼

    -(void) textFieldDidBeginEditing:(UITextField *)textField 
    { 
        UITableViewCell *cell = (UITableViewCell *) [[textField superview] superview]; 
        [self.tableView scrollToRowAtIndexPath:[tableView indexPathForCell:cell] 
        atScrollPosition:UITableViewScrollPositionBottom animated:YES]; 
    } 
    
    3

    我發現它實際上很容易做到這一點。

    的UITextField委託方法textFieldDidBeginEditing會給你的文本字段,然後你就可以使用映射到一個indexPath:

    self.currentIndexPath = [self.tableView indexPathForRowAtPoint:textField.frame.origin]; 
    

    然後你就可以滾動細胞進入視野(即在UIKeyboardDidShowNotification鍵盤通知處理程序) :

    [self.tableView scrollToRowAtIndexPath:self.currentIndexPath atScrollPosition:UITableViewScrollPositionNone animated:YES]; 
    
    +0

    在此示例中,textField的框架將在單元格內容視圖的座標中顯示原點。爲了這個工作,至少對於動態表格來說,需要的點是'textField.superview.superview.frame.origin',它轉換爲:textField-> CellContentView->單元格在表格座標中的原點。 – Gobot 2012-03-26 03:14:56

    21

    我發現了以下工作井(假定您在表視圖控制器是)

    - (void)textFieldDidBeginEditing:(UITextField *)textField{ 
        CGPoint pnt = [self.tableView convertPoint:textField.bounds.origin fromView:textField]; 
        NSIndexPath* path = [self.tableView indexPathForRowAtPoint:pnt]; 
        [self.tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
    } 
    
    1

    didSelectRowAtIndexPath不會被UITextField嵌入單元調用;因此,滾動邏輯需要在別處。

    - (void)textFieldDidBeginEditing:(UITextField *)textField { 
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:1]; 
        UITableViewCell *cell = [_tableView cellForRowAtIndexPath:indexPath]; 
        [_tableView setContentOffset:CGPointMake(0, cell.frame.size.height) animated:YES]; 
    } 
    

    確保導線文本框授人以自我

    0

    的問題是由事實,那就是找出用戶是否拍了拍文本字段或者它是通過becomeFirstResponder激活沒有簡單的方法加重。

    我可以想出的最優雅的解決方案是在單元格子類上實現hitTest:withEvent:,並且基本上假設文本字段在選擇單元格之前不存在。

    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { 
        UIView *view = [super hitTest:point withEvent:event]; 
    
        if(view == self.textField && !self.selected) { 
         return self; 
        } 
    
        return view; 
    } 
    

    tableView:didSelectRowAtIndexPath:那麼應該手動進行文本字段第一個響應者。

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
        TextFieldCell* cell = [self.tableView cellForRowAtIndexPath:indexPath]; 
    
        [cell.textField becomeFirstResponder] 
    
        [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
    } 
    

    最後,我們必須在完成編輯時取消選擇該行。這可以通過UITextField委託或通過鍵盤通知來完成,無論你喜歡什麼。

    - (void)textFieldDidEndEditing:(UITextField *)textField { 
        [self.view endEditing:YES]; 
    } 
    
    相關問題