Başka bir UIView altında bir UIView ile etkileşime izin verme


115

Bir UIView'de başka bir UIView altında bulunan bir düğmeyle etkileşime izin vermenin basit bir yolu var mı?

Örneğin, şu anda ekranın üstünde bir nesne ve ekranın altında bir nesne olan ve ortasında hiçbir şey olmayan bir UIView (A) var. Bu, ortasında (B) düğmeleri olan başka bir UIView'ın üstüne oturur. Ancak, B.'nin ortasındaki düğmelerle etkileşim kuramıyorum.

B'de düğmeleri görebiliyorum - A'nın arka planını clearColor olarak ayarladım - ancak B'deki düğmeler, aslında bu düğmelerin üstünde A'dan herhangi bir nesne olmamasına rağmen dokunuş almıyor gibi görünüyor.

DÜZENLE - Yine de üst UIV görünümündeki nesnelerle etkileşimde bulunabilmek istiyorum

Elbette bunu yapmanın basit bir yolu var mı?


2
Hemen hemen hepsi burada açıklanmıştır: developer.apple.com/iphone/library/documentation/iPhone/… Ama temelde hitTest'i geçersiz kılın: withEvent:, hatta bir kod örneği bile sağlarlar.
nash

Bunun için küçük bir sınıf yazdım. (Cevaplara bir örnek eklendi). Buradaki çözüm, kabul edilen yanıttan biraz daha iyi çünkü UIButtonyarı saydam altındaki a'ya hala tıklayabilirken , şeffaf UIViewolmayan kısmı UIViewdokunma olaylarına yanıt verecektir.
Segev

Yanıtlar:


97

Üstten görünümünüz için bir UIView alt sınıfı oluşturmalı ve aşağıdaki yöntemi geçersiz kılmalısınız:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    // UIView will be "transparent" for touch events if we return NO
    return (point.y < MIDDLE_Y1 || point.y > MIDDLE_Y2);
}

Ayrıca hitTest: event: method'a da bakabilirsiniz.


19
Middle_y1 / y2 burada neyi temsil ediyor?
Jason Renaldo

Bu returnifadenin ne yaptığından emin değilim , ama return CGRectContainsPoint(eachSubview.frame, point)benim için çalışıyor. Aksi takdirde son derece yararlı cevap
n00neimp0rtant

MIDDLE_Y1 / Y2 işi sadece bir örnektir. Bu işlev, MIDDLE_Y1<=y<=MIDDLE_Y2bölgedeki dokunma olayları için "şeffaf" olacaktır .
gyim

41

Buradaki cevapların çoğu işe yarayacak olsa da, en uygun, genel ve kusursuz cevabın burada verilmediğini görünce biraz şaşırdım. @ Ash en yakın geldi, ancak süpervizyona dönerken garip bir şeyler oluyor ... bunu yapma.

Bu cevap, burada benzer bir soruya verdiğim cevaptan alınmıştır .

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

[super hitTest:point withEvent:event]dokunulan o görünümün hiyerarşisindeki en derin görünümü döndürür. Eğer hitView == self(yani temas noktasının altında alt nilgörünüm yoksa ), bu görünümün dokunmayı almaması gerektiğini belirterek geri dönün . Yanıtlayıcı zincirinin çalışma şekli, bu noktanın üzerindeki görünüm hiyerarşisinin, dokunmaya yanıt verecek bir görünüm bulunana kadar geçilmeye devam edeceği anlamına gelir.Etmeyin onun Superview dokunuşlar veya olmasın kabul edip, etmemeye Bu görüşe kadar olmadığı için, Superview dönüş!

Bu çözüm:

  • uygun , çünkü diğer görünümlere / alt görünümlere / nesnelere referans gerektirmez;
  • genel , çünkü yalnızca dokunulabilir alt görünümler için bir kapsayıcı görevi gören herhangi bir görünüm için geçerlidir ve alt görünümlerin yapılandırması, çalışma şeklini etkilemez ( pointInside:withEvent:belirli bir dokunulabilir alanı geri döndürmek için geçersiz kılmanız durumunda olduğu gibi ).
  • kusursuz , çok fazla kod yok ... ve kavramın kafanızı karıştırması zor değil.

