2015-02-11 11 views
17

Chcę utworzyć widok, który wygląda tak: Goal ViewJak utworzyć UIView z przezroczystym kółkiem wewnątrz (w szybkim)?

mogę zrozumieć, co potrzebne jest UIView z pewnego rodzaju maski, mogę zrobić maskę w kształcie koła z wykorzystaniem UIBezierpath, jednak nie mogę Odwróć to sprawia, że ​​maskuje wszystko oprócz koła. Potrzebuję tego jako maski widoku, a nie warstwy wypełnienia, ponieważ widok, który zamierzam maskować, ma na sobie efekt UIBlurEffect. Celem końcowym jest animacja tego UIView na szczycie moich istniejących widoków w celu zapewnienia instrukcji.

Należy pamiętać, że używam szybkiego. Czy jest gdzieś to zrobić? Jeśli tak to jak?

+0

Wygląda duplikat http : //stackoverflow.com/questions/6867300/core-graphics-how-to-draw-a-rectangle-with-an-ellipse-transparency-hole –

Odpowiedz

36

Możesz użyć tej funkcji, aby stworzyć to, czego potrzebujesz.

func createOverlay(frame : CGRect) 
{ 
    let overlayView = UIView(frame: frame) 
    overlayView.alpha = 0.6 
    overlayView.backgroundColor = UIColor.blackColor() 
    self.view.addSubview(overlayView) 

    let maskLayer = CAShapeLayer() 

    // Create a path with the rectangle in it. 
    var path = CGPathCreateMutable() 

    let radius : CGFloat = 50.0 
    let xOffset : CGFloat = 10 
    let yOffset : CGFloat = 10 

    CGPathAddArc(path, nil, overlayView.frame.width - radius/2 - xOffset, yOffset, radius, 0.0, 2 * 3.14, false) 
    CGPathAddRect(path, nil, CGRectMake(0, 0, overlayView.frame.width, overlayView.frame.height)) 


    maskLayer.backgroundColor = UIColor.blackColor().CGColor 

    maskLayer.path = path; 
    maskLayer.fillRule = kCAFillRuleEvenOdd 

    // Release the path since it's not covered by ARC. 
    overlayView.layer.mask = maskLayer 
    overlayView.clipsToBounds = true 
} 

Regulacja radius i xOffset i yOffset zmienić promień i położenia koła.

+1

Witaj Rakesh! Twoje rozwiązanie było bardzo pomocne. Mam jedno małe wątpliwości. Mam przycisk poniżej tego zamaskowanego czarnego widoku. Zrobiłem przezroczysty prostokąt nad przyciskiem, tak jak w powyższym rozwiązaniu. Ale ponieważ ten czarny widok jest na górze, nie mogę dotknąć przycisku. Czy jest jakiś sposób, aby kliknąć przycisk? – Abhishek729

14

Dla Swift 3, oto odpowiedź rakeshbs' sformatowane tak zwraca UIView potrzebne:

func createOverlay(frame : CGRect, xOffset: CGFloat, yOffset: CGFloat, radius: CGFloat) -> UIView 
{ 
    let overlayView = UIView(frame: frame) 
    overlayView.alpha = 0.6 
    overlayView.backgroundColor = UIColor.black 

    // Create a path with the rectangle in it. 
    let path = CGMutablePath() 
    path.addArc(center: CGPoint(x: xOffset, y: yOffset), radius: radius, startAngle: 0.0, endAngle: 2 * 3.14, clockwise: false) 
    path.addRect(CGRect(x: 0, y: 0, width: overlayView.frame.width, height: overlayView.frame.height)) 

    let maskLayer = CAShapeLayer() 
    maskLayer.backgroundColor = UIColor.black.cgColor 
    maskLayer.path = path; 
    maskLayer.fillRule = kCAFillRuleEvenOdd 

    // Release the path since it's not covered by ARC. 
    overlayView.layer.mask = maskLayer 
    overlayView.clipsToBounds = true 

    return overlayView 
} 
+0

Dzięki za szybkie 3 tłumaczenia !! bardzo pomocne – Ran

5

Updated ponownie Swift 4 & usunięto kilka elementów, aby kod mocniej.

func createOverlay(frame: CGRect, 
        xOffset: CGFloat, 
        yOffset: CGFloat, 
        radius: CGFloat) -> UIView { 
    let overlayView = UIView(frame: frame) 
    overlayView.backgroundColor = UIColor.black.withAlphaComponent(0.6) 

    let path = CGMutablePath() 
    path.addArc(center: CGPoint(x: xOffset, y: yOffset), 
       radius: radius, 
       startAngle: 0.0, 
       endAngle: 2.0 * .pi, 
       clockwise: false) 
    path.addRect(CGRect(origin: .zero, size: overlayView.frame.size)) 

    let maskLayer = CAShapeLayer() 
    maskLayer.backgroundColor = UIColor.black.cgColor 
    maskLayer.path = path 
    maskLayer.fillRule = kCAFillRuleEvenOdd 

    overlayView.layer.mask = maskLayer 
    overlayView.clipsToBounds = true 

    return overlayView 
} 

A rough podział na to, co się dzieje:

  1. Tworzenie widoku wielkości do określonej ramki z czarnym tle ustawionym na 60% krycia
  2. Utwórz ścieżkę do rysowania koła za pomocą dostarczona punktem wyjścia i promień
  3. Tworzenie maski dla obszaru usunąć
  4. Zastosuj klip maska ​​& do granic

Poniższy fragment kodu będzie nazwać i umieścić koło na środku ekranu o promieniu 50:

let overlay = createOverlay(frame: view.frame, 
          xOffset: view.frame.midX, 
          yOffset: view.frame.midY, 
          radius: 50.0) 
view.addSubview(overlay) 

który wygląda tak: enter image description here

Powiązane problemy