UIView abgerundete Ecken geben


577

Meine Login-Ansicht hat eine Unteransicht mit einem UIActivityView und UILabelsagen : „In Signing ...“. Diese Unteransicht hat Ecken, die nicht abgerundet sind. Wie kann ich sie rund machen?

Gibt es eine Möglichkeit, dies in meinem xib zu tun?


6
Um so etwas in IB zu tun, wäre ein vorgerendertes Bild mit abgerundeten Ecken erforderlich
Ed Marty

9
Nicht unbedingt @ ed-marty. Diese Antwort von @Gujamin verdient etwas mehr Anerkennung, da sie zeigt, wie die cornerRadiusEigenschaft nur mit Interface Builder auf die Tabelle angewendet wird , ohne dass vorgerenderte Bilder verwendet oder im Code festgelegt werden müssen.
DJSKinner

Antworten:


1219

Versuche dies

#import <QuartzCore/QuartzCore.h> // not necessary for 10 years now  :)

...

view.layer.cornerRadius = 5;
view.layer.masksToBounds = true;

Hinweis: Wenn Sie versuchen, abgerundete Ecken auf UIViewControllerdie Ansicht einer Ansicht anzuwenden , sollte diese nicht im Konstruktor des Ansichtscontrollers angewendet werden, sondern in -viewDidLoad, nachdem sie viewtatsächlich instanziiert wurde.


6
Beachten Sie, dass die Eigenschaft nur in iPhone 3.0 vorhanden ist, nicht in früheren Versionen.
Kendall Helmstetter Gelner

5
Ich muss nur sagen, dass dies eine der sofort befriedigendsten Antworten war, die ich je auf SO gesehen habe. Das erste Überprüfen hier ersparte mir nur eine Stunde Kampf mit einem Bildeditor und hätte meine Ansicht für Farb- / Größenänderungen spröder gemacht. Vielen Dank!
Justin Searls

20
In Verbindung stehender Hinweis: Jeder, der an mehr visuellen Extras (z. B. Schatten) interessiert ist, um sie einfach auf eine UIView anzuwenden, sollte die CALayer-Klassenreferenz lesen. Das meiste davon ist so einfach wie das Festlegen von ein oder zwei Eigenschaftswerten, wie die obige Antwort: developer.apple.com/mac/library/documentation/GraphicsImaging/…
Justin Searls

6
@Ben Collins (oder jeder andere, der dieses Problem hat), stellen Sie sicher, dass in Ihrer Ansicht "Clip-Unteransichten" festgelegt sind. Sie können dies im Interface Builder überprüfen.
zem