Bunu, bir geçersiz kılma için anlamsız görünüm alt sınıflarını kaydetmek için bir alt sınıfa soyutlayacak kadar sık ​​kullanıyorum. Bonus olarak, yapılandırılabilir hale getirmek için bir mülk ekleyin:

@interface ISView : UIView
@property(nonatomic, assign) BOOL onlyRespondToTouchesInSubviews;
@end

@implementation ISView
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *hitView = [super hitTest:point withEvent:event];
    if (hitView == self && onlyRespondToTouchesInSubviews) return nil;
    return hitView;
}
@end

O zaman vahşileşin ve bu manzarayı ovayı kullandığınız her yerde kullanın UIView. Bunu yapılandırılması ayarlama gibi basit gibidir onlyRespondToTouchesInSubviewsiçin YES.


2
Tek doğru cevap. Açık olmak gerekirse , bir görünüme yapılan dokunuşları görmezden gelmek istiyorsanız , ancak görünümde bulunan herhangi bir düğmeyi (diyelim ki) yok saymak istiyorsanız , Stuart'ın açıkladığı gibi yapın. (Ben genellikle buna "sahip görünümü" diyorum çünkü bazı düğmeleri zararsız bir şekilde "tutabilir", ancak tutucunun "altındaki" hiçbir şeyi etkilemez.)
Şişko

UITableView og UICollectionView gibi görünümünüz kaydırılabilirse ve yukarı veya aşağı kaydırdıysanız, noktaları kullanan diğer çözümlerden bazıları sorun yaşar. Ancak bu çözüm, kaydırmadan bağımsız olarak çalışır.
pajevic

31

Bununla başa çıkmanın birkaç yolu var. Benim favorim hitTest: withEvent'i geçersiz kılmaktır: çelişen görünümlere (belki de dolaylı olarak) ortak bir denetim görünümü olan bir görünümde (bunlara A ve B dediğiniz gibi geliyor). Örneğin, şuna benzer bir şey (burada A ve B, UIView işaretçileridir; burada B, normalde göz ardı edilen "gizli" dir):

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    CGPoint pointInB = [B convertPoint:point fromView:self];

    if ([B pointInside:pointInB withEvent:event])
        return B;

    return [super hitTest:point withEvent:event];
}

pointInside:withEvent:Yöntemi gyim'in önerdiği şekilde de değiştirebilirsiniz . Bu, en azından dokunuşlar için, A'da etkili bir şekilde "bir delik açarak" esasen aynı sonucu elde etmenizi sağlar.

Diğer bir yaklaşım olay iletmedir, bu da bazı dokunuşları ilk gittikleri yerden farklı bir nesneye göndermek için geçersiz kılma touchesBegan:withEvent:ve benzer yöntemler ( touchesMoved:withEvent:vb.) Anlamına gelir . Örneğin, A'da şöyle bir şey yazabilirsiniz:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if ([self shouldForwardTouches:touches]) {
        [B touchesBegan:touches withEvent:event];
    }
    else {
        // Do whatever A does with touches.
    }
}

Ancak, bu her zaman beklediğiniz gibi çalışmayacaktır ! Önemli olan, UIButton gibi yerleşik kontrollerin her zaman iletilen dokunuşları göz ardı etmesidir. Bu nedenle ilk yaklaşım daha güvenilirdir.

Tüm bunları daha ayrıntılı olarak açıklayan iyi bir blog yazısı ve fikirleri tanıtmak için çalışan küçük bir xcode projesi var, burada mevcut:

http://bynomial.com/blog/?p=74


Bu çözümle ilgili sorun - ortak denetim görünümünde hitTest'i geçersiz kılmak - alttaki görünüm bir bütün kaydırılabilir görünümlerden biri olduğunda (MapView vb.) Alttaki görünümün tamamen doğru çalışmasına izin vermemesidir. Yukarıdaki gyim tarafından önerildiği gibi üst görünümün içinde, söyleyebildiğim kadarıyla her durumda çalışır.
delany

