Tylko dwa zaokrąglone rogi? [duplikat]

To pytanie ma już odpowiedź tutaj:

W mojej aplikacji na iPad, chcę, aby drugi widok pojawiał się w głównym, gdy użytkownik kliknie przycisk. Nowy widok będzie mniejszy niż pierwszy i przyciemni tło podczas wyświetlania. Chcę dwa górne rogi nowego widok wydaje się zaokrąglony, ale za pomocą cornerRadius ustawia wszystkie z nich zaokrąglone. Jak zrobić tylko dwa rogi zaokrąglone?

Author: Jumhyn, 2011-01-30

3 answers

Musisz to zrobić w drawRect:. W rzeczywistości zmodyfikowałem klasyczny addRoundedRectToPath: tak, że zajmuje bitmapę i zaokrągla rogi, o które prosisz:

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 zajmuje maskę bitową (nazwałem ją UIImageRoundedCorner, ponieważ robiłem to dla obrazów, ale można to nazwać jak chcesz), a następnie tworzy ścieżkę opartą na rogach, które chcesz zaokrąglać. Następnie zastosujesz tę ścieżkę do widoku w drawRect:

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

Jak już mówiłem, robiłem to dla UIImages, więc mój kod nie jest do końca skonfigurować do użycia w drawRect:, ale powinno być dość łatwo go dostosować. Po prostu budujesz ścieżkę, a następnie wycinasz jej kontekst.

Edit: aby wyjaśnić część maska bitowa, jest to tylko enum:

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

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

Znacznie Później Edit: Odkryłem łatwiejszy sposób, aby to zrobić za pomocą UIBezierPath's bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:. Po prostu użyj CGPath obiektu Beziera path w swoim kontekście.

 17
Author: kevboh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-04 12:26:52

W Celu C

   // 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;

Jest to inny, aby użyć górnego zaokrąglonego rogu. Round two corners in UIView

/ Align = "Left" / !!
myView.clipsToBounds = true
myView.layer.cornerRadius = 10
myView.layer.maskedCorners = [.layerMinXMinYCorner,.layerMaxXMinYCorner]

Tutaj wpisz opis obrazka

 63
Author: SachinVsSachin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-10 12:27:22

Wspaniała praca Tomka Kuźmy. Oto nowa klasa TKRoundedView dla Twoich wymagań.
Twoje wymagania mogą być spełnione tylko przez ten parametr.

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ę sprawdzić poniższy link do przykładowego projektu
https://github.com/mapedd/TKRoundedView

 8
Author: iNeal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-16 06:42:24