2011-01-30 16 views
18

W mojej aplikacji na iPada chcę, aby drugi widok pojawił się w głównym oknie, gdy użytkownik kliknie przycisk. Nowy widok będzie mniejszy niż pierwszy i przyciemnić tło, gdy jest wyświetlane. Chcę, aby dwa górne rogi nowego widoku wyglądały na zaokrąglone, ale za pomocą rogu Radius ustawia się wszystkie zaokrąglone. Jak mogę zaokrąglić tylko dwa rogi?Tylko dwa zaokrąglone rogi?

Odpowiedz

17

Musisz to zrobić w drawRect :. I rzeczywiście zmodyfikowany klasyczny addRoundedRectToPath: tak, że zajmuje bitmapę i zaokrągla narożniki zażądać:

static void addRoundedRectToPath(CGContextRef context, CGRect rect, float radius, UIImageRoundedCorner cornerMask) 
{ 
    CGContextMoveToPoint(context, rect.origin.x, rect.origin.y + radius); 
    CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + rect.size.height - radius); 
    if (cornerMask & UIImageRoundedCornerTopLeft) { 
     CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + rect.size.height - radius, 
         radius, M_PI, M_PI/2, 1); 
    } 
    else { 
     CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + rect.size.height); 
     CGContextAddLineToPoint(context, rect.origin.x + radius, rect.origin.y + rect.size.height); 
    } 

    CGContextAddLineToPoint(context, rect.origin.x + rect.size.width - radius, 
          rect.origin.y + rect.size.height); 

    if (cornerMask & UIImageRoundedCornerTopRight) { 
     CGContextAddArc(context, rect.origin.x + rect.size.width - radius, 
         rect.origin.y + rect.size.height - radius, radius, M_PI/2, 0.0f, 1); 
    } 
    else { 
     CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height); 
     CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height - radius); 
    } 

    CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + radius); 

    if (cornerMask & UIImageRoundedCornerBottomRight) { 
     CGContextAddArc(context, rect.origin.x + rect.size.width - radius, rect.origin.y + radius, 
         radius, 0.0f, -M_PI/2, 1); 
    } 
    else { 
     CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y); 
     CGContextAddLineToPoint(context, rect.origin.x + rect.size.width - radius, rect.origin.y); 
    } 

    CGContextAddLineToPoint(context, rect.origin.x + radius, rect.origin.y); 

    if (cornerMask & UIImageRoundedCornerBottomLeft) { 
     CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + radius, radius, 
         -M_PI/2, M_PI, 1); 
    } 
    else { 
     CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y); 
     CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + radius); 
    } 

    CGContextClosePath(context); 
} 

To trwa maskę bitową (nazwałem go UIImageRoundedCorner ponieważ robiłem to dla zdjęć, ale można to nazwać cokolwiek), a następnie tworzy ścieżkę na podstawie narożników, które chcesz zaokrąglić. Następnie zastosować tę ścieżkę do widoku w drawRect:

CGContextBeginPath(context); 
addRoundedRectToPath(context, rect, radius, yourMask); 
CGContextClosePath(context); 
CGContextClip(context); 

Jak powiedziałem, że robię to dla UIImages, więc mój kod nie jest dokładnie skonfigurować do użytku w drawRect :, ale powinno być dość łatwe aby go dostosować. Po prostu budujesz ścieżkę, a następnie przycinasz do niej kontekst.

Edit: Aby wyjaśnić tę część maski bitowej, to tylko wyliczenia:

typedef enum { 
    UIImageRoundedCornerTopLeft = 1, 
    UIImageRoundedCornerTopRight = 1 << 1, 
    UIImageRoundedCornerBottomRight = 1 << 2, 
    UIImageRoundedCornerBottomLeft = 1 << 3 
} UIImageRoundedCorner; 

W ten sposób można lub rzeczy razem, tworząc maskę bitową, która identyfikuje narożniki, ponieważ każdy członek wyliczenia reprezentuje inna moc dwóch w masce bitowej.

znacznie później Edit: odkryłem łatwiejszy sposób to zrobić przy użyciu UIBezierPath „s bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:. Po prostu użyj obiektu ścieżki Beziera w twoim kontekście: CGPath.

+0

Świetna odpowiedź! Po prostu potrzebuję pomocy w jego implementacji. Po pierwsze, w jaki sposób mogę stworzyć własną maskę bitową? – Jumhyn

+0

Edytowanie odpowiedzi w celu wyjaśnienia wyliczenia. – kevboh

+0

Moja odpowiedź jest zbudowana, aby wziąć wszystkie narożniki, które chcesz zaokrąglić. Jeśli potrzebujesz tylko dwóch górnych narożników i nie przejmuj się innymi, możesz edytować bzdury z bitmaskami i po prostu użyć dwóch sekcji, które odpowiadają zaokrąglonym narożnikom. – kevboh

56
// Create the path (with only the top-left corner rounded) 
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds 
          byRoundingCorners:UIRectCornerTopLeft| UIRectCornerTopRight 
          cornerRadii:CGSizeMake(10.0, 10.0)]; 
// Create the shape layer and set its path 
CAShapeLayer *maskLayer = [CAShapeLayer layer]; 
maskLayer.frame = imageView.bounds; 
maskLayer.path = maskPath.CGPath; 
// Set the newly created shape layer as the mask for the image view's layer 
imageView.layer.mask = maskLayer; 

To jest inny używać górną zaokrąglony narożnik. Round two corners in UIView

+2

To działa dobrze .. dziękuje dużo –

+0

To działa, ALE powoduje renderowanie poza ekranem w całym obszarze 'imageView', powodując wyrzuconą animację – Philip007

+0

Najlepsza odpowiedź znalazłem na ten temat! – PaperThick

8

Cudowna praca wykonana przez Tomka Kuźmę. Oto nowa klasa TKRoundedView dla Twoich wymagań.
Twoje wymagania mogą być spełnione tylko za pomocą tego parametru.

TKRoundedView *view = [[TKRoundedView alloc] initWithFrame:frame]; 
view.roundedCorners = TKRoundedCornerTopLeft | TKRoundedCornerTopRight; 

Ale zapewnia również następujące dodatkowe funkcje.

TKRoundedView *view = [[TKRoundedView alloc] initWithFrame:frame]; 
view.roundedCorners = TKRoundedCornerTopLeft 
view.borderColor = [UIColor greenColor]; 
view.fillColor = [UIColor whiteColor]; 
view.drawnBordersSides = TKDrawnBorderSidesLeft | TKDrawnBorderSidesTop; 
view.borderWidth = 5.0f; 
view.cornerRadius = 15.0f; 

Proszę kasy na poniższy link do przykładowego projektu
https://github.com/mapedd/TKRoundedView

+0

^tak dobrze! Działa świetnie z automatycznym układem. –

Powiązane problemy