@delany, Bu doğru değil; diğer görünümlerin altında oturan kaydırılabilir görünümlere sahip olabilir ve hitTest'i geçersiz kılarak ikisinin de çalışmasını sağlayabilirsiniz. İşte bazı örnek kodlar: bynomial.com/blogfiles/Temp32.zip
Tyler

Hey. Tüm kaydırılabilir görünümler değil - sadece bazıları ... Posta kodunuzu yukarıdan denedim, UIScrollView'ı (örneğin) MKMapView olarak değiştirdim ve çalışmıyor. Dokunmalar işe yarıyor - sorun görünen kaydırma işlemidir.
delany

Tamam, kontrol ettim ve hitTest'in MKMapView ile istediğiniz şekilde çalışmadığını onayladım. Bu konuda haklıydın @delany; UIScrollView ile doğru çalışmasına rağmen. MKMapView'ın neden başarısız olduğunu merak ediyorum?
Tyler

@Tyler Bahsettiğiniz gibi, "Asıl mesele UIButton gibi yerleşik kontrollerin her zaman iletilen dokunuşları görmezden gelmesidir", bunu nasıl bildiğinizi ve bu davranışı açıklamanın resmi bir belge olup olmadığını bilmek istiyorum. UIButton düz bir UIView alt görünümüne sahip olduğunda, alt görünümün sınırları içindeki dokunma olaylarına yanıt vermeyeceği bir sorunla karşılaştım. Ve olayın UIView'ın varsayılan davranışı olarak UIButton'a doğru bir şekilde iletildiğini buldum, ancak bunun belirlenmiş bir özellik veya sadece bir hata olduğundan emin değilim. Lütfen bana bununla ilgili belgeleri gösterir misiniz? Çok teşekkür ederim içtenlikle.
Neal.Marlin

29

Ayarlamalısınız upperView.userInteractionEnabled = NO;, aksi takdirde üst görünüm dokunuşları keser.

Bunun Arayüz Oluşturucu sürümü, Nitelikleri Görüntüle panelinin altında "Kullanıcı Etkileşimi Etkin" adlı bir onay kutusudur. İşaretini kaldırın ve gitmeniz iyi olur.


Üzgünüm - söylemeliydim. Yine de üst UIView'deki nesnelerle etkileşim kurabilmek istiyorum.
delany

Ancak üst Görünüm herhangi bir dokunuş alamaz, düğmeyi üst Görünüme dahil edin.
imcaptor

2
Bu çözüm benim için çalışıyor. Dokunuşlara hiç tepki vermek için üst görünüme ihtiyacım yoktu.
TJ

11

PointInside: withEvent'in özel uygulaması gerçekten de gidilecek yol gibi görünüyordu, ancak sabit kodlanmış koordinatlarla uğraşmak bana tuhaf geldi. Bu yüzden, CGRectContainsPoint () işlevini kullanarak CGPoint'in CGRect düğmesinin içinde olup olmadığını kontrol ettim:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    return (CGRectContainsPoint(disclosureButton.frame, point));
}

8

Son zamanlarda bana yardımcı olacak bir ders yazdım. Bunu bir için özel bir sınıf olarak kullanmak UIButtonveya UIViewsaydam bir piksel üzerinde yürütülen dokunma olaylarını geçecektir.

Bu çözüm, kabul edilen yanıttan biraz daha iyidir, çünkü UIButtonyarı saydam altındaki a'yı hala tıklayabilirken , şeffaf UIViewolmayan kısmı UIViewdokunma olaylarına yanıt verecektir.

GIF

GIF'te de görebileceğiniz gibi, Zürafa düğmesi basit bir dikdörtgendir ancak şeffaf alanlardaki dokunma olayları alttaki sarıya aktarılır UIButton.

Sınıfa bağla


2
Kodunuz o kadar uzun olmadığı için, projenizin ileride bir noktada taşınması veya kaldırılması ihtimaline karşı cevabınıza ilgili kısımlarını eklemelisiniz.
Gavin

Teşekkürler, çözümünüz, dokunma olaylarına yanıt vermek için UIView'umun şeffaf olmayan kısmına ihtiyaç duyduğum durumum için işe yarıyor, ancak şeffaf kısım yok. Parlak!
Bruce

