2012-06-25 24 views
10
self.myPath=[UIBezierPath bezierPathWithArcCenter:center 
              radius:200 
             startAngle:0 
             endAngle:180 
             clockwise:YES]; 

(tyle udało mi się wstać działa z pomocą niektórych googling ..)Jak uzyskać odwrotną ścieżkę UIBezierPath

mam tę ścieżkę. Teraz chcę wypełnić odwrotność tej ścieżki, pozostawiając tę ​​część i wypełniając wszystko inne. Czy ktoś może mi pomóc z kodowaniem. Nie mam zbyt wielu informacji na ten temat.

> PROBLEM

enter image description here

Obszar to pokazano po użyciu Cemal Odpowiedź poprzednio tylko pokazał okrąg z czerwonego obrysu.

> NOWA EDYCJA

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     self.backgroundColor = [UIColor whiteColor]; 
     self.punchedOutPath = 
     [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 50, 400, 400)]; 
     self.fillColor = [UIColor redColor]; 
     self.alpha = 0.8; 
    } 
    return self; 
} 

- (void)drawRect:(CGRect)rect 
{ 
    [[self fillColor] set]; 
    UIRectFill(rect); 

    CGContextRef ctx = UIGraphicsGetCurrentContext(); 
    CGContextSetBlendMode(ctx, kCGBlendModeDestinationOut); 

    [[self punchedOutPath] fill]; 

    CGContextSetBlendMode(ctx, kCGBlendModeNormal); 
} 

enter image description here

+0

będzie to pełny okrąg lub otwarte okrągły kształt? Czy możesz podać obraz tego, czego oczekujesz? To nie musi być piękne, ale bardzo pomoże ludziom zrozumieć, co próbujesz zrobić, aby mogli ci pomóc. –

+0

done..pracowałam nad dostarczeniem go dopiero odkąd dokonałem nagrody – Shubhank

Odpowiedz

2

Mam dwie rozwiązanie dla Ciebie.

  1. Narysuj tę ścieżkę na CALayer. I użyj tej CALayer jako warstwy maski dla rzeczywistego CALayer.

  2. Narysuj prostokąt z rozmiarami, z których wykonujesz zdjęcie, zanim dodasz łuk.

    UIBezierPath *path = [UIBezierPath bezierPathWithRect:view.frame]; 
    [path addArcWithCenter:center 
           radius:200 
          startAngle:0 
           endAngle:2*M_PI 
          clockwise:YES]; 
    

użyłbym drugie rozwiązanie. :)

+2