2
Dies funktioniert hervorragend, ABER wenn Sie viele dieser abgerundeten Ecken in einer Bildlaufansicht oder Animation haben (ich habe versucht, sie in einer UITableView zu verwenden), wird Ihre Leistung stark leiden. Schöne glatte Scrolling-Tabellenansicht wird schnell abgehackt :(
Slee

261

Sie können auch die Funktion Benutzerdefinierte Laufzeitattribute des Interface Builder verwenden, um den Schlüsselpfad layer.cornerRadiusauf einen Wert festzulegen. Stellen Sie jedoch sicher, dass Sie die QuartzCoreBibliothek einschließen .

Dieser Trick funktioniert auch zum Festlegen von layer.borderWidth, funktioniert jedoch nicht, layer.borderColorda dies ein CGColornicht a erwartetUIColor .

Sie können die Effekte im Storyboard nicht sehen, da diese Parameter zur Laufzeit ausgewertet werden.

Verwenden des Schnittstellen-Generators zum Festlegen des Eckenradius


10
Denken Sie daran, die Clip SubviewsOption auch für die Ansicht IB einzuchecken
Peter

2
(oder) einen Schlüsselpfad hinzufügen: layer.masksToBounds, Typ: boolean: Checked
Amitabh

64

Jetzt können Sie eine schnelle Kategorie in UIView (Code unter dem Bild) in @IBInspectable verwenden, um das Ergebnis im Storyboard anzuzeigen. (Wenn Sie die Kategorie verwenden, verwenden Sie nur CornerRadius und nicht layer.cornerRadius als Schlüsselpfad.

extension UIView {
    @IBInspectable var cornerRadius: CGFloat {
        get {
            return layer.cornerRadius
        }
        set {
            layer.cornerRadius = newValue
            layer.masksToBounds = newValue > 0
        }
    }
}

Geben Sie hier die Bildbeschreibung ein


Wenn Sie eine benutzerdefinierte Unterklasse verwenden, kennzeichnen Sie @IBDesignablediese unbedingt mit , um eine Live-Vorschau in IB zu erhalten! (Mehr unter nshipster.com/ibinspectable-ibdesignable )
Clozach

56

Schnell

Kurze Antwort:

myView.layer.cornerRadius = 8
myView.layer.masksToBounds = true  // optional

Ergänzende Antwort

Wenn Sie zu dieser Antwort gekommen sind, haben Sie wahrscheinlich bereits genug gesehen, um Ihr Problem zu lösen. Ich füge diese Antwort hinzu, um ein bisschen mehr visuelle Erklärung dafür zu geben, warum Dinge das tun, was sie tun.

Wenn Sie mit einem regulären beginnen UIView, hat es quadratische Ecken.

let blueView = UIView()
blueView.frame = CGRect(x: 100, y: 100, width: 100, height: 50)
blueView.backgroundColor = UIColor.blueColor()
view.addSubview(blueView)

Geben Sie hier die Bildbeschreibung ein

Sie können es um runde Ecken geben, indem Sie die cornerRadiusEigenschaft der Ansicht ändern layer.

blueView.layer.cornerRadius = 8

Geben Sie hier die Bildbeschreibung ein

Größere Radiuswerte ergeben abgerundete Ecken

blueView.layer.cornerRadius = 25

Geben Sie hier die Bildbeschreibung ein

und kleinere Werte ergeben weniger abgerundete Ecken.

blueView.layer.cornerRadius = 3

Geben Sie hier die Bildbeschreibung ein

Dies könnte ausreichen, um Ihr Problem genau dort zu lösen. Manchmal kann eine Ansicht jedoch eine Unteransicht oder eine Unterschicht haben, die außerhalb der Grenzen der Ansicht liegt. Wenn ich zum Beispiel eine Unter hinzuzufügen Ansicht wie diese

let mySubView = UIView()
mySubView.frame = CGRect(x: 20, y: 20, width: 100, height: 100)
mySubView.backgroundColor = UIColor.redColor()
blueView.addSubview(mySubView)

oder wenn ich eine Unter hinzuzufügen Schicht wie diese

let mySubLayer = CALayer()
mySubLayer.frame = CGRect(x: 20, y: 20, width: 100, height: 100)
mySubLayer.backgroundColor = UIColor.redColor().CGColor
blueView.layer.addSublayer(mySubLayer)

Dann würde ich mit enden

Geben Sie hier die Bildbeschreibung ein

Wenn ich nicht möchte, dass Dinge außerhalb der Grenzen hängen, kann ich das tun

blueView.clipsToBounds = true

oder dieses

blueView.layer.masksToBounds = true

was dieses Ergebnis gibt:

Geben Sie hier die Bildbeschreibung ein

Beide clipsToBoundsund masksToBoundssind gleichwertig . Es ist nur so, dass der erste mit UIViewund der zweite mit verwendet wird CALayer.

Siehe auch


4
Ich möchte auch hinzufügen, dass das Einstellen des Eckenradius auf die Hälfte der kürzeren Seite (in diesem Fall blueView.frame.size.height/2) zu einer perfekt abgerundeten Ecke führt.
Johann Burgess

44

Ein anderer Ansatz als der von Ed Marty:

#import <QuartzCore/QuartzCore.h>

[v.layer setCornerRadius:25.0f];
[v.layer setMasksToBounds:YES];

Sie benötigen die setMasksToBounds, um alle Objekte von IB zu laden ... Ich habe ein Problem, bei dem meine Ansicht gerundet wurde, aber die Objekte von IB nicht hatten: /

das hat es behoben = D hoffe es hilft!


48
Wo ist der Unterschied? außer keine Punktsyntax zu verwenden?
user102008

3
[v.layer setMasksToBounds: YES]; \ n Diese Linie ist magisch, sie löst mein großes Problem
Cullen SUN

3
Ich habe dies geschrieben, als ich mit der iOS-Entwicklung begann und nicht wusste, dass es keinen Unterschied zwischen der Punktsyntax und der Klammer-Syntax gibt. Deshalb habe ich es als "anders" geschrieben. Mein Code enthielt auch den Import <>, den Ed Marty in seiner ursprünglichen Antwort (später bearbeitet in) nicht hatte, und daher hilft meine Antwort den Leuten, ihr Problem zu beheben (auch bekannt als nicht importiert zu haben).
Kristian Flatheim Jensen

28

Wie in diesem Blog-Beitrag beschrieben , gibt es hier eine Methode, um die Ecken eines UIView abzurunden:

+(void)roundView:(UIView *)view onCorner:(UIRectCorner)rectCorner radius:(float)radius
{
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds
                                                   byRoundingCorners:rectCorner
                                                         cornerRadii:CGSizeMake(radius, radius)];
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = view.bounds;
    maskLayer.path = maskPath.CGPath;
    [view.layer setMask:maskLayer];
    [maskLayer release];
}

Das Coole daran ist, dass Sie auswählen können, welche Ecken aufgerundet werden sollen.


6
Anstatt nur einen Link zu einer externen Website bereitzustellen, ziehen wir es vor, dass die Antworten hier in sich geschlossen sind. Deshalb habe ich den relevanten Code aus dem verlinkten Blog-Beitrag in Ihre Antwort aufgenommen. Leute können den Blog-Beitrag für weitere Details besuchen, aber dies stellt sicher, dass der Inhalt überlebt, wenn der betreffende Beitrag verschwindet. Außerdem haben Sie diese Antwort auf verschiedene Fragen gepostet, die nicht wirklich dasselbe stellten. Diese wurden entfernt und eine Frage als Duplikat dieser Frage geschlossen. Wir möchten Antworten haben, die zu jeder Frage passen.
Brad Larson

5
Vorausschauend. Der Blog-Beitrag ist jetzt 404.
Anthony C

Dieser Ansatz ist "Sauber", verbirgt jedoch alle Schatteneffekte in der Ansicht.
Thesummersign

19

Sie müssen zuerst die Header-Datei importieren <QuartzCore/QuartzCore.h>

 #import QuartzCore/QuartzCore.h>

[yourView.layer setCornerRadius:8.0f];
yourView.layer.borderColor = [UIColor redColor].CGColor;
yourView.layer.borderWidth = 2.0f;
[yourView.layer setMasksToBounds:YES];

Verpassen Sie nicht zu verwenden - setMasksToBoundssonst wird der Effekt möglicherweise nicht angezeigt.


2
"QuartzCore / QuartzCore.h" muss nicht importiert werden
Sudhir Kumar

Ja, Sie müssen importieren.
Lord Zsolt

3
@LordZsolt Vielleicht haben sie das mit iOS7 geändert, aber Sie müssen QuartzCore nicht mehr importieren.
Marc

14

Sie können die folgende benutzerdefinierte UIViewKlasse verwenden, die auch die Rahmenfarbe und -breite ändern kann. In diesem IBDesignalbeFall können Sie die Attribute auch im Interface Builder ändern.

Geben Sie hier die Bildbeschreibung ein

import UIKit

@IBDesignable public class RoundedView: UIView {

    @IBInspectable var borderColor: UIColor = UIColor.white {
        didSet {
            layer.borderColor = borderColor.cgColor
        }
    }

    @IBInspectable var borderWidth: CGFloat = 2.0 {
        didSet {
            layer.borderWidth = borderWidth
        }
    }

    @IBInspectable var cornerRadius: CGFloat = 0.0 {
        didSet {
            layer.cornerRadius = cornerRadius
        }
    }

}

6
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(20, 50, 200, 200)];

