2013-05-02 12 views
17

Chciałbym przeciągnąć UIImage na jedno z kilku UButtonów i zmienić położenie na podstawie którego przycisku przeciągnęłam.Jak się dowiedzieć, na jakim widoku zakończyło się wydarzenie dotykowe?

Problem, na który się natknąłem, polega na tym, że UITouch zapisuje tylko widok, w którym rozpoczął się mój dotyk. Chciałbym uzyskać dostęp do widoku, na którym kończy się mój dotyk. Jak mogę to zrobić?

Kod:

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch *touch = [touches anyObject]; 
    CGPoint location = [touch locationInView:self.view]; 

    dealerBtnOrigin = [touch locationInView:self.view]; 

    //NSLog(@"%u %u",touch.view.tag, ((UIView *)[dealerBtns objectAtIndex:[table getButtonSeat]]).tag); 
    //CHECK TO SEE WHICH BUTTON WAS TOUCHED 
    if (touch.view == ((UIView *)[dealerBtns objectAtIndex:[table getButtonSeat]])) 
    { 
     ((UIView *)[dealerBtns objectAtIndex:[table getButtonSeat]]).center = location; 
    } 
} 

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch *touch = [touches anyObject]; 
    CGPoint location = [touch locationInView:self.view]; 


    if (touch.view == ((UIView *)[dealerBtns objectAtIndex:[table getButtonSeat]])) 
    { 
     ((UIView *)[dealerBtns objectAtIndex:[table getButtonSeat]]).center = location; 
    } 
} 

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch *touch = [touches anyObject]; 
    CGPoint location = [touch locationInView:self.view]; 
    UIView *endView = [self.view hitTest:location withEvent:nil]; 

    if (touch.view == ((UIView *)[dealerBtns objectAtIndex:[table getButtonSeat]])) 
    { 
     NSLog(@"%u %u",endView.tag, touch.view.tag); 
     if([buttons containsObject:(UIButton *)endView]) 
     { 
      [[dealerBtns objectAtIndex:[table getButtonSeat]] setHidden:YES]; 
      [table passButton:touch.view.tag]; 
      [[dealerBtns objectAtIndex: touch.view.tag] setHidden:NO]; 
     } 
     ((UIView *)[dealerBtns objectAtIndex:[table getButtonSeat]]).center = dealerBtnOrigin; 
    } 

} 
+0

Nie sądzę, żebym mógł skorzystać z ręcznego rozwiązania za pomocą współrzędnych CGPoint, aby dowiedzieć się, który przycisk jest używany, ponieważ używam wielu scenorysów dla różnych rozmiarów ekranu/urządzeń. – Deco

Odpowiedz

16

To jest bardzo łatwe do wykrycia swoją wreszcie dotknął widok, spróbuj tego kodu

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    CGPoint location = [[touches anyObject] locationInView:self.view]; 
    CGRect fingerRect = CGRectMake(location.x-5, location.y-5, 10, 10); 

    for(UIView *view in self.view.subviews){ 
     CGRect subviewFrame = view.frame; 

     if(CGRectIntersectsRect(fingerRect, subviewFrame)){ 
      //we found the finally touched view 
      NSLog(@"Yeah !, i found it %@",view); 
     } 

    } 

} 
+0

ten powrócił trzy widoki: * Moje aplikacje w tle obrazu * The UIButton przeciągnąłem przez małe UIImage do (widoku chcę) * Moja mała UIImage interesujące zobaczyć, jak to działa i prawdopodobnie wyjaśnia, dlaczego odpowiedź powyżej wstałem t działa dla mnie. Dzięki. – Deco

+0

Bardzo, bardzo ładne rozwiązanie, mam nadzieję, że dla Ciebie najlepsze :) – TMMDev

+1

Możesz użyć CGRectContainsPoint zamiast CGRectIntersectsRect dla dokładniejszego przecięcia. –

0

W ogóle, trzeba wziąć punkt, w którym akcent zakończył, i określić, czy leży to w widoku, który Cię interesuje. Robię to za pomocą kodu podobnego do następującego:

CGPoint newCenter = dragView.center; 
for (UIView *v in dropTargets) 
{ 
    CGRect convertedTargetFrame = [v.superview convertRect:v.frame toView:nil]; 
    if (CGRectContainsPoint(convertedTargetFrame, newCenter)) 
    { 
     activeTargetIndex = idx; 
    } 
} 

(ten kod był edytowany w locie, aby usunąć wiele nieistotnych rzeczy, ale zachowuję listę potencjalnych celów upuszczania w dropTargets, a to tylko patrzy na tę listę, aby zobaczyć, który z potencjalnych UIViews może zawierać punkt).

Istotne jest to, że jeśli znasz widok lub widoki, do których możesz potencjalnie przeciągnąć element, możesz określić, czy ramka tego widoku zawiera punkt za pomocą CGRectContainsPoint. Ważne jest, aby pamiętać, że mogą one leżeć w różnych układach współrzędnych i może być konieczne przejście z jednej na drugą przed porównaniem.

21

Użyj testu trafień. Znasz lokalizację tego punktu jako CGPoint pod kątem ostatecznego superview, self.view. Następnie można zapytać self.view które jego subviews że punkt znajduje się w:

CGPoint location = [touch locationInView:self.view]; 
UIView* v = [self.view hitTest:location withEvent:nil]; 

UIView v jest widok szukasz.

+0

Wrzuciłem to do mojego kodu (w dotkniętych dotknięciach przycisku) i nadal otrzymuję widok, od którego zaczyna się dotyk. Zaktualizowałem moje pytanie, by zawierało najsilniejsze. – Deco

+0

Po odrobinie eksperymentów wygląda na to, że widok, który jest zwracany, jest w rzeczywistości metodą UIImage, którą przeciągam, a nie oryginalnym UIButtonem (mają ten sam znacznik) lub przyciskiem, który przeciągam obraz do zamierzonego. – Deco

+1

Tak, bałem się, że to może się stać. Okay, wtedy prostym rozwiązaniem jest * przesłonięcie * 'hitTest: withEvent:' w 'self.view' tak, że gdy wykonujesz ten * szczególny * test trafień, nie zwraca on widoku, który przeciągasz (ty Będę musiał powiedzieć, który to jest). Następnie będzie kontynuował testowanie i zamiast tego zwróci widok za tym. – matt

0

Zakładając jest @property zdania docelowej w kontenerze, a widok cel jest dodawany do zbiornika:

@property (nonatomic, strong) UIView* targetView; 

// ... 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    NSSet* touchesForTargetView = [event touchesForView:self.targetView]; 
    if (touchesForTargetView.allObjects.count != 0) { 
     // touch was at target view 
    } 
    else { 
     // touch was somewhere else 
    }  
} 
0

Swift 4:

nadpisanie funkcjono touchesEnded (_ dotyka: Set, z wydarzeniem: UIEvent) {

if let touch = touches.first{ 
     let location = touch.location(in: self.view) 
     let v = touch.view 

// dalej .. }

} 
Powiązane problemy