Donner des coins arrondis à UIView

577

Ma vue de connexion a une sous-vue qui a un UIActivityViewet un UILabeldicton «Connexion…». Cette sous-vue a des coins qui ne sont pas arrondis. Comment puis-je les arrondir?

Existe-t-il un moyen de le faire à l'intérieur de mon xib?

itsaboutcode
la source
6
Faire quelque chose comme ça dans IB nécessiterait une image pré-rendue avec des coins arrondis
Ed Marty
9
Pas nécessairement @ ed-marty, cette réponse de @Gujamin mérite un peu plus de crédit car elle montre comment appliquer la cornerRadiuspropriété à la table en utilisant Interface Builder uniquement, sans avoir à utiliser des images pré-rendues ou à la définir dans le code.
djskinner

Réponses:

1219

Essaye ça

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

...

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

Remarque: Si vous essayez d'appliquer des coins arrondis à UIViewControllerla vue d'un, il ne doit pas être appliqué dans le constructeur du contrôleur de vue, mais plutôt dans -viewDidLoad, après viewest réellement instancié.

Ed Marty
la source
6
Notez que la propriété n'existe que dans l'iPhone 3.0, pas dans les versions antérieures.
Kendall Helmstetter Gelner
5
Je dois juste dire que c'était l'une des réponses les plus satisfaisantes que j'ai jamais vues sur SO. Vérifier ici d'abord m'a sauvé une heure de combat avec un éditeur d'image et aurait rendu ma vue plus fragile aux changements de couleur / taille. Merci!
Justin Searls
20
Remarque connexe: toute personne intéressée par des goodies plus visuels (c'est-à-dire des ombres) à appliquer facilement à une UIView devrait consulter la référence de la classe CALayer. La plupart de cela est aussi simple que de définir une ou deux valeurs de propriété, comme la réponse ci-dessus: developer.apple.com/mac/library/documentation/GraphicsImaging/…
Justin Searls
6
@Ben Collins (ou toute autre personne ayant ce problème), assurez-vous que votre vue a défini des "sous-vues de clip". Vous pouvez vérifier cela dans le générateur d'interface.
zem
2
cela fonctionne très bien MAIS si vous avez beaucoup de ces coins arrondis dans toute sorte de vue de défilement ou d'animation (j'ai essayé de les utiliser dans une UITableView), vos performances en souffriront grandement. Une belle vue de la table de défilement lisse devient rapidement saccadée :(
Slee
261

Vous pouvez également utiliser la fonction Attributs d'exécution définis par l' utilisateur du générateur d'interface pour définir le chemin layer.cornerRadiusd' accès à une valeur. Assurez-vous cependant d'inclure la QuartzCorebibliothèque.

Cette astuce fonctionne également pour définir layer.borderWidth mais cela ne fonctionnera pas layer.borderColorcar cela attend un CGColorpas un UIColor.

Vous ne pourrez pas voir les effets dans le storyboard car ces paramètres sont évalués au moment de l'exécution.

Utilisation du générateur d'interface pour définir le rayon d'angle

Gujamin
la source
10
n'oubliez pas de vérifier également l' Clip Subviewsoption pour la vue IB
Peter
2
(ou) ajoutez un chemin de clé: layer.masksToBounds, Type: booléen: Vérifié
Amitabh
64

Vous pouvez maintenant utiliser une catégorie rapide dans UIView (code sous l'image) avec @IBInspectable pour afficher le résultat sur le storyboard (si vous utilisez la catégorie, utilisez uniquement cornerRadius et non layer.cornerRadius comme chemin de clé.

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

entrez la description de l'image ici

Guilherme Torres Castro
la source
Et si vous utilisez une sous-classe personnalisée, assurez-vous de la marquer @IBDesignablepour obtenir un aperçu en direct dans IB! (Plus sur nshipster.com/ibinspectable-ibdesignable )
clozach
56

Rapide

Réponse courte:

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

Réponse supplémentaire

Si vous êtes parvenu à cette réponse, vous en avez probablement déjà vu assez pour résoudre votre problème. J'ajoute cette réponse pour donner un peu plus d'explications visuelles sur les raisons pour lesquelles les choses font ce qu'elles font.

Si vous commencez avec un régulier, UIViewil a des coins carrés.

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

entrez la description de l'image ici

Vous pouvez lui donner des coins arrondis en modifiant la cornerRadiuspropriété de la vue layer.

blueView.layer.cornerRadius = 8

entrez la description de l'image ici

Des valeurs de rayon plus grandes donnent des coins plus arrondis

blueView.layer.cornerRadius = 25

entrez la description de l'image ici

et des valeurs plus petites donnent des coins moins arrondis.

blueView.layer.cornerRadius = 3

entrez la description de l'image ici

Cela pourrait suffire à résoudre votre problème. Cependant, une vue peut parfois avoir une sous-vue ou une sous-couche qui dépasse les limites de la vue. Par exemple, si je devais ajouter une vue secondaire comme celle-ci

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

ou si je devais ajouter une sous- couche comme celle-ci

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

Ensuite, je me retrouverais avec

entrez la description de l'image ici

Maintenant, si je ne veux pas que les choses dépassent des limites, je peux le faire

blueView.clipsToBounds = true

ou ca

blueView.layer.masksToBounds = true

ce qui donne ce résultat:

entrez la description de l'image ici

Les deux clipsToBoundset masksToBoundssont équivalents . C'est juste que le premier est utilisé avec UIViewet le second est utilisé avec CALayer.

Voir également

Suragch
la source
4
Je voudrais également ajouter que le fait de définir le rayon du coin sur la moitié du côté le plus court (dans ce cas blueView.frame.size.height/2) donne un coin parfaitement arrondi.
Johann Burgess
44

Une approche différente de celle d'Ed Marty:

#import <QuartzCore/QuartzCore.h>

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

Vous avez besoin de setMasksToBounds pour qu'il charge tous les objets d'IB ... j'ai un problème où ma vue a été arrondie, mais je n'ai pas eu les objets d'IB: /

cela l'a corrigé = D j'espère que ça aide!

Kristian Flatheim Jensen
la source
48
en quoi est-ce différent? autre que de ne pas utiliser la syntaxe à points?
user102008
3
[v.layer setMasksToBounds: YES]; \ n cette ligne est magique, elle résout mon gros problème
Cullen SUN
3
J'ai écrit cela lorsque j'ai commencé le développement iOS et je ne savais pas qu'il n'y avait pas de différence entre la syntaxe des points et la syntaxe des crochets. Je l'ai donc écrit comme "différent". Mon code incluait également l'importation <> qu'Ed Marty n'avait pas dans sa réponse d'origine (éditée plus tard dans) et donc ma réponse aide les gens à résoudre leur problème (c'est-à-dire ne pas l'avoir importé).
Kristian Flatheim Jensen
28

Comme décrit dans cet article de blog , voici une méthode pour contourner les coins d'un UIView:

+(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];
}

La partie intéressante à ce sujet est que vous pouvez sélectionner les coins que vous souhaitez arrondir.

pabloruiz55
la source
6
Plutôt que de simplement fournir un lien vers un site externe, nous préférons que les réponses soient autonomes ici, j'ai donc apporté le code correspondant du blog lié dans votre réponse. Les gens peuvent visiter le blog pour plus de détails, mais cela garantit que le contenu survivra si le message en question disparaît. De plus, vous avez posté cette réponse à plusieurs questions différentes qui ne posaient pas vraiment la même chose. Celles-ci ont été supprimées et une question a été classée en double de celle-ci. Nous aimons avoir des réponses conçues pour correspondre à chaque question.
Brad Larson
5
Prescient. Le blog est maintenant 404.
Anthony C
Cette approche est propre, mais elle masquera tout effet d'ombre sur la vue.
thesummersign
19

Vous devez d'abord importer le fichier d'en-tête <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];