@Bruce Sana yardım ettiğine sevindim!
Segev

4

Sanırım bu partiye biraz geç kaldım, ancak bu olası çözümü ekleyeceğim:

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

Özel bir UIView standart hitTest işlevini geçersiz kılmak için bu kodu kullanırsanız, YALNIZCA görünümün kendisini yok sayar. Bu görünümün tüm alt görünümleri, isabetlerini normal şekilde döndürür ve görünümün kendisine gidecek tüm isabetler, gözetim görünümüne geçer.

-Kül


1
Bu benim tercih ettiğim yöntem, ancak geri dönmen gerektiğini düşünmüyorum [self superview]. bu yöntemle ilgili dokümantasyon durumu "Belirli bir noktayı içeren görünüm hiyerarşisinde alıcının en uzak neslini döndürür (kendisi dahil)" ve "Nokta, alıcının görüş hiyerarşisinin tamamen dışındaysa sıfır döndürür". geri dönmen gerektiğini düşünüyorum nil. sıfır döndüğünüzde, herhangi bir isabet olup olmadığını kontrol etmek için denetim süpervizöre geçecektir. yani temelde aynı şeyi yapacak, ancak süpervizyona geri dönmenin gelecekte bir şeyleri bozması dışında.
jasongregori

Elbette, bu muhtemelen akıllıca olacaktır (orijinal cevabımın tarihini not edin - o zamandan beri çok daha fazla kodlama yaptım)
Ash

4

Sadece Kabul Edilen Cevabı kısaltmak ve bunu referansım için buraya koymak. Kabul Edilen Cevap mükemmel çalışıyor. Görünümünüzün alt görünümlerinin dokunuşu almasına veya arkamızdaki herhangi bir görüntüye aktarmasına izin vermek için bunu şu şekilde genişletebilirsiniz:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    // If one of our subviews wants it, return YES
    for (UIView *subview in self.subviews) {
        CGPoint pointInSubview = [subview convertPoint:point fromView:self];
        if ([subview pointInside:pointInSubview withEvent:event]) {
            return YES;
        }
    }
    // otherwise return NO, as if userInteractionEnabled were NO
    return NO;
}

Not: Alt görünüm ağacında özyineleme yapmak zorunda bile değilsiniz, çünkü her pointInside:withEvent:yöntem bunu sizin için halledecektir.


3

UserInteraction özelliğini devre dışı bırakmak yardımcı olabilir. Örneğin:

UIView * topView = [[TOPView alloc] initWithFrame:[self bounds]];
[self addSubview:topView];
[topView setUserInteractionEnabled:NO];

(Not: Yukarıdaki kodda, 'kendi' bir görünümü ifade eder)

Bu şekilde, yalnızca topView'da görüntüleyebilirsiniz, ancak kullanıcı girdilerini alamazsınız. Tüm bu kullanıcı dokunuşları bu görünümden geçecek ve alt görünüm onlara yanıt verecektir. Bu topView'ı saydam resimleri görüntülemek veya onları canlandırmak için kullanırdım.


3

Bu yaklaşım oldukça temiz ve şeffaf alt görünümlerin de dokunuşlara tepki vermemesini sağlıyor . Sadece alt sınıflara ayırın UIViewve uygulamasına aşağıdaki yöntemi ekleyin:

@implementation PassThroughUIView

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    for (UIView *v in self.subviews) {
        CGPoint localPoint = [v convertPoint:point fromView:self];
        if (v.alpha > 0.01 && ![v isHidden] && v.userInteractionEnabled && [v pointInside:localPoint withEvent:event])
            return YES;
    }
    return NO;
}

@end

2

Buradaki çözümüm:

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    CGPoint pointInView = [self.toolkitController.toolbar convertPoint:point fromView:self];

    if ([self.toolkitController.toolbar pointInside:pointInView withEvent:event]) {
       self.userInteractionEnabled = YES;
    } else {
       self.userInteractionEnabled = NO;
    }

    return [super hitTest:point withEvent:event];
}

Bu yardımcı olur umarım


