2010-12-13 61 views
1

我正在構建一個iOS桌面遊戲(類似於拼字遊戲或單詞),涉及到在屏幕上移動小瓷磚,我發現用戶有時很難觸摸並移動瓷磚,因爲它們太小。由於遊戲的設計,我無法增加瓷磚的尺寸,所以我不得不實施一些小技巧,使用戶更容易觸摸和移動瓷磚,並且它們很好地工作。剩下的唯一問題是用戶有時只是在瓷磚外面接觸,當用戶試圖移動瓷磚時,瓷磚會停留在原來的位置。如何在iOS設備上以滑動手勢捕捉子視圖?

我有我如何可以解決此兩種想法......

  1. 如果當用戶觸摸屏幕瓷磚沒有感動,我可以使用父視圖的觸摸位置找到最接近的瓷磚到觸摸位置並以某種方式將觸摸事件轉發到該視圖的視圖。
  2. 如果在用戶觸摸屏幕時沒有觸摸平鋪,當用戶試圖移動平鋪時,我可以以某種方式「抓住」平鋪。

我更喜歡實施解決方案#2,因爲解決方案#1有太多問題,更不用說解決方案#2是一種更現實的體驗。也就是說,如果用戶在手指上方拖動手指併發送觸摸事件以將其移動到手指位置,我怎麼能「抓住」一個瓦片?

目前,我的貼圖是作爲UIView的子類實現的,它們直接處理觸摸事件(touchesBegain,touchesMoved和touchesEnded)。因此,如果用戶僅觸摸視圖外面並將其手指拖動到視圖上,則由於它沒有收到初始的touchesBegan事件,所以它不會收到任何觸摸事件。

在此先感謝您的所有智慧!

回答

4

也許你應該有「板子」視圖處理所有的拖動。當觸摸開始並且在那一刻有一個圖塊時,然後開始拖動它。否則,請檢查觸摸何時移動,只要找到一個圖塊,就開始拖動它。

您可以在棋盤視圖中覆蓋hitTest:withEvent:,以便它仍然可以檢測觸摸何時觸及棋盤,但始終返回自身,以便觸摸事件進入棋盤視圖(例如,記錄在單獨成員中擊中的子視圖變量,這樣你就可以知道什麼時候開始觸摸事件時纔開始拖動)。

更多詳細信息

在處理觸摸,UIView的將使用則hitTest發現應接收觸摸事件的看法。默認實現會檢查每個子視圖,以便層次結構中「最深」的子視圖可以觸及。爲了讓棋盤視圖接收觸摸,您必須在所有拼貼視圖上禁用userInteraction。但是這意味着你不能使用hitTest來查找被觸摸的圖塊,因爲它忽略了禁用userInteraction的視圖。

所以我說的是在觸摸視圖上啓用了leave userInteraction。但是在板子視圖上重寫hitTest,以便它首先調用超級實現來查找一個圖塊(如果結果爲self,板子本身被擊中)。無需執行自己的拼貼搜索。事情是這樣的:

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

現在你知道在touchesMoved移動什麼瓷磚。然而,我並不認爲hitTest是因爲觸摸被移動而被調用的,所以如果沒有拾取tile,您可能需要手動調用它(您可以將pointevent從觸摸傳遞到touchesMoved

+0

謝謝,布萊恩,這聽起來像這裏的正確方法。快速的問題,如果我重寫板視圖中的hitTest方法,我究竟想在它裏面做什麼?我是否想要遍歷所有的瓷磚並檢查命中點是否碰到任何瓷磚?如果是這樣,重寫hitTest方法有什麼意義呢,爲什麼我不能在棋盤的觸摸事件方法中檢查它(例如touchesBegan,touchesMoved等)? – BeachRunnerFred 2010-12-13 17:42:44

+0

更多的細節回答更多 – Brian 2010-12-13 18:19:33

+0

謝謝,布萊恩,這對我有很大的幫助。我會給它一個!另外,由於我的棋盤視圖包含其他類型的視圖,而不僅僅是拼貼,我假設我必須檢查從[super hitTest]調用返回的對象的類型,並確保它是拼貼視圖。我應該使用[hitView isKindOfClass:[TileView類]]爲此? – BeachRunnerFred 2010-12-13 18:33:20

1

你有沒有進去看了UIGestureRecognizer API我覺得你最好的辦法是增加一個UIPanGestureRecognizer識別到你的董事會的看法則這將還擊選擇您的UIViewController

設置在viewDidLoad中:

UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] 
                 initWithTarget:self action:@selector(handlePan:)]; 

[[self view] addGestureRecognizer:panGestureRecognizer]; 

然後執行t他選擇:

- (void)handlePan:(UIPanGestureRecognizer *)gestureRecognizer{ 
      CGPoint currentPoint = [gesture locationInView:[self view]]; 
    } 

當您設置了手勢識別器,你可以設置參數來限制回調(只認平底鍋1個手指等,並在回調可以檢查手勢特性,看看鍋繼續或者即將結束。您也可以抓取當前點並確定它是否在瓷磚中或附近。

+0

謝謝,cesarislaw。問題,你的解決方案的重點似乎在於:1)檢測平移手勢,2)獲取當前位置,以便我可以隨心所欲地做任何事情,是嗎?如果沒有,我很抱歉,我還是比較新的iOS。如果是這樣,爲什麼不使用touchesMoved事件方法來獲取這些信息呢?再次感謝! – BeachRunnerFred 2010-12-13 17:49:13

+0

我發現手勢提供了對反饋的更多控制,併爲我做了很多低級別的工作,使我可以專注於應用程序邏輯而不是觸摸檢測(這是一個水龍頭還是一個平底鍋?)等等。我的應用程序是一個繪圖應用程序需要驗證用戶是否按特定順序從一個區域移動到另一個區域。手勢是iOS4的新功能,所以如果您需要3.2或更高版本的兼容性,觸摸檢測是您唯一的選擇。 – cesarislaw 2010-12-13 18:37:32

+0

另外我依稀記得遇到一些觸碰事件有時會被其他視圖攔截而未傳遞的問題(我想說的UIScrollView對此尤其不好)。 – cesarislaw 2010-12-13 18:40:36

相關問題