簡體   English   中英

如何從UIScrollView竊取觸摸?

[英]How to steal touches from UIScrollView?

今天,在我的創作時間,我做了一些非常全面的研究,如何從UIScrollView竊取觸摸並立即將它們發送到特定的子視圖,同時保持其余滾動視圖的默認行為。 考慮在UITableView中使用UIPickerView。 默認行為是,如果您將手指拖到選擇器視圖上,滾動視圖將滾動,選擇器視圖將保持不變。

我嘗試的第一件事是覆蓋

- (BOOL)touchesShouldCancelInContentView:(UIView *)view

並且根本不允許UIScrollView取消選擇器視圖內的觸摸。 這有效,但它有一個令人不快的副作用。 您希望選擇器視圖立即響應,因此您必須將delaysContentTouches設置為NO。 問題是您不希望表視圖的其余部分立即響應,因為如果確實如此,表視圖單元將始終在滾動開始之前突出顯示幾毫秒。

我嘗試的第二件事是覆蓋

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

因為我已經讀過滾動視圖總是返回自己,所以它會“竊取”其子視圖中的觸摸,然后如果它們對滾動視圖不感興趣則將它們發送到子視圖。 但是,這不再適用。 UIScrollView的hitTest的默認實現:withEvent:實際上返回應該接收觸摸的子視圖。 相反,它使用手勢識別器來攔截觸摸。

所以我嘗試的第三件事就是實現我自己的手勢識別器,如果觸摸在選擇器視圖之外,則會導致失敗,否則會成功。 然后我將所有滾動視圖的手勢識別器設置為失敗,除非我的手勢識別器使用以下代碼失敗:

for (UIGestureRecognizer * gestureRecognizer in self.tableView.gestureRecognizers)
{
    [gestureRecognizer requireGestureRecognizerToFail:myRecognizer];
}

事實上這實際上是從滾動視圖中竊取了觸摸,但是拾取器視圖從未接收到它們。 所以我可能只是發送我的手勢識別器使用此代碼接收的所有觸摸:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    for (UITouch *touch in touches)
        [touch.view touchesBegan:touches withEvent:event];
}

以上代碼是簡化版。 我還確保視圖是一個選擇器視圖(或其中一個子視圖),並為上面提到的手勢識別器設置適當的狀態。 我也做了同樣的取消,結束和感動。 但是,選擇器視圖仍然沒有響應。

在回到我的日常工作之前,我還嘗試了最后一件事。 在我廣泛的谷歌搜索過程中,我讀到嵌套的UIScrollViews從3.x開始就神奇地工作了,所以我嘗試將我的選擇器視圖放在嵌套的UIScrollView中並在其上設置以下屬性:

scrollView.delaysContentTouches = NO;
scrollView.canCancelContentTouches = NO;

正如人們所期望的那樣,外部滾動視圖不會處理內部滾動視圖與處理選擇器視圖時的任何不同,因此內部滾動視圖沒有接收到觸摸。 我認為這是一個很長的鏡頭,但它很容易實現,所以我認為值得一試。

我所知道的是UIScrollView有一個名為UIScrollViewDelayedTouchesBeganGestureRecognizer的手勢識別器,它攔截觸摸並在150(?)ms后將它們發送到適當的子視圖。 我想我應該能夠寫一個類似的識別器,導致滾動視圖的默認識別器失敗,而不是延遲觸摸立即將它們發送到選擇器視圖。 因此,如果有人知道如何編寫這樣的識別器,請告訴我,如果您有任何其他問題的解決方案,那么您也非常歡迎。

感謝您閱讀整個問題,即使您不知道答案,您仍然可以提出問題,以便得到更多關注(希望能得到答案的人)。 謝謝! :)

有時你必須先問問題才能找到答案。 Dan Ray遇到了類似的問題,並用一個非常不同的解決方案解決了它。

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView* result = [super hitTest:point withEvent:event];

    if ([result.superview isKindOfClass:[UIPickerView class]])
    {
        self.scrollEnabled = NO;
    }
    else 
    {
        self.scrollEnabled = YES;    
    }
    return result;
}

我已經測試了代碼,它也適用於我。 然而,這並不是真正從滾動視圖中偷取的東西,所以如果有人知道如何實際竊取那些很棒的觸摸。

來源: UITableView.tableFooterView內的UIPickerView沒有接收拖動觸摸

有點晚了,但我找到了這個解決方案: http//www.cocoanetics.com/2010/06/hacking-uiscrollview-gesture-recognizers/適合我

我也參加了派對,但是對於新手來說,如果你只想在滾動視圖中忽略滑動,對我有用的是在視圖中添加一個平移手勢識別器,我想忽略滑動,如這個:

let panGesture = UIPanGestureRecognizer()
panGesture.cancelsTouchesInView = false
myView?.addGestureRecognizer(panGesture)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM