2011-05-01 126 views
27

我有UIViewControllerUITableView作爲孩子在視圖中, 我想要做的是當我觸摸任何行我顯示底部的視圖。如果用戶觸摸其他位置的行或bottomView,我想隱藏該視圖。在UITableView上觸摸事件?

問題是當我點擊UITableView它不會觸發touchesEnded事件。

現在我該如何檢測UITableView上的觸摸並將其與行選擇事件區分開來。

謝謝。

+0

林不知道我明白。你是說你有一個擁有UITableView的UIView(viewA),和另一個UIView(viewB)(在底部)。如果用戶觸摸UiTableViewCell或viewB以外的任何地方,則希望隱藏viewB。否則,顯示viewB。那是對的嗎? – 2011-05-01 14:19:38

+0

是的正是我想要做的。如果用戶觸摸UITableViewCell我想顯示viewB。我可以通過didRowSelectedAtIndexPath進行存檔: – 2011-05-05 09:55:06

+0

那麼你在問什麼?「你如何捕獲在UITableView上發生的觸摸事件,而不是在單元格中? – 2011-05-05 15:34:31

回答

6

我很長時間以來一直面臨這個問題,並沒有得到任何工作解決方案。最後,我選擇了一個替代方案。我知道技術上這不是解決方案,但這可能有助於某人尋找相同的肯定。

在我來說,我要選擇的行會顯示一些選項後,我在任何地方觸及表或視圖我想隱藏這些選項或做任何任務,除了先前選擇的行我也以下:

  1. 爲視圖設置觸摸事件。當您觸摸視圖中除表格視圖外的任何位置時,這將執行此任務。

  2. TableView中的didSelectRowAtIndexPath方法做以下

    - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { 
        if(indexPath.row != previousSelectedRow && previousSelectedRow != -1) { 
         // hide options or whatever you want to do 
         previousSelectedRow = -1; 
        } 
        else { 
         // show your options or other things 
         previousSelectedRow = indexPath.row; 
        } 
    } 
    

我知道這是舊的文章,而不是一個良好的技術解決方案,但這個工作對我來說。我張貼這個答案,因爲這可以幫助確定的人。

注意:這裏寫的代碼可能有拼寫錯誤,因爲直接在這裏輸入。 :)

2

收到關於UITableView使用觸摸事件:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    //<my stuff> 

    [super touchesBegan:touches withEvent:event]; 
} 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    //<my stuff> 

    [super touchesMoved:touches withEvent:event]; 
} 

- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event 
{ 
    //<my stuff> 

    [super touchesEnded:touches withEvent:event]; 
} 

- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event 
{ 
    //<my stuff> 
    [super touchesCancelled:touches withEvent:event]; 
} 

receive touch events in UITableView

-2

在您的控制器類聲明其去除底視圖的方法。事情是這樣的:

-(IBAction)bottomViewRemove:(id)sender { 

[bottomView removeFromSuperview]; 

} 

在Interface Builder中,選擇您的看法,並在自定義類部分的身份檢查,類改變從UIViewUIControl。之後,轉到連接檢查器並將TouchUpInside事件連接到上面聲明的方法。希望這可以幫助。

8

我只是偶然發現可能是您的問題的解決方案。當您創建表視圖使用此代碼:

tableView.canCancelContentTouches = NO; 

沒有這個設置爲NO,因爲甚至有垂直運動的在你的表視圖(微微有點觸摸事件,一旦取消,如果你把的NSLog聲明在您的代碼中,只要表開始垂直滾動,就會調用touchesCancelled)。

+1

您的解決方案不起作用。我試過你的解決方案,並用包括'touchesCledlled'在內的所有觸摸事件。在'viewDidLoad'中,我設置了[[tblTemp setCanCancelContentTouches:NO];'。我的觸摸方法沒有被調用。 – 2012-07-23 04:30:25

14

您應該將觸摸事件轉發給視圖的控制器。 子類的實現代碼如下控件,然後重寫方法:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [super touchesBegan:touches withEvent:event]; //let the tableview handle cell selection 
    [self.nextResponder touchesBegan:touches withEvent:event]; // give the controller a chance for handling touch events 
} 

然後,你可以做你在控制器的觸摸方法想要什麼。

+0

謝謝@longway,但我沒有得到touchsBegan叫我比我怎麼可以forwar它查看的控制器? 這個問題是關於如何調用touchesBegan事件,當我觸摸tableView :) – 2012-07-21 11:26:07

+0

你子類UItableView,重寫觸摸手柄的方法。然後你創建你的表使用你自定義tableview類 – longway 2012-07-21 12:18:11

+0

嗨,我已經嘗試過你的解決方案,當然可以檢測tableview的topuch並傳遞給它相應的superview。堅果現在我有問題,即UITableview委託方法,即didSelectRowAtIndexPath沒有得到調用。最終,我想要的是,首先檢測觸摸tableview傳遞它superview做一些行動,然後執行didSelectRowAtIndexPath。你能幫我嗎? – 2013-08-02 10:54:51

50

不需要子類化任何東西,您可以將UITapGestureRecognizer添加到UITableView,並根據您的標準吸收手勢。

在您的viewDidLoad:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapOnTableView:)]; 
[self.myTableView addGestureRecognizer:tap]; 

然後,實現你的動作是這樣的標準:

-(void) didTapOnTableView:(UIGestureRecognizer*) recognizer { 
    CGPoint tapLocation = [recognizer locationInView:self.myTableView]; 
    NSIndexPath *indexPath = [self.myTableView indexPathForRowAtPoint:tapLocation]; 

    if (indexPath) { //we are in a tableview cell, let the gesture be handled by the view 
     recognizer.cancelsTouchesInView = NO; 
    } else { // anywhere else, do what is needed for your case 
     [self.navigationController popViewControllerAnimated:YES]; 
    } 
} 

請注意,如果你只是想簡單地拿起點擊任意位置上該表,但不在單元行中的任何按鈕上,只需使用上面的第一個代碼片段即可。一個典型的例子是當你有一個UITableView並且還有一個UISearchBar。當用戶點擊,滾動等表格視圖時,您想要消除搜索欄。代碼示例...

-(void)viewDidLoad { 
    [super viewDidLoad]; 
    etc ... 

    [self _prepareTable]; 
} 
-(void)_prepareTable { 
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 
    self.tableView.allowsSelection = NO; 
    etc... 

    UITapGestureRecognizer *anyTouch = 
     [[UITapGestureRecognizer alloc] 
     initWithTarget:self action:@selector(tableTap)]; 
    [self.tableView addGestureRecognizer:anyTouch]; 
} 
// Always drop the keyboard when the user taps on the table: 
// This will correctly NOT affect any buttons in cell rows: 
-(void)tableTap { 
    [self.searchBar resignFirstResponder]; 
} 
// You probably also want to drop the keyboard when the user is 
// scrolling around looking at the table. If so: 
-(void)scrollViewDidScroll:(UIScrollView *)scrollView { 
    [self.searchBar resignFirstResponder]; 
} 
// Finally you may or may not want to drop the keyboard when 
// a button in one cell row is clicked. If so: 
-(void)clickedSomeCellButton... { 
    [self.searchBar resignFirstResponder]; 
    ... 
} 

希望它可以幫助別人。

+1

我更喜歡在scrollViewWillBeginDragging中調用resignFirstResponder:(UIScrollView *)scrollView方法而不是scrollViewDidScroll。因爲如果用戶在滾動減速過程中將滾動然後單擊searchBar - 鍵盤會在屏幕上出現一秒鐘,然後它會隱藏,這不是一個合適的行爲。使用scrollViewWillBeginDragging方法解決此問題。 – Werewolf 2016-10-20 09:04:44

3

試試這個方法:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView 
{ 

} 

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 
{ 

} 

使用scrollViewDidEndDragging像touchesEnded的替代品。希望能幫助到你。