Drugie rozwiązanie jest lepsze, z wyjątkiem łuku wymagającego dodania w kierunku przeciwnym do ruchu wskazówek zegara, więc obszar, który ogranicza, jest wykluczony przez [niezerową regułę liczby zwojów] (https: //developer.apple.com/library/ios/documentation/graphicsimaging/conceptual/drawingwithquartz2d/dq_paths/dq_paths.html#//apple_ref/doc/uid/TP30001066-CH211-TPXREF106) (prostokąt jest dodawany zgodnie z ruchem wskazówek zegara) . –

+0

to nie działa dla mnie, otrzymuję całkiem bardzo dziwny wynik ... i dodałem to w pytaniu..prawo widzę..dzięki – Shubhank

+1

EndAngle musi być radianami (nie stopniami). Potrzebujesz okręgu 360 °, czyli 2pi lub 6.283. Możesz zapisać to jako '2 * M_PI'. –

12

Oto alternatywa, która w ogóle nie wymaga odwrócenia ścieżki.

Masz fragment widoku, który zasadniczo ma być „clip out”:

clipped out

Powiedzmy, że chcesz, aby biały obszar będzie [UIColor whiteColor] z 75% alfa. Oto, jak szybko to zrobić:

  • Tworzysz nową podklasę UIView.
  • Pogląd ten ma dwie właściwości:

    @property (retain) UIColor *fillColor; 
    @property (retain) UIBezierPath *punchedOutPath; 
    
  • przesłonić jego -drawRect: sposób, aby to zrobić:

    - (void)drawRect:(CGRect)rect { 
        [[self fillColor] set]; 
        UIRectFill(rect); 
    
        CGContextRef ctx = UIGraphicsGetCurrentContext(); 
        CGContextSetBlendMode(ctx, kCGBlendModeDestinationOut); 
    
        [[self punchedOutPath] fill]; 
    
        CGContextSetBlendMode(ctx, kCGBlendModeNormal); 
    } 
    

Jest pewien wyjątek tutaj: The fillColor zdania muszą nie obejmują składnik alfa. Więc w twoim przypadku, chcesz, aby to było tylko [UIColor whiteColor]. Następnie samodzielnie zastosuj bit alpha, dzwoniąc pod numer [myView setAlpha:0.75].

Co tu się dzieje: Jest to tryb mieszania o nazwie "Destination Out". Matematycznie jest zdefiniowany jako R = D*(1 - Sa), ale w kategoriach laika oznacza "Obraz docelowy wszędzie tam, gdzie obraz docelowy jest nieprzejrzysty, ale obraz źródłowy jest przezroczysty, a przezroczysty w innym miejscu".

Więc to będzie używać docelowego (czyli to, co już w kontekście) gdy nowy materiał jest przezroczysty (czyli na zewnątrz ścieżki Beziera), a następnie gdzie ścieżka Beziera będzie nieprzezroczysta, że ​​materiał jest stanie się przezroczysty. Jednak obiekt docelowy musi już być nieprzejrzysty. Jeśli nie jest nieprzejrzysty, mieszanie nie robi tego, co chcesz. Dlatego musisz podać nieprzezroczysty UIColor, a następnie wykonać dowolną przezroczystość bezpośrednio w widoku.


Pobiegłem ten sam, z tych okoliczności:

  • okno ma [UIColor greenColor] tło
  • fillColor jest biały
  • punchedOutPath jest owalny to wkładce 10 punktów od krawędzi widoku.
  • widok ma alpha z 0.75

Z powyższego kodu, otrzymuję to:

enter image description here

Wnętrze jest czyste zielone, a na zewnątrz ma półprzezroczystą nakładkę.


Aktualizacja

Jeśli pokrycie jest obraz, następnie trzeba utworzyć nowy obraz. Ale zasada jest ta sama:

UIImage* ImageByPunchingPathOutOfImage(UIImage *image, UIBezierPath *path) { 
    UIGraphicsBeginImageContextWithOptions([image size], YES, [image scale]); 

    [image drawAtPoint:CGPointZero]; 

    CGContextRef ctx = UIGraphicsGetCurrentContext(); 
    CGContextSetBlendMode(ctx, kCGBlendModeDestinationOut); 
    [path fill]; 


    UIImage *final = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return final; 
} 

Można by następnie podjąć wynik tej funkcji i umieścić go w UIImageView.

+0

czy będziesz w stanie dostarczyć mi swojego projektu .. ?? Proszę..! byłoby lepiej, ponieważ miałbym działający kod ... w przeciwnym razie będę musiał wyjaśnić ci pytania ... i może ci to przeszkadzać !. – Shubhank

+0

@shubhank kod w odpowiedzi opisuje wszystko, czego potrzebujesz –

+0

cześć..możesz sprawdzić moją nową edycję do quesów.i wypróbowałeś swoją metodę..i ustawić tło mojego widoku na biały kolor..zawierać owal jest jest czarny kolor .. możesz mi pomóc z nim .. powinno być białe ... dzięki – Shubhank

14

Użyj bezierPathByReversingPath. Z dokumentów (tylko iOS 6.0+):

Tworzy i zwraca nowy obiekt ścieżki Beziera z odwróconą zawartością bieżącej ścieżki.

tak, aby odwrócić swoją ścieżkę, którą tylko ty:

UIBezierPath* aPath = [UIBezierPath bezierPathWithArcCenter:center 
                radius:200 
               startAngle:0 
                endAngle:180 
                clockwise:YES]; 
self.myPath = [aPath bezierPathByReversingPath]; 
2

Można umieścić to w jednej aplikacji do sterownika ekranu Widok: To sprawi, żółty tło widoku i niebieską warstwę na na górze, który ma owalny obszar wycięty przez maskę.

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 

    // create a yellow background 
    UIView *bg = [[UIView alloc] initWithFrame:self.view.bounds]; 
    bg.backgroundColor = [UIColor yellowColor]; 
    [self.view addSubview:bg];  

    // create the mask that will be applied to the layer on top of the 
    // yellow background 
    CAShapeLayer *maskLayer = [CAShapeLayer layer]; 
    maskLayer.fillRule = kCAFillRuleEvenOdd; 
    maskLayer.frame = self.view.frame; 

    // create the paths that define the mask 
    UIBezierPath *maskLayerPath = [UIBezierPath bezierPath]; 
    [maskLayerPath appendPath:[UIBezierPath bezierPathWithRect:CGRectInset(self.view.bounds, 20, 20)]]; 
    // here you can play around with paths :) 
// [maskLayerPath appendPath:[UIBezierPath bezierPathWithOvalInRect:(CGRect){{80, 80}, {140, 190}}]]; 
    [maskLayerPath appendPath:[UIBezierPath bezierPathWithOvalInRect:(CGRect){{100, 100}, {100, 150}}]]; 
    maskLayer.path = maskLayerPath.CGPath; 

    // create the layer on top of the yellow background 
    CALayer *imageLayer = [CALayer layer]; 
    imageLayer.frame = self.view.layer.bounds; 
    imageLayer.backgroundColor = [[UIColor blueColor] CGColor]; 

    // apply the mask to the layer 
    imageLayer.mask = maskLayer; 
    [self.view.layer addSublayer:imageLayer]; 

} 

to może odpowiedzieć na to pytanie, a także: UIBezierPath Subtract Path

+0

Czy możesz wyjaśnić, co robisz i dlaczego? Tak więc osoba, która pyta i inne osoby szukające odpowiedzi, rozumieją, na co odpowiedzieliście. – Manuel

+0

"Owalny region" pojawia się dla mnie ... – zakdances

+0

Dziwne, dlaczego nie miałby [UIBezierPath bezierPathWithOvalInRect:] narysować owalu? Czy skopiowałeś i wkleiłeś ten kod do pustego projektu na jednym ekranie? – user511

Powiązane problemy