Ne manquez pas d'utiliser - setMasksToBounds, sinon l'effet peut ne pas être affiché.

Samir Jwarchan
la source
2
Pas besoin d'importer "QuartzCore / QuartzCore.h"
Sudhir Kumar
Oui, vous devez importer.
Lord Zsolt
3
@LordZsolt Ils ont peut-être changé cela avec iOS7, mais vous n'avez plus besoin d'importer QuartzCore.
Marc
15

Vous pouvez utiliser la UIViewclasse personnalisée suivante qui peut également modifier la couleur et la largeur de la bordure. En l'état, IBDesignalbevous pouvez également modifier les attributs dans le générateur d'interface.

entrez la description de l'image ici

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
        }
    }

}
Vakas
la source
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];
jorik
la source
L'application de setMasksToBounds est importante. La définition d'une couleur d'arrière-plan et d'une ombre portée ne l'est pas.
djskinner
3

Swift 4 - Utilisation d'IBDesignable

   @IBDesignable
    class DesignableView: UIView {
    }

    extension UIView
    {

        @IBInspectable
        var cornerRadius: CGFloat {
            get {
                return layer.cornerRadius
            }
            set {
            layer.cornerRadius = newValue
        }
    }
}
Saranjith
la source
Je suis désolé, mais en tant que nouveau venu dans le développement IOS. Comment la solution empêche-t-elle layer.cornerRadiusde revenir à son état d'origine? (ei comment le storyboard de xcode sait-il définir cornerRadiusuniquement après l' UIViewinitialisation de l'original )?
AlanSTACK
3
view.layer.cornerRadius = 25
view.layer.masksToBounds = true
Parth Barot
la source
3

- SwiftUI

Dans SwiftUI, vous pouvez utiliser le cornerRadiusmodificateur directement sur celui que Viewvous voulez. Par exemple de cette question:

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

Aperçu

Notez qu'il n'y a plus de rayon de type diamant, donc même si vous définissez le cornerRadius sur plus de la moitié de la hauteur , il arrondira en douceur.

Consultez cette réponse pour savoir comment arrondir des coins spécifiques dans SwiftUI

Mojtaba Hosseini
la source
2

Veuillez importer Quartzcore frameworkpuis vous devez définir setMaskToBoundssur TRUEcette ligne la plus importante.

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

DeveshM
la source
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;
}
Ashish Patel
la source
2

Faites cela par programme en 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];

Nous pouvons également le faire à partir de stoaryboard.

 layer.cornerRadius  Number  5

entrez la description de l'image ici

Vikas Rajput
la source
2

si le coin rond ne fonctionne pas dans viewDidload (), il est préférable d'écrire du code dans viewDidLayoutSubview ()

-(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);
}

J'espère que cela t'aides!

Dharmesh Mansata
la source
0

Vous pouvez également utiliser une image:

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];
richy
la source
0

set cornerRadious Property for round View

set masksToBounds La valeur booléenne de l'image ne sera pas toujours dessinée en dehors de la limite du rayon d'angle

view.layer.cornerRadius = 5;

view.layer.masksToBounds = YES;
bhautikmewada191
la source
0

Utilisation de l'extension UIView:

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
}
}

Usage:

override func viewWillAppear(animated: Bool) {

sampleView.addRoundedCornerToView(statusBarView)

}
AG
la source
0

Dans Swift 4.2 et 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
    }
}
iOS
la source
-4

ON Xcode 6 Votre essai

     self.layer.layer.cornerRadius = 5.0f;

ou

    self.layer.layer.cornerRadius = 5.0f;
    self.layer.clipsToBounds = YES;
Saringkhan Vungsin
la source