2

Her iki görünümde de dokunuşu kesmek için yapabileceğiniz bir şey var.

Üstten görünüm:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   // Do code in the top view
   [bottomView touchesBegan:touches withEvent:event]; // And pass them on to bottomView
   // You have to implement the code for touchesBegan, touchesEnded, touchesCancelled in top/bottom view.
}

Ama fikir bu.


Bu kesinlikle mümkün - ancak çok fazla iş var (alt katmanda kendi dokunmaya duyarlı nesnelerinizi (örneğin düğmeler) yuvarlamanız gerekecek, sanırım?) sezgisel görünen davranışları elde etmenin bir yolu.
delany

Emin değilim, belki de denemeliyiz.
Alexandre Cassagne

2

İşte bir Swift versiyonu:

override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
    return !CGRectContainsPoint(buttonView.frame, point)
}

2

Hızlı 3

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
    for subview in subviews {
        if subview.frame.contains(point) {
            return true
        }
    }
    return false
}

1

UI araç setini kullanarak hiçbir zaman eksiksiz bir kullanıcı arayüzü oluşturmadım, bu yüzden bu konuda fazla deneyimim yok. İşte yine de çalışması gerektiğini düşündüğüm şey.

Her UIView ve bu UIWindow, subviewstüm alt görünümleri içeren bir NSArray olan bir özelliğe sahiptir .

Bir görünüme eklediğiniz ilk alt görünüm, 0 dizinini ve sonraki dizin 1'i vb. Alacaktır. Ayrıca değiştirebilir addSubview:ile insertSubview: atIndex:veyainsertSubview:aboveSubview: hiyerarşisinde subview konumunu belirleyebilir gibi yöntemlere ve.

Bu nedenle, UIWindow'unuza ilk olarak hangi görünümü eklediğinizi görmek için kodunuzu kontrol edin. Bu 0, diğeri 1 olacak.
Şimdi, alt görünümlerinizden birinden diğerine ulaşmak için aşağıdakileri yaparsınız:

UIView * theOtherView = [[[self superview] subviews] objectAtIndex: 0];
// or using the properties syntax
UIView * theOtherView = [self.superview.subviews objectAtIndex:0];

Bunun sizin durumunuz için işe yarayıp yaramadığını bana bildirin!


(bu işaretin altında önceki cevabım var):

Görünümlerin birbirleriyle iletişim kurması gerekiyorsa, bunu bir denetleyici aracılığıyla (yani popüler MVC modelini kullanarak ) yapmaları gerekir .

Yeni bir görünüm oluşturduğunuzda, kendisini bir denetleyiciye kaydettirdiğinden emin olabilirsiniz.

Dolayısıyla teknik, görünümlerinizin bir denetleyiciye kaydedildiğinden emin olmaktır (bu, onları ada göre veya bir Sözlük veya Dizide tercih ettiğiniz her şeyi saklayabilir). Ya kontrolörün sizin için bir mesaj göndermesini sağlayabilirsiniz ya da görünüme bir referans alıp doğrudan onunla iletişim kurabilirsiniz.

Görünümünüzde denetleyiciye bir bağlantı yoksa (durum böyle olabilir) , denetleyicinize bir referans almak için tekli ve / veya sınıf yöntemlerinden yararlanabilirsiniz.


Cevabınız için teşekkürler - ama anladığımdan emin değilim. Her iki görünümün de bir denetleyicisi vardır - sorun şu ki, bir görünüm diğerinin üstünde olduğunda, alttaki görünüm olayları toplamıyor (ve bunları denetleyicisine iletmiyor), bu olayları gerçekte bu olayları 'bloke eden' bir nesne olmasa bile üstten görünüm.
delany

UIV Görünümlerimizin tepesinde bir UIWindow'unuz var mı? Bunu yaparsanız, olaylar yayılmalıdır ve herhangi bir "sihir" yapmanıza gerek kalmaz. Apple Dev Center'da [Pencere ve Görünümler] [1] hakkında bir şeyler okuyun (ve bu size yardımcı olmazsa kesinlikle başka bir yorum ekleyin!) [1]: developer.apple.com/iphone/library/documentation/ iPhone /…
nash

