Dando a UIView esquinas redondeadas

577

Mi vista de inicio de sesión tiene una subvista que tiene un UIActivityViewy un UILabeldicho "Iniciando sesión ...". Esta subvista tiene esquinas que no son redondeadas. ¿Cómo puedo hacerlos redondos?

¿Hay alguna forma de hacerlo dentro de mi xib?

itsaboutcode
fuente
66
Hacer algo como esto en IB requeriría una imagen renderizada previamente con esquinas redondeadas
Ed Marty
99
No necesariamente @ ed-marty, esta respuesta de @Gujamin merece algo más de crédito, ya que muestra cómo aplicar la cornerRadiuspropiedad a la tabla usando solo Interface Builder, sin tener que usar imágenes renderizadas previamente o establecerlas en el código.
djskinner

Respuestas:

1219

Prueba esto

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

...

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

Nota: Si está intentando aplicar esquinas redondeadas a UIViewControllerla vista de una vista, no debe aplicarse en el constructor del controlador de vista, sino más bien en -viewDidLoad, después de que viewse instancia.

Ed Marty
fuente
66
Tenga en cuenta que la propiedad solo existe en iPhone 3.0, no en versiones anteriores.
Kendall Helmstetter Gelner el
55
Solo tengo que decir que esta fue una de las respuestas más satisfactorias de inmediato que he visto en SO. Comprobar aquí primero me ahorró una hora de pelea con un editor de imágenes y habría hecho que mi vista fuera más frágil a los cambios de color / tamaño. ¡Gracias!
Justin Searls
20
Nota relacionada: cualquier persona interesada en más objetos visuales (es decir, sombra) para aplicar fácilmente a una UIView debe consultar la referencia de clase CALayer. La mayor parte es tan fácil como establecer uno o dos valores de propiedad, como la respuesta anterior: developer.apple.com/mac/library/documentation/GraphicsImaging/…
Justin Searls
66
@Ben Collins (o cualquier otra persona que tenga este problema), asegúrese de que su vista tenga "subvistas de clip" configuradas. Puede verificar esto en el generador de interfaces.
zem
2
esto funciona muy bien, PERO si tiene muchas de estas esquinas redondeadas en cualquier tipo de vista de desplazamiento o animación (intenté usarlas en un UITableView), su rendimiento se verá muy afectado. La vista de la tabla de desplazamiento suave y agradable se vuelve rápidamente entrecortada :(
Slee
261

También puede usar la característica Atributos de tiempo de ejecución definidos por el usuario del generador de interfaces para establecer la ruta de la clave layer.cornerRadiusa un valor. Sin QuartzCoreembargo, asegúrese de incluir la biblioteca.

Este truco también funciona para configurar layer.borderWidth, sin embargo, no funcionará, layer.borderColorya que esto espera un CGColornoUIColor .

No podrá ver los efectos en el guión gráfico porque estos parámetros se evalúan en tiempo de ejecución.

Uso del generador de interfaces para establecer el radio de la esquina

Gujamin
fuente
10
recuerde marcar también la Clip Subviewsopción para la vista IB
Peter
2
(o) agregue una Ruta de clave: layer.masksToBounds, Tipo: boolean: Checked
Amitabh
64

Ahora puede usar una categoría rápida en UIView (código debajo de la imagen) con @IBInspectable para mostrar el resultado en el guión gráfico (si está usando la categoría, use solo cornerRadius y no layer.cornerRadius como ruta clave.

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

ingrese la descripción de la imagen aquí

Guilherme Torres Castro
fuente
Y si está utilizando una subclase personalizada, asegúrese de etiquetarla @IBDesignablepara obtener una vista previa en vivo en IB. (Más en nshipster.com/ibinspectable-ibdesignable )
clozach
56

Rápido

Respuesta corta:

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

Respuesta suplementaria

Si ha llegado a esta respuesta, probablemente ya haya visto lo suficiente para resolver su problema. Estoy agregando esta respuesta para dar un poco más de explicación visual de por qué las cosas hacen lo que hacen.

Si comienzas con un regular UIView, tiene esquinas cuadradas.

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

ingrese la descripción de la imagen aquí

Puede darle esquinas redondeadas cambiando la cornerRadiuspropiedad de la vista layer.

blueView.layer.cornerRadius = 8

ingrese la descripción de la imagen aquí

Los valores de radio mayores dan esquinas más redondeadas

blueView.layer.cornerRadius = 25

ingrese la descripción de la imagen aquí

y valores más pequeños dan esquinas menos redondeadas.

blueView.layer.cornerRadius = 3

ingrese la descripción de la imagen aquí

Esto podría ser suficiente para resolver su problema allí mismo. Sin embargo, a veces una vista puede tener una subvista o una subcapa que se sale de los límites de la vista. Por ejemplo, si tuviera que agregar una vista secundaria como esta

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

o si tuviera que añadir un sub capa como esto

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

Entonces terminaría con

ingrese la descripción de la imagen aquí

Ahora, si no quiero que las cosas cuelguen fuera de los límites, puedo hacer esto

blueView.clipsToBounds = true

o esto

blueView.layer.masksToBounds = true

lo que da este resultado:

ingrese la descripción de la imagen aquí

Ambos clipsToBoundsy masksToBoundsson equivalentes . Es solo que el primero se usa con UIViewy el segundo se usa con CALayer.

Ver también

Suragch
fuente
44
También me gustaría agregar que establecer el radio de la esquina en la mitad del lado más corto (en este caso blueView.frame.size.height/2) da como resultado una esquina perfectamente redondeada.
Johann Burgess
44

Un enfoque diferente al que hizo Ed Marty:

#import <QuartzCore/QuartzCore.h>

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

Necesita los setMasksToBounds para que cargue todos los objetos de IB ... Tengo un problema en el que mi vista se redondeó, pero no tenía los objetos de IB: /

esto lo solucionó = D espero que ayude!

Kristian Flatheim Jensen
fuente
48
¿Cómo es diferente? aparte de no usar la sintaxis de puntos?
user102008
3
[v.layer setMasksToBounds: YES]; \ n esta línea es mágica, resuelve mi gran problema
Cullen SUN
3
Escribí esto cuando comencé el desarrollo de iOS y no sabía que no había diferencia entre la sintaxis de puntos y la sintaxis de paréntesis. Por eso lo escribí como "diferente". Mi código también incluía la importación <> que Ed Marty no tenía en su respuesta original (luego editada) y, por lo tanto, mi respuesta ayuda a las personas a solucionar su problema (es decir, no importarlo).
Kristian Flatheim Jensen
28

Como se describe en esta publicación de blog , aquí hay un método para redondear las esquinas de una 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];
}

