2011-01-07 19 views
18

Fare konumunun bir NSView öğesinin içinde olup olmadığını bulmam gerekiyor.Fare, görünümün üstündeyse nasıl bulunur

NSPointInRect(point, rect) kullanırım, ancak rect koordinatlarını ekran koordinatlarına dönüştürmem gerekir ve nasıl yapacağımı bilmiyorum. Herhangi bir yardım çok takdir edilecektir! Böyle

+0

Bize bir neden verebilir misiniz? Genel olarak bu teknik harika bir fikir değildir, ancak yazdıklarınızı bilmeden söylemek zor. –

cevap

22

kullanımı NSView en convertPoint: fromView: yöntem nil olarak fromView pencere bir noktaya gizli bir görünümün koordinat sistemine koordine eder. inRect: Eski da koordinat sistemleri çevrilmiş hesapları olarak yerine NSPointInRect arasında yöntem

görünümün koordinat sistemine fare noktası dönüştürme sonra NSView en fare kullanmak.

Alternatif olarak, Tracking Area Object'u kullanabilirsiniz.

+1

NSTrackingArea, tam olarak ne aradığım oldu! Teşekkür ederim! –

+1

Bunu bağlıyorum ... ama convertPoint işlevi aslında ilk parametresi olarak bir NSPoint nesnesini ister. Ne vermeliyim. lütfen açıklayınız. –

+2

NSView'in faresindeki 'NSRect' argümanı için' self.bounds' 'u geçmeniz gerektiğini eklemek istiyorum: inRect: '' self.frame''i göndermek koordinatları dengeleyecektir. – ColdSteel

33

şey sizin için çalışması gerekir:

NSView* myView; // The view you are converting coordinates to 
NSPoint globalLocation = [ NSEvent mouseLocation ]; 
NSPoint windowLocation = [ [ myView window ] convertScreenToBase: globalLocation ]; 
NSPoint viewLocation = [ myView convertPoint: windowLocation fromView: nil ]; 
if(NSPointInRect(viewLocation, [ myView bounds ])) { 
    // Do your thing here 
} 

Ben şahsen bu birçok yerel değişkenleri kullanabilir yok ama umarım bu bu örnek daha anlaşılır kılmak.

+0

NSEvent zaten bir [olayı locationInWindow] var, bu nedenle ilk 3 satır gereksiz –

+1

locationInWindow büyük olasılıkla çoğu zaman çalışır. Ancak bu Apple belgelerinden: "NSMouseMoved ve muhtemelen diğer olaylar ile, alıcı bir nil pencere olabilir (yani, pencere döndürür nil). Bu durumda, locationInWindow ekran konumunu ekran koordinatlarına döndürür." Dolayısıyla, locationInWindow'a güvenmemek daha sağlam olabilir.Zaten bir etkinlik geçirdiyseniz, locationInWindow kesinlikle kullanılacak. Cevabımdaki yöntem zaten bir etkinlik nesnesine sahip olmasanız bile işe yarayacaktır. –

5

fare yararlanarak bazı kod: inRect: (önerilen yöntem; çevrilmiş koordinatlar için hesaplar) bu cevapların

CGPoint point = [self convertPoint:[event locationInWindow] fromView:nil]; 
CGRect rect = [self bounds]; 
if ([self mouse:point inRect:rect]) { 
} 
1

Yok bir görünüm dikdörtgen olmayabileceğini dikkate almak.

Dikdörtgen olmayan görünümlerde de çalışan evrensel bir yöntem. Watch-face veya karmaşık bir yol şekli düşünün.

Bu kod parçacığı size bir globalPoint'ten (globalToLocal) bir localPoint verecektir. (0,01 pencere boşluğunda GlobalPoint) Argümanı "toView" olarak değiştirirseniz, "localToGlobal" noktası alırsınız.

let localPoint = convertPoint(aPoint, fromView: self.window?.contentView)  

Nokta yolun içinde olsaydı ya da olmasaydı, körük doğru ya da yanlış geri dönecekti.

CGPathContainsPoint(someCGPath,nil,localPoint,true)

NOT:

(self.window?.mouseLocationOutsideOfEventStream)! 

NOT: daha doğru da olabilir Apoint hitTest parametre türetilmiş bir globalPoint, aynı zamanda elde edilebilir Bunu yapmanın yolu. Ama bu işe yarıyor ve ters çevrilmiş görüşlere önem vermiyor.

+0

Yukarıda açıklanan yaklaşımda bile hala tuzaklar var. Örneğin, bir NSViews hiyerarşisinde TextField'ı vurmak için temiz bir çözüm bulma konusunda çok fazla sorun yaşadım. Elma, taktikleri değiştiğinde textField'ı seçtiğinde de benimsemelisiniz. Bu çalışmayı ve onun oldukça temizliğini elde etmenin bir yolunu buldum. Bununla birlikte, muhtemelen her bir hitTestPoint'i hiyerarşideki her görünümde saygısız ve dengelenmeye başlar, çünkü bu, elmanın bileşenleri ile yaptığı gibi görünür. Sadece kullandığım her View sınıfında yer alan bir yönteme ekleyin. – eonist

+0

Bu çok "dağınık" bir makaledir, ancak denememek için size biraz bilgi verebilir. http://stylekit.org/blog/2016/01/28/Hit-testing-sub-views/ (temelde hitTesting araştırmasından aldığı tüm notlarım) Üstelik, hitTesting söz konusu olduğunda taşındı ve temiz bir iş akışına sahip oldum. – eonist

İlgili konular