objective framework developer apple ios swift core-graphics

ios - framework - objective c documentation



¿Crear un rectángulo con solo dos esquinas redondeadas en swift? (10)

2017 ...

@IBDesignable class RoundedEnds: UIView { override func layoutSubviews() { setup() } // "layoutSubviews" is best func setup() { let r = self.bounds.size.height / 2 let path = UIBezierPath(roundedRect: self.bounds, cornerRadius:r) let mask = CAShapeLayer() mask.path = path.cgPath self.layer.mask = mask } }

Para solo algunas esquinas, solo cambia a:

roundedRect: self.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: r, height: r)

Tenga en cuenta que, como de costumbre, ha habido muchos pequeños cambios en Swift, por ejemplo, la capitalización de constantes, etc.

Necesito crear un rectángulo que tenga solo dos esquinas redondeadas en Swift (el código de Objective C también es correcto).

En este momento mi código está creando dos rectángulos con

CGPathCreateWithRoundedRect(CGRectMake(0, 0, 30, 60), 5, 5, nil);

y

CGPathCreateWithRoundedRect(CGRectMake(0, 0, 30, 60), 0, 0, nil);

y fusionándolos (para tener dos esquinas en ángulo recto y dos redondeadas) pero no estoy contento con el código y estoy bastante seguro de que debería haber formas mucho mejores de hacerlo.

Soy nuevo en iOS y desarrollo gráfico y rápido.


Aquí hay una rápida extensión Swift 3 que puede usar para redondear y bordes opcionales.

Nota: si está utilizando autolayout, es posible que tenga que llamar esto en una de las devoluciones de llamada del ciclo de vida de la vista como viewDidLayoutSubviews o layoutSubviews después de que la vista haya sido restringida.

import UIKit extension UIView { /** Rounds the given set of corners to the specified radius - parameter corners: Corners to round - parameter radius: Radius to round to */ func round(corners: UIRectCorner, radius: CGFloat) { _ = _round(corners: corners, radius: radius) } /** Rounds the given set of corners to the specified radius with a border - parameter corners: Corners to round - parameter radius: Radius to round to - parameter borderColor: The border color - parameter borderWidth: The border width */ func round(corners: UIRectCorner, radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat) { let mask = _round(corners: corners, radius: radius) addBorder(mask: mask, borderColor: borderColor, borderWidth: borderWidth) } /** Fully rounds an autolayout view (e.g. one with no known frame) with the given diameter and border - parameter diameter: The view''s diameter - parameter borderColor: The border color - parameter borderWidth: The border width */ func fullyRound(diameter: CGFloat, borderColor: UIColor, borderWidth: CGFloat) { layer.masksToBounds = true layer.cornerRadius = diameter / 2 layer.borderWidth = borderWidth layer.borderColor = borderColor.cgColor; } } private extension UIView { @discardableResult func _round(corners: UIRectCorner, radius: CGFloat) -> CAShapeLayer { let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius)) let mask = CAShapeLayer() mask.path = path.cgPath self.layer.mask = mask return mask } func addBorder(mask: CAShapeLayer, borderColor: UIColor, borderWidth: CGFloat) { let borderLayer = CAShapeLayer() borderLayer.path = mask.path borderLayer.fillColor = UIColor.clear.cgColor borderLayer.strokeColor = borderColor.cgColor borderLayer.lineWidth = borderWidth borderLayer.frame = bounds layer.addSublayer(borderLayer) } }


En Swift 2.3 puedes hacerlo por

let maskPath = UIBezierPath(roundedRect: anyView.bounds, byRoundingCorners: [.BottomLeft, .BottomRight], cornerRadii: CGSize(width: 10.0, height: 10.0)) let shape = CAShapeLayer() shape.path = maskPath.CGPath view.layer.mask = shape

En Objective-C podrías usar el método de clase UIBezierPath

bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:

ejemplo de implementación

// set the corner radius to the specified corners of the passed container - (void)setMaskTo:(UIView*)view byRoundingCorners:(UIRectCorner)corners { UIBezierPath *rounded = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(10.0, 10.0)]; CAShapeLayer *shape = [[CAShapeLayer alloc] init]; [shape setPath:rounded.CGPath]; view.layer.mask = shape; }

y llamar al método anterior como

[self setMaskTo:anyView byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight];


Esto es lo que haces en Swift 2.0

var maskPath = UIBezierPath(roundedRect: anyView.bounds, byRoundingCorners: [.BottomLeft, .BottomRight], cornerRadii: CGSize(width: 10.0, height: 10.0))


Se actualizó la respuesta de iWasRobbed para trabajar con la versión Swift 3.0 GM:

import UIKit extension UIView { /** Rounds the given set of corners to the specified radius - parameter corners: Corners to round - parameter radius: Radius to round to */ func round(corners: UIRectCorner, radius: CGFloat) { _round(corners: corners, radius: radius) } /** Rounds the given set of corners to the specified radius with a border - parameter corners: Corners to round - parameter radius: Radius to round to - parameter borderColor: The border color - parameter borderWidth: The border width */ func round(corners: UIRectCorner, radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat) { let mask = _round(corners: corners, radius: radius) addBorder(mask: mask, borderColor: borderColor, borderWidth: borderWidth) } /** Fully rounds an autolayout view (e.g. one with no known frame) with the given diameter and border - parameter diameter: The view''s diameter - parameter borderColor: The border color - parameter borderWidth: The border width */ func fullyRound(diameter: CGFloat, borderColor: UIColor, borderWidth: CGFloat) { layer.masksToBounds = true layer.cornerRadius = diameter / 2 layer.borderWidth = borderWidth layer.borderColor = borderColor.cgColor; } } private extension UIView { @discardableResult func _round(corners: UIRectCorner, radius: CGFloat) -> CAShapeLayer { let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius)) let mask = CAShapeLayer() mask.path = path.cgPath self.layer.mask = mask return mask } func addBorder(mask: CAShapeLayer, borderColor: UIColor, borderWidth: CGFloat) { let borderLayer = CAShapeLayer() borderLayer.path = mask.path borderLayer.fillColor = UIColor.clear.cgColor borderLayer.strokeColor = borderColor.cgColor borderLayer.lineWidth = borderWidth borderLayer.frame = bounds layer.addSublayer(borderLayer) } }


Sobre la base de la excelente respuesta de Sanjay, escribí una rápida extensión CALayer para Swift 2.3, en caso de que necesites hacer algo así como "solo redondear algunas esquinas" más de una vez.

extension CALayer { func roundCorners(corners: UIRectCorner, radius: CGFloat) { let maskPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius)) let shape = CAShapeLayer() shape.path = maskPath.CGPath mask = shape } }

Uso:

myView.layer.roundCorners([.TopLeft, .TopRight], radius: myCornerRadius)

Swift 3.0 (en este ejemplo, los límites vinieron de la vista no de la capa. Usando los límites de la vista, haga que este código funcione con vistas en un UITableViewCell.):

func roundCorners(corners: UIRectCorner, radius: CGFloat, viewBounds: CGRect) { let maskPath = UIBezierPath(roundedRect: viewBounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius)) let shape = CAShapeLayer() shape.path = maskPath.cgPath mask = shape }

Uso:

myView.layer.roundCorners(corners: [.topLeft, .topRight], radius: myCornerRadius, viewBounds: bounds)


Versión de Objective-C de la respuesta de iWasRobbed:

UIView + RoundCorners.h

#import <UIKit/UIKit.h> @interface UIView (RoundCorners) /** Rounds the given set of corners to the specified radius - parameter corners: Corners to round - parameter radius: Radius to round to */ - (void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius; /** Rounds the given set of corners to the specified radius with a border - parameter corners: Corners to round - parameter radius: Radius to round to - parameter borderColor: The border color - parameter borderWidth: The border width */ - (void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth; /** Fully rounds an autolayout view (e.g. one with no known frame) with the given diameter and border - parameter diameter: The view''s diameter - parameter borderColor: The border color - parameter borderWidth: The border width */ - (void)fullyRoundWithDiameter:(CGFloat)diameter borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth; @end

UIView + RoundCorners.m

#import "UIView+RoundCorners.h" @implementation UIView (RoundCorners) - (void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius { [self _roundCorners:corners radius:radius]; } - (void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth { CAShapeLayer *mask = [self _roundCorners:corners radius:radius]; [self addBorderWithMask:mask borderColor:borderColor borderWidth:borderWidth]; } - (void)fullyRoundWithDiameter:(CGFloat)diameter borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth { self.layer.masksToBounds = YES; self.layer.cornerRadius = diameter / 2; self.layer.borderWidth = borderWidth; self.layer.borderColor = borderColor.CGColor; } - (CAShapeLayer *)_roundCorners:(UIRectCorner)corners radius:(CGFloat)radius { UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius, radius)]; CAShapeLayer *mask = [CAShapeLayer layer]; mask.path = path.CGPath; self.layer.mask = mask; return mask; } - (void)addBorderWithMask:(CAShapeLayer *)mask borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth { CAShapeLayer *borderLayer = [CAShapeLayer layer]; borderLayer.path = mask.path; borderLayer.fillColor = UIColor.clearColor.CGColor; borderLayer.strokeColor = borderColor.CGColor; borderLayer.lineWidth = borderWidth; borderLayer.frame = self.bounds; [self.layer addSublayer:borderLayer]; } @end


Swift 3 - UIView útil de UIView cuando necesita redondear esquinas específicas de algunas vistas:

extension UIView { func round(corners: UIRectCorner, radius: CGFloat) { let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius)) let mask = CAShapeLayer() mask.path = path.cgPath self.layer.mask = mask } }

entonces solo úsalo así:

someView.round(corners: [.topLeft, .topRight], radius: 5)


Swift 4+, iOS 11+

Si ya tiene una UIView llamada myView referenciada como un IBOutlet , intente agregar las siguientes dos líneas en ViewDidLoad() o donde sea que se esté cargando:

myView.layer.cornerRadius = 10 myView.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]

Puede cambiar la matriz [] a cualquier combinación de MinX , MinY , MaxX y MaxY para seleccionar las esquinas deseadas. El ejemplo anterior redondea las dos esquinas inferiores.

Este es solo otro enfoque, puede ser un poco más simple dependiendo de su diseño.


Swift 4:

let maskPath = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: [.allCorners], cornerRadii: CGSize(width: 10.0, height: 10.0)) let shape = CAShapeLayer() shape.path = maskPath.cgPath cell.layer.mask = shape return cell