Lo bueno de esto es que puedes seleccionar qué esquinas quieres redondear.

pabloruiz55
fuente
66
En lugar de simplemente proporcionar un enlace a un sitio externo, preferimos que las respuestas sean autónomas aquí, por lo que traje el código relevante de la publicación del blog vinculado a su respuesta. Las personas pueden visitar la publicación del blog para obtener más detalles, pero esto asegura que el contenido sobrevivirá si la publicación en cuestión desaparece. Además, publicó esta respuesta a varias preguntas diferentes que realmente no hicieron la misma cosa. Se eliminaron y una pregunta se cerró como un duplicado de esta. Nos gusta tener respuestas diseñadas para que coincidan con cada pregunta.
Brad Larson
55
Presciente. La publicación del blog es 404 ahora.
Anthony C
Este enfoque es limpio pero ocultará cualquier efecto de sombra en la vista.
thesummersign
19

Primero debe importar el archivo de encabezado <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];

No se pierda el uso setMasksToBounds; de lo contrario, es posible que no se muestre el efecto.

Samir Jwarchan
fuente
2
No es necesario importar "QuartzCore / QuartzCore.h"
Sudhir Kumar
Sí, necesitas importar.
Lord Zsolt
3
@LordZsolt Tal vez lo cambiaron con iOS7, pero ya no es necesario importar QuartzCore.
Marc
15

Puede usar la siguiente UIViewclase personalizada que también puede cambiar el color y el ancho del borde. Como es esto, también IBDesignalbepuede cambiar los atributos en el generador de interfaces.

ingrese la descripción de la imagen aquí

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
fuente
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
fuente
Aplicar setMasksToBounds es importante. Establecer un color de fondo y sombra paralela no lo es.
djskinner
3

Swift 4 - Uso de IBDesignable

   @IBDesignable
    class DesignableView: UIView {
    }

    extension UIView
    {

        @IBInspectable
        var cornerRadius: CGFloat {
            get {
                return layer.cornerRadius
            }
            set {
            layer.cornerRadius = newValue
        }
    }
}
Saranjith
fuente
Lo siento, pero como recién llegado al desarrollo de iOS. ¿Cómo evita que la solución layer.cornerRadiusregrese al estado original? (¿Cómo sabe el guión gráfico de xcode cómo configurar cornerRadiussolo después de UIViewinicializar el original )?
AlanSTACK
3
view.layer.cornerRadius = 25
view.layer.masksToBounds = true
Parth Barot
fuente
3

- SwiftUI

En SwiftUI, puede usar el cornerRadiusmodificador directamente en el Viewque desee. Por ejemplo de esta pregunta:

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

Avance

Tenga en cuenta que no hay más diamantes como el radio, por lo que incluso si establece la esquina Radio más de la mitad de la altura , se redondeará suavemente.

Consulte esta respuesta para ver cómo redondear esquinas específicas en SwiftUI

Mojtaba Hosseini
fuente
2

Importa, Quartzcore frameworkentonces debes configurarlo setMaskToBoundsenTRUE esta la línea muy importante.

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

DeveshM
fuente
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
fuente
2

Haga esto programáticamente 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];

También podemos hacer esto desde stoaryboard.

 layer.cornerRadius  Number  5

ingrese la descripción de la imagen aquí

Vikas Rajput
fuente
2

Si la esquina redonda no funciona en viewDidload () , es mejor escribir código en 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);
}

¡Espero que esto ayude!

Dharmesh Mansata
fuente
0

También puedes usar una imagen:

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];
rico
fuente
0

set cornerRadious Property for round View

establecer el valor booleano masksToBounds para la imagen aún no se dibujará fuera del límite del radio de la esquina

view.layer.cornerRadius = 5;

view.layer.masksToBounds = YES;
bhautikmewada191
fuente
0

Usando la extensión 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
}
}

Uso:

override func viewWillAppear(animated: Bool) {

sampleView.addRoundedCornerToView(statusBarView)

}
AG
fuente
0

En Swift 4.2 y 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
fuente
-4

ON Xcode 6 Tu intento

     self.layer.layer.cornerRadius = 5.0f;

o

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