view.layer.backgroundColor = [UIColor whiteColor].CGColor;
view.layer.cornerRadius = 20.0;
view.layer.frame = CGRectInset(v.layer.frame, 20, 20);

view.layer.shadowOffset = CGSizeMake(1, 0);
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowRadius = 5;
view.layer.shadowOpacity = .25;

[self.view addSubview:view];
[view release];

Das Anwenden von setMasksToBounds ist wichtig. Das Einstellen einer Hintergrundfarbe und eines Schlagschattens ist nicht möglich.
DJSKinner

3

Swift 4 - Verwenden von IBDesignable

   @IBDesignable
    class DesignableView: UIView {
    }

    extension UIView
    {

        @IBInspectable
        var cornerRadius: CGFloat {
            get {
                return layer.cornerRadius
            }
            set {
            layer.cornerRadius = newValue
        }
    }
}

Es tut mir leid, aber als Neuling in der IOS-Entwicklung. Wie verhindert die Lösung, dass layer.cornerRadiusder ursprüngliche Zustand wiederhergestellt wird? (Wie kann das Storyboard von xcode cornerRadiuserst nach der UIViewInitialisierung des Originals eingestellt werden ?)
AlanSTACK


3

- SwiftUI

In SwiftUI können Sie den cornerRadiusModifikator direkt für jeden Viewgewünschten verwenden. Zum Beispiel dieser Frage:

Text("Signing In…")
    .padding(16)
    .background(Color.red)
    .cornerRadius(50)

Vorschau

Beachten Sie, dass es keinen diamantähnlichen Radius mehr gibt. Selbst wenn Sie den Eckradius auf mehr als die Hälfte der Höhe einstellen einstellen, wird er glatt gerundet.

