快速创build一个只有两个圆angular的矩形?
我需要在swift中创build一个只有两个圆angular的矩形(Objective C代码也可以)。
目前我的代码正在创build两个矩形
CGPathCreateWithRoundedRect(CGRectMake(0, 0, 30, 60), 5, 5, nil);
和
CGPathCreateWithRoundedRect(CGRectMake(0, 0, 30, 60), 0, 0, nil);
并合并它们(有两个直angular和两个圆angular的),但是我对代码不满意,我很确定应该有更好的方法来做到这一点。
我是新来的iOS和graphics开发和迅速。
在Swift 2.3中你可以这样做
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
在Objective-C中,您可以使用UIBezierPath
类方法
bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:
示例实现 –
// 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; }
并调用上面的方法as-
[self setMaskTo:anyView byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight];
这里有一个快速的Swift 3扩展,你可以使用它进行舍入和可选的边界。
请注意:如果您使用的是自动布局,则可能需要在视图生效后调用此视图,例如viewDidLayoutSubviews
或layoutSubviews
。
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 (eg 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) } }
这里是你在Swift 2.0中所做的
var maskPath = UIBezierPath(roundedRect: anyView.bounds, byRoundingCorners: [.BottomLeft, .BottomRight], cornerRadii: CGSize(width: 10.0, height: 10.0))
build立在Sanjay的优秀答案之上,我为Swift 2.3写了一个快速的CALayer扩展,以防止你不止一次地做这种“只有一些angular落”的事情。
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 } }
用法:
myView.layer.roundCorners([.TopLeft, .TopRight], radius: myCornerRadius)
Swift 3.0(在这个例子中,边界来自视图而不是来自图层,使用视图边界使这个代码在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 }
用法:
myView.layer.roundCorners(corners: [.topLeft, .topRight], radius: myCornerRadius, viewBounds: bounds)
Swift 3 – 有用的UIView
扩展当你需要舍入一些视图的特定angular落:
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 } }
那么就像这样使用它:
someView.round(corners: [.topLeft, .topRight], radius: 5)
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 } }
只有一些angular落,只需改变:
roundedRect: self.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: r, height: r)
请注意,像往常一样,在Swift中有很多小的变化,例如常量的大写等等。
Objective-C版本的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 (eg 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
更新了iWasRobbed与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 (eg 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) } }
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