Evet, kesinlikle - hiyerarşinin tepesinde bir UIWindow.
delany

Cevabımı, bir görünümler hiyerarşisinden geçme kodunu içerecek şekilde güncelledim. Başka yardıma ihtiyacınız olursa bana bildirin!
nash

Yardımınız için teşekkürler nash - ama bu arayüzleri oluşturma konusunda oldukça tecrübeliyim ve şu anki arayüzüm bildiğim kadarıyla doğru bir şekilde kuruldu. Sorun, diğerlerinin üzerine yerleştirildiklerinde tam görünümlerin varsayılan davranışı gibi görünüyor.
delany

1

Bence doğru yol, görünüm hiyerarşisine yerleştirilmiş görünüm zincirini kullanmaktır. Ana görünüme gönderilen alt görünümleriniz için genel UIView kullanmayın, bunun yerine MYView: UIView (veya UIImageView gibi istediğiniz süper türü) yapmak için UIView (veya UIImageView gibi varyantlarından birini) alt sınıfını kullanın. YourView uygulamasında touchesBegan yöntemini uygulayın. Daha sonra bu görünüme dokunulduğunda bu yöntem çağrılacaktır. Bu uygulamada sahip olmanız gereken tek şey bir örnek yöntemidir:

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event ;
{   // cannot handle this event. pass off to super
    [self.superview touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event]; }

this touchesBegan bir yanıtlayıcı api'sidir, bu nedenle bunu genel veya özel arayüzünüzde bildirmenize gerek yoktur; Bilmen gereken şu sihirli api'lerden biri. Bu self.superview, isteği sonunda viewController'a gönderecektir. ViewController'da, dokunmayı işlemek için bu touchesBegan'ı uygulayın.

Dokunma konumunun (CGPoint), görünüm hiyerarşi zincirinde yukarı çıkarken sizin için çevreleyen görünüme göre otomatik olarak ayarlandığını unutmayın.


1

Sadece bunu göndermek istiyorum, çünkü biraz benzer bir problemim vardı, burada cevapları burada şanssız uygulamaya çalışmak için önemli miktarda zaman harcadım. Ne yaptım:

 for(UIGestureRecognizer *recognizer in topView.gestureRecognizers)
 {
     recognizer.delegate=self;
     [bottomView addGestureRecognizer:recognizer];   
 }
 topView.abView.userInteractionEnabled=NO; 

ve uygulama UIGestureRecognizerDelegate:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

Alttan görünüm, çok sayıda segmenti olan bir gezinme denetleyicisiydi ve üzerinde pan hareketiyle kapanabilen bir tür kapı vardı. Her şey başka bir VC'ye gömüldü. Bir cazibe gibi çalıştı. Bu yardımcı olur umarım.


1

HitTest tabanlı çözüm için Swift 4 Uygulaması

let hitView = super.hitTest(point, with: event)
if hitView == self { return nil }
return hitView

0

Stuart'ın mükemmel ve çoğunlukla kusursuz cevabından ve Segev'in yararlı uygulamasından türetilen işte, herhangi bir projeye dahil edebileceğiniz bir Swift 4 paketi:

extension UIColor {
    static func colorOfPoint(point:CGPoint, in view: UIView) -> UIColor {

        var pixel: [CUnsignedChar] = [0, 0, 0, 0]

        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)

        let context = CGContext(data: &pixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)

        context!.translateBy(x: -point.x, y: -point.y)

        view.layer.render(in: context!)

        let red: CGFloat   = CGFloat(pixel[0]) / 255.0
        let green: CGFloat = CGFloat(pixel[1]) / 255.0
        let blue: CGFloat  = CGFloat(pixel[2]) / 255.0
        let alpha: CGFloat = CGFloat(pixel[3]) / 255.0

        let color = UIColor(red:red, green: green, blue:blue, alpha:alpha)

        return color
    }
}

Ve sonra hitTest ile:

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    guard UIColor.colorOfPoint(point: point, in: self).cgColor.alpha > 0 else { return nil }
    return super.hitTest(point, with: event)
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.