Überprüfen Sie diese Antwort, um zu erfahren, wie bestimmte Ecken in SwiftUI gerundet werden


2

Bitte importieren , Quartzcore frameworkdann haben Sie zu Satz setMaskToBoundszuTRUE die sehr wichtige Linie dieses.

Dann: [[yourView layer] setCornerRadius:5.0f];


2
UIView* viewWithRoundedCornersSize(float cornerRadius,UIView * original)
{
    // Create a white border with defined width
    original.layer.borderColor = [UIColor yellowColor].CGColor;
    original.layer.borderWidth = 1.5;

    // Set image corner radius
    original.layer.cornerRadius =cornerRadius;

    // To enable corners to be "clipped"
    [original setClipsToBounds:YES];
    return original;
}

2

Tun Sie dies programmgesteuert in obj c

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(20, 50,    200, 200)];

view.layer.backgroundColor = [UIColor whiteColor].CGColor;
view.layer.cornerRadius = 20.0;
view.layer.frame = CGRectInset(v.layer.frame, 20, 20);

[view.layer.shadowOffset = CGSizeMake(1, 0);
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowRadius = 5;
view.layer.shadowOpacity = .25;][1]

[self.view addSubview:view];

Wir können dies auch von stoaryboard aus tun.

 layer.cornerRadius  Number  5

Geben Sie hier die Bildbeschreibung ein


2

Wenn die runde Ecke in viewDidload () nicht funktioniert, ist es besser, Code in viewDidLayoutSubview () zu schreiben.

-(void)viewDidLayoutSubviews
{
    viewTextfield.layer.cornerRadius = 10.0 ;                                               
    viewTextfield.layer.borderWidth = 1.0f;
    viewTextfield.layer.masksToBounds =  YES;
    viewTextfield.layer.shadowRadius = 5;
    viewTextfield.layer.shadowOpacity = 0.3;
    viewTextfield.clipsToBounds = NO;
    viewTextfield.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
}

Hoffe das hilft!


0

Sie können auch ein Bild verwenden:

UIImage *maskingImage = [UIImage imageNamed:@"bannerBarBottomMask.png"];
CALayer *maskingLayer = [CALayer layer];
maskingLayer.frame = CGRectMake(-(self.yourView.frame.size.width - self.yourView.frame.size.width) / 2
                                , 0
                                , maskingImage.size.width
                                , maskingImage.size.height);
[maskingLayer setContents:(id)[maskingImage CGImage]];
[self.yourView.layer setMask:maskingLayer];

0

setze eckeRadious Eigenschaft für runde Ansicht

set masksToBounds Boolescher Wert für das Bild wird immer noch nicht außerhalb der Eckenradiusgrenze gezeichnet

view.layer.cornerRadius = 5;

view.layer.masksToBounds = YES;

0

Verwenden der UIView-Erweiterung:

extension UIView {    

func addRoundedCornerToView(targetView : UIView?)
{
    //UIView Corner Radius
    targetView!.layer.cornerRadius = 5.0;
    targetView!.layer.masksToBounds = true

    //UIView Set up boarder
    targetView!.layer.borderColor = UIColor.yellowColor().CGColor;
    targetView!.layer.borderWidth = 3.0;

    //UIView Drop shadow
    targetView!.layer.shadowColor = UIColor.darkGrayColor().CGColor;
    targetView!.layer.shadowOffset = CGSizeMake(2.0, 2.0)
    targetView!.layer.shadowOpacity = 1.0
}
}

Verwendungszweck:

override func viewWillAppear(animated: Bool) {

sampleView.addRoundedCornerToView(statusBarView)

}

0

In Swift 4.2 und Xcode 10.1

let myView = UIView()
myView.frame = CGRect(x: 200, y: 200, width: 200, height: 200)
myView.myViewCorners()
//myView.myViewCorners(width: myView.frame.width)//Pass View width
view.addSubview(myView)

extension UIView {
    //If you want only round corners
    func myViewCorners() {
        layer.cornerRadius = 10
        layer.borderWidth = 1.0
        layer.borderColor = UIColor.red.cgColor
        layer.masksToBounds = true
    }
    //If you want complete round shape, enable above comment line
    func myViewCorners(width:CGFloat) {
        layer.cornerRadius = width/2
        layer.borderWidth = 1.0
        layer.borderColor = UIColor.red.cgColor
        layer.masksToBounds = true
    }
}

-4

ON Xcode 6 Ihr Versuch

     self.layer.layer.cornerRadius = 5.0f;

oder

    self.layer.layer.cornerRadius = 5.0f;
    self.layer.clipsToBounds = YES;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.