2011-10-10 14 views
55

UIView, ekranın bir köşesine giren özel bir UIViewController sahibine sahibim, ancak bunun bir kısmı üzerinde bazı düğmeler ve nesneler olan kısımlar dışında saydamdır. Bu görünümdeki nesnelerin düzeni nedeniyle, görünümün çerçevesi onun altındaki bazı düğmeleri kapsayabilir. Önemli bir şeye dokunmuyorlarsa, o görünümdeki herhangi bir dokunuşları görmezden gelmek istiyorum, ancak sadece gerçek dokunma olaylarını (touchesEnded/nextResponder şeyleri) geçirebiliyorum. Bir UIButton'um veya touch'Ended kullanmayan bir şeye benziyorsam, dokunma olayını buna nasıl iletebilirim?Dokunma olaylarını göz ardı etmek ve başka bir alt görüntünün UIControl nesnelerine iletmek nasıl?

Bu özel ViewController pek çok farklı görünümde kullanılabileceğinden, düğmeyi çevirmek için yalnızca el ile ayarlayamıyorum. Temelde bu çağrı için bir yol gerekir: yanı UIControl türlerinde

[self.nextResponder touchesEnded:touches withEvent:event];

.

cevap

120

görünümde hitTest:withEvent: geçersiz kılmak için olduğunu size Dokunuşları görmezden gelmek ister. Görünüm hiyerarşinizin karmaşıklığına bağlı olarak, bunu yapmanın birkaç kolay yolu vardır.

sen görmezden görünümüne altına görünümüne başvuru varsa:

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

    // If the hitView is THIS view, return the view that you want to receive the touch instead: 
    if (hitView == self) { 
     return otherView; 
    } 
    // Else return the hitView (as it could be one of this view's buttons): 
    return hitView; 
} 

Eğer görünümüne başvuru yoksa:

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

    // If the hitView is THIS view, return nil and allow hitTest:withEvent: to 
    // continue traversing the hierarchy to find the underlying view. 
    if (hitView == self) { 
     return nil; 
    } 
    // Else return the hitView (as it could be one of this view's buttons): 
    return hitView; 
} 

Ben ilk yaklaşım öneriyoruz En sağlam olarak (altta yatan görünüme bir referans elde etmek mümkün ise).

+0

Yapmak istediğim gibi görünüyor, ancak dokunmalarını görmezden gelmek istediğim görünüm, oluşturduğum UIViewController'ın görünüm özelliğidir, bu yüzden bu görünümün hitTest işlevini geçersiz kılacak bir yol var mı? –

+4

@chris: Tabii, sadece alt sınıfı ve yukarıda gösterildiği gibi geçersiz kılın. İçinde çok az bir kodla asılı fazladan bir '.h 've' .m' dosyanız olacağı anlamına gelir, ancak işi yapacak. Ayrıca, geçit görünümü, araç takımınızda bulunması yararlı bir alt sınıftır. Görünüm denetleyiciniz bir 'nib' görünümü oluşturuyorsa, sadece IB dosyasına gidip görünümün sınıfını kimlik denetçisindeki yeni alt sınıfa dönüştürün. Program aracılığıyla oluşturulmuşsa, görünüm alt sınıfınızı 'loadView' içinde oluşturun ve atayın (düzenlemeye bakın). – Stuart

+0

Harika tavsiye! Bütün gün için iyi bir çözüm arıyordum. Teşekkürler. – Judioo

7

UITouch olaylarını nesneler arasında geçirmenin iyi bir yolunu bulamadım. Ne genellikle daha iyi çalışır hitTest uygulamak ve nokta bunu işlemek istediğiniz görünümde değilse nil döndürmektir: Bunu yapmanın en iyi yolu Muhtemelen

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

Bu eski bir sorudur ve aramaların başında gelir. Bu yüzden, durumunuz için daha iyi çalışabilecek başka bir çözüm yollayacağımı düşündüm. Benim durumumda bir etiketi başka bir etiketin üstüne sürüklemek istedim ve etiketin altını hitTest'te almak istedim. Yapılacak en basit şey, userInteractionEnabled değerini NO veya false olarak ayarlamaktır, sonra hitTest'inizi yapmak ve daha sonra yeniden taşımanız gerektiğinde tekrar ayarlamaktır.

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { 
    let touch = touches.first 
    let location = touch?.locationInView(self.view) 
    self.label1.userInteractionEnabled = false 
    let view = self.view.hitTest(location!, withEvent: nil) as? UILabel 
    print(view?.text) 
    self.label1.userInteractionEnabled = true 
} 
+0

Çözüm için teşekkürler. – Hiren

+0

Bu işe yaramaz çünkü label1.userInteractionEnabled öğesini false olarak ayarladığınızda etiket1 daha sonra dokunuşları algılamayacaktır. –

+0

@FredA. Bu yüzden şunu yazdım: "... ve tekrar harekete geçmeniz gerekiyorsa tekrar geri getirin". Belki yeterince açık değildim? – smileBot

8

Swift cevap::

Sen IgnoreTouchView bir UIView alt sınıfı oluşturabilirsiniz İşte Swift bir kod örneği. Söz konusu UIView için, true UserInteractionEnabled ayarlamalısınız

class IgnoreTouchView : UIView { 
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { 
     let hitView = super.hitTest(point, with: event) 
     if hitView == self { 
      return nil 
     } 
     return hitView 
    } 
} 

Not: Bir storyboard olarak, VC bakış (ler) dokunuşlar geçmesine istediğiniz üzerinde ayarlayın!

Bu zaman ana kaydırma önler (veya diğer etkileşimleri önlemek için değiştirilebilir) ... Ben karmaşık dokunmatik müdahale ile UIControl vardı, ama bir kaydırma görünümünde gömüldüğünde komik hareket:

+0

Kevin, en son Swift sürümüne Nisan2017'de birkaç karakter düzenledim. (Değiştirmek için çekinmeyin vs.) Şerefe – Fattie

0

Sorunum benzerdi alt görünümü aktif bir dokunma hareketine sahiptir.

Çözümümün:

alt görünümde didBeginInteraction ve didEndInteraction için bir temsilci protokolünü oluşturun. touchesBegan

den

Çağrı delegate.didBeginInteraction

Çağrı touchesEnded gelen delegate.didEndInteraction ve ana kontrol birimi,

touchesCancelled uygulamak didBegin ve didEnd protokolü, set temsilci

sonra NO = scrollView.scrollEnabled ayarlamak didBegin, scrollEnabled = Evet.

Bu sorunun, sorulan sorudan biraz farklı kullanım durumu olan birine yardımcı olmasını umarız!

İlgili konular