2013-02-14 9 views
15

Próbuję zaokrąglić dolne dwa rogi UIView, a także obramowanie warstwy jest zaokrąglone. Obecnie wykonuję:Zaokrąglić rogi UIView i zaokrąglić również granicę warstwy widoku

UIRectCorners corners = UIRectCornerBottomLeft | UIRectCornerBottomRight; 
CGSize radii = CGSizeMake(kThisViewCornerRadius, kThisViewCornerRadius); 
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:myView.bounds 
              byRoundingCorners:corners 
               cornerRadii:radii]; 

CAShapeLayer *maskLayer = [CAShapeLayer layer]; 
[maskLayer setPath:path.CGPath]; 
myView.layer.mask = maskLayer; 

To działa dobrze dla normalnych widoków. Jednak warstwa myView „s ma swoje borderColor i borderWidth zestaw, a jak widać na zrzucie ekranu, obramowanie warstwy nie jest uzyskiwanie zaokrągleniu:

Screenshot of the problem

Próbowałem też instacji UIView i powrocie [CAShapeLayer layer] z +[Class layerClass], i ustawianie warstwy widoku jako warstwy kształtu, ale brzeg kończył się pod podglądami widoku.

Czy można zaokrąglić niektóre narożniki widoku, zaokrąglić granicę warstwy widoku i przyciąć subviews pod krawędzią warstwy?

Należy pamiętać, że jest to , a nie o tym, jak zaokrąglić niektóre rogi, a nie inne, ale raczej jak sprawić, aby kreska prawidłowo zachowywała się.

+1

dodać warstwę kształtu, który jest głaskani w hierarchii warstw? –

+0

Dobra sugestia, ale przetestowałem ją, a pociągnięcia za krawędzią warstwy kształtowej nadal pojawiają się za podglądami widoku. –

+0

Właściwie twój komentarz sprawił, że myślałem na właściwym tropie, a ja go otrzymałem. Opublikuję to jako odpowiedź. Dzięki! –

Odpowiedz

36

Wymyśliłem nowy sposób myślenia o tym, dzięki komentarzowi David Rönnqvist.

Próbowałem wykonać zaokrąglenie rogu i obrys w jednej warstwie. Zamiast tego podzieliłem go na dwie warstwy: jedną, aby zamaskować warstwę widoku wokół rogów, a drugą w widoku, aby dodać obrys.

UIView *containerView = [[UIView alloc] initWithFrame:someFrame]; 

UIRectCorners corners = UIRectCornerBottomLeft | UIRectCornerBottomRight; 
CGSize radii = CGSizeMake(kThisViewCornerRadius, kThisViewCornerRadius); 

UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:myView.bounds 
              byRoundingCorners:corners 
               cornerRadii:radii]; 

// Mask the container view’s layer to round the corners. 
CAShapeLayer *cornerMaskLayer = [CAShapeLayer layer]; 
[cornerMaskLayer setPath:path.CGPath]; 
containerView.layer.mask = cornerMaskLayer; 

// Make a transparent, stroked layer which will dispay the stroke. 
CAShapeLayer *strokeLayer = [CAShapeLayer layer]; 
strokeLayer.path = path.CGPath; 
strokeLayer.fillColor = [UIColor clearColor].CGColor; 
strokeLayer.strokeColor = [UIColor redColor].CGColor; 
strokeLayer.lineWidth = 2; // the stroke splits the width evenly inside and outside, 
          // but the outside part will be clipped by the containerView’s mask. 

// Transparent view that will contain the stroke layer 
UIView *strokeView = [[UIView alloc] initWithFrame:containerView.bounds]; 
strokeView.userInteractionEnabled = NO; // in case your container view contains controls 
[strokeView.layer addSublayer:strokeLayer]; 

// configure and add any subviews to the container view 

// stroke view goes in last, above all the subviews 
[containerView addSubview:strokeView]; 
+1

+ 100 Świetne rzeczy – DogCoffee

+0

bardzo ładne! Ale czy mogę ustawić opcjonalne granice? – Vishnu

+0

Co masz na myśli przez opcjonalne granice? –

0

Oto mały kod. Alloc zainicjuj widok i wyślij tę metodę, aby zaokrąglić rogi. Możesz dowolnie zaokrąglić dowolny z narożników. Daj również kolor obrysu cienia.

-(void) setMaskTo:(UIView*)view byRoundingCorners:(UIRectCorner)corners withColor: (UIColor*) color 
{ 
UIBezierPath* rounded = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(9.0, 9.0)]; 

CAShapeLayer* shape = [[[CAShapeLayer alloc] init] autorelease]; 
[shape setPath:rounded.CGPath]; 
shape.strokeColor = [[UIColor grayColor] CGColor]; 

view.backgroundColor=color; 
view.layer.mask = shape; 
} 

Wywołanie metody w ten sposób.

[self setMaskTo:ABCView byRoundingCorners:UIRectCornerAllCorners withColor:[UIColor greenColor]]; 
+0

Czy to działa u każdego? Nie działa dla mnie .. –

9

Odpowiedź Zev Eisenberg jest właściwa.

Chociaż wolę:

[self.layer addSublayer:strokeLayer]; 

zamiast tworzenia i dodawania podrzędny:

CGSize radii = CGSizeMake(radius, radius); 

UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds 
              byRoundingCorners:corners 
               cornerRadii:radii]; 

// Mask the container view’s layer to round the corners. 
CAShapeLayer *cornerMaskLayer = [CAShapeLayer layer]; 
[cornerMaskLayer setPath:path.CGPath]; 
self.layer.mask = cornerMaskLayer; 

// Make a transparent, stroked layer which will dispay the stroke. 
CAShapeLayer *strokeLayer = [CAShapeLayer layer]; 
strokeLayer.path = path.CGPath; 
strokeLayer.fillColor = [UIColor clearColor].CGColor; 
strokeLayer.strokeColor = color.CGColor; 
strokeLayer.lineWidth = 2; // the stroke splits the width evenly inside and outside, 
// but the outside part will be clipped by the containerView’s mask. 

[self.layer addSublayer:strokeLayer];