視圖的touch事件的傳播控制

在視圖控制器類中,self.view中會包括多個多層的自定義視圖。我自定義了一個uicollectionview類,名稱爲gridview,又自定義了一個uicollectionviewcell類,名爲gridcell。在gridcell的contentview中增加uitextfield對象。

+----------------------------+

|A -gridview                |

|+--------+   +------------+ |

||B-      |  |C           | |

||gridcell|   |gridcell   | |

|+--------+  +------------+ |

|                            |

|                            |

+----------------------------+

這樣,該視圖控制器類就會展現出一系列的表格組合,類似於excel。要實現的功能有這些:

1、在touch一個格子時就能出現虛擬鍵盤,從而可以立即編輯它。

2、在虛擬鍵盤出現以後,再touch表格視圖的任意點都能關閉虛擬鍵盤,但不再次打開可能被touch到的另外一個格子。

3、在longpress一個格子時,還是鎖定並移動它到任意位置上。

通過對touch事件的控制,可以實現虛擬鍵盤的打開和關閉,所見即所得的功能。


uiview的hitTest:withEvent:方法

在自定義的gridview類中,需要對該方法進行重定義,用於控制touch事件的傳播和對gridview的處理。

如果hitTest:withEvent:返回的結果不是nil,則touch事件會傳播到gridcell中,並調用gridview的-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event方法。

如果返回的結果是nil,則返回調用視圖控制器類中-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event方法,這個方法重載以後,可以實現對控制虛擬鍵盤的關閉。

因此,重載這個方法,可以實現對touch事件的傳播的控制。

gridview中重載的方法

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

{

    // 根據條件截斷 事件的傳輸鏈條

    if ([selfisFirstResponder]) {

        // [selfresignFirstResponder]; 因爲該方法 一次點擊會被調用兩次,導致其會進一步調用cell中的該方法。所以不在此處 resign first responder

        // 在此出將 事件鏈條 截斷,從而使得 集合視圖可以工作。否則,將觸發集合視圖覆蓋的虛擬鍵盤。

//        return NO;

    }

   

    return [superpointInside:point withEvent:event];

}

在這個方法中也可以實現對touch事件的傳播進行控制。

//---

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

{

    GTMLoggerDebug(@"\nmasterCV hitTest:%@", [NSDate date]);

    // 根據條件截斷 事件的傳輸鏈條

    if ([selfisFirstResponder]) {

        // [selfresignFirstResponder]; 因爲該方法 一次點擊會被調用兩次,導致其會進一步調用cell中的該方法。所以不在此處 resign first responder

        // 在此出將 事件鏈條 截斷,從而使得 集合視圖可以工作。否則,將觸發集合視圖覆蓋的虛擬鍵盤。

        return nil;

    }

   

    if (self.editingCell)

    {

        return nil;

    }

   

    UIView *result = [superhitTest:point withEvent:event];

    return result;

}

注意,這兩個方法在一次touch時,會被多次調用。在ios7.1中,我測試結果是2次調用,在網上看到有說是3次調用的。

因此,該方法中只用來實現touch事件的傳播控制,不做其他任務如關閉虛擬鍵盤等處理。

這些任務處理在視圖控制類中實現。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    [supertouchesBegan:touches withEvent:event];

 

    if ([_gridViewisFirstResponder]) {

        [_gridViewresignFirstResponder];

    }

 

    [self.navigationItem.titleViewendEditing:YES];

 

    [self.viewendEditing:YES];

}

處理的任務分別有:

如果gridview是第一響應者,則重置它;

導航欄上標題視圖的編輯結束;

self.view中所有視圖的編輯結束。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章