Как установить cornerRadius только для верхнего левого и верхнего правого угла UIView?
Есть ли способ установить cornerRadius
только для верхнего левого и верхнего правого угла UIView
?
Я попробовал следующее, но в итоге я больше не видел.
UIView *view = [[UIView alloc] initWithFrame:frame];
CALayer *layer = [CALayer layer];
UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:frame byRoundingCorners:(UIRectCornerTopLeft|UIRectCornerTopRight) cornerRadii:CGSizeMake(3.0, 3.0)];
layer.shadowPath = shadowPath.CGPath;
view.layer.mask = layer;
Ответы
Ответ 1
Swift 4
Обратите внимание на тот факт, что если у вас есть ограничения макета, вы должны обновить это следующим образом в своем подклассе UIView:
override func layoutSubviews() {
super.layoutSubviews()
roundCorners(corners: [.topLeft, .topRight], radius: 3.0)
}
Если вы этого не сделаете, он не появится.
А для закругления углов используйте расширение:
extension UIView {
func roundCorners(corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
layer.mask = mask
}
}
Ответ 2
Я не уверен, почему ваше решение не работает, но для меня работает следующий код. Создайте маску безье и примените ее к вашему виду. В моем коде ниже я округлял нижние углы _backgroundView
с радиусом 3 пикселя. self
является обычным UITableViewCell
:
UIBezierPath *maskPath = [UIBezierPath
bezierPathWithRoundedRect:self.backgroundImageView.bounds
byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight)
cornerRadii:CGSizeMake(20, 20)
];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = self.bounds;
maskLayer.path = maskPath.CGPath;
self.backgroundImageView.layer.mask = maskLayer;
Быстрая версия с некоторыми улучшениями:
let path = UIBezierPath(roundedRect:viewToRound.bounds, byRoundingCorners:[.TopRight, .BottomLeft], cornerRadii: CGSizeMake(20, 20))
let maskLayer = CAShapeLayer()
maskLayer.path = path.CGPath
viewToRound.layer.mask = maskLayer
версия Swift 3.0:
let path = UIBezierPath(roundedRect:viewToRound.bounds,
byRoundingCorners:[.topRight, .bottomLeft],
cornerRadii: CGSize(width: 20, height: 20))
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
viewToRound.layer.mask = maskLayer
Быстрое расширение здесь
Ответ 3
Вот версия Swift ответа @JohnnyRockex
extension UIView {
func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
}
view.roundCorners([.topLeft, .bottomRight], radius: 10)
Примечание
Если вы используете Автомакет, вам необходимо подклассифицировать UIView
и вызвать roundCorners
в представлении layoutSubviews
для оптимального эффекта.
class View: UIView {
override func layoutSubviews() {
super.layoutSubviews()
self.roundCorners([.topLeft, .bottomLeft], radius: 10)
}
}
Ответ 4
И, наконец ,... есть CACornerMask в iOS11! С CACornerMask
это можно сделать довольно просто:
let view = UIView()
view.clipsToBounds = true
view.layer.cornerRadius = 10
view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner] // Top right corner, Top left corner respectively
Ответ 5
Пример кода Swift: fooobar.com/questions/28274/...
Не напрямую. Вам нужно будет:
Ответ 6
Вот короткий метод, реализованный следующим образом:
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *openInMaps = [UIButton new];
[openInMaps setFrame:CGRectMake(15, 135, 114, 70)];
openInMaps = (UIButton *)[self roundCornersOnView:openInMaps onTopLeft:NO topRight:NO bottomLeft:YES bottomRight:NO radius:5.0];
}
- (UIView *)roundCornersOnView:(UIView *)view onTopLeft:(BOOL)tl topRight:(BOOL)tr bottomLeft:(BOOL)bl bottomRight:(BOOL)br radius:(float)radius {
if (tl || tr || bl || br) {
UIRectCorner corner = 0;
if (tl) {corner = corner | UIRectCornerTopLeft;}
if (tr) {corner = corner | UIRectCornerTopRight;}
if (bl) {corner = corner | UIRectCornerBottomLeft;}
if (br) {corner = corner | UIRectCornerBottomRight;}
UIView *roundedView = view;
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:roundedView.bounds byRoundingCorners:corner cornerRadii:CGSizeMake(radius, radius)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = roundedView.bounds;
maskLayer.path = maskPath.CGPath;
roundedView.layer.mask = maskLayer;
return roundedView;
}
return view;
}
Ответ 7
В swift 4.1 и Xcode 9.4.1
В iOS 11 достаточно одной строки:
detailsSubView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]//Set your view here
Смотрите полный код:
//In viewDidLoad
if #available(iOS 11.0, *){
detailsSubView.clipsToBounds = false
detailsSubView.layer.cornerRadius = 10
detailsSubView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
} else {
//For lower versions
}
Но для более низких версий
let rectShape = CAShapeLayer()
rectShape.bounds = detailsSubView.frame
rectShape.position = detailsSubView.center
rectShape.path = UIBezierPath(roundedRect: detailsSubView.bounds, byRoundingCorners: [.topLeft , .topRight], cornerRadii: CGSize(width: 20, height: 20)).cgPath
detailsSubView.layer.mask = rectShape
Полный код есть.
if #available(iOS 11.0, *){
detailsSubView.clipsToBounds = false
detailsSubView.layer.cornerRadius = 10
detailsSubView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
}else{
let rectShape = CAShapeLayer()
rectShape.bounds = detailsSubView.frame
rectShape.position = detailsSubView.center
rectShape.path = UIBezierPath(roundedRect: detailsSubView.bounds, byRoundingCorners: [.topLeft , .topRight], cornerRadii: CGSize(width: 20, height: 20)).cgPath
detailsSubView.layer.mask = rectShape
}
Если вы используете AutoResizing в раскадровке, напишите этот код в viewDidLayoutSubviews().
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if #available(iOS 11.0, *){
detailsSubView.clipsToBounds = false
detailsSubView.layer.cornerRadius = 10
detailsSubView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
}else{
let rectShape = CAShapeLayer()
rectShape.bounds = detailsSubView.frame
rectShape.position = detailsSubView.center
rectShape.path = UIBezierPath(roundedRect: detailsSubView.bounds, byRoundingCorners: [.topLeft , .topRight], cornerRadii: CGSize(width: 20, height: 20)).cgPath
detailsSubView.layer.mask = rectShape
}
}
Ответ 8
iOS 11, Swift 4
И вы можете попробовать этот код:
if #available(iOS 11.0, *) {
element.clipsToBounds = true
element.layer.cornerRadius = CORNER_RADIUS
element.layer.maskedCorners = [.layerMaxXMaxYCorner]
} else {
// Fallback on earlier versions
}
И вы можете использовать это в ячейке табличного представления.
Ответ 9
Попробуйте этот код,
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:( UIRectCornerTopLeft | UIRectCornerTopRight) cornerRadii:CGSizeMake(5.0, 5.0)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.view.bounds;
maskLayer.path = maskPath.CGPath;
view.layer.mask = maskLayer;
Ответ 10
Эмма: .TopRight
и .BottomRight
не работают для вас, возможно, потому что вызов view.roundCorners
выполняется ДО того, как будут вычислены конечные view bounds
представления. Обратите внимание, что Bezier Path
происходит от границ представления во время его вызова. Например, если автоматическое расположение сузит вид, закругленные углы с правой стороны могут быть за пределами вида. Попробуйте вызвать его в viewDidLayoutSubviews
, где граница представления является окончательной.
Ответ 11
Swift 4 Swift 5 простой способ в 1 линию
Использование:
//MARK:- Corner Radius of only two side of UIViews
self.roundCorners(view: yourview, corners: [.bottomLeft, .topRight], radius: 12.0)
Функция:
//MARK:- Corner Radius of only two side of UIViews
func roundCorners(view :UIView, corners: UIRectCorner, radius: CGFloat){
let path = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
view.layer.mask = mask
}
Ответ 12
Для этого программным способом было бы создать UIView
поверх верхней части UIView
с закругленными углами. Или вы можете скрыть верх над чем-то.
Ответ 13
Swift 4
extension UIView {
func roundTop(radius:CGFloat = 5){
self.clipsToBounds = true
self.layer.cornerRadius = radius
if #available(iOS 11.0, *) {
self.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]
} else {
// Fallback on earlier versions
}
}
func roundBottom(radius:CGFloat = 5){
self.clipsToBounds = true
self.layer.cornerRadius = radius
if #available(iOS 11.0, *) {
self.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMinXMaxYCorner]
} else {
// Fallback on earlier versions
}
}
}
Ответ 14
// Create the path (with only the top-left corner rounded)
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds
byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight)
cornerRadii:CGSizeMake(7.0, 7.0)];
// Create the shape layer and set its path
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = cell.stripBlackImnageView.bounds;
maskLayer.path = maskPath.CGPath;
// Set the newly created shapelayer as the mask for the image view layer
view.layer.mask = maskLayer;
Ответ 15
Все приведенные ответы действительно хороши и достоверны (особенно идея Yunus об использовании свойства mask
).
Однако мне было нужно что-то более сложное, потому что мой слой часто менял размеры, что означало, что мне приходилось каждый раз называть эту маскирующую логику, и это было немного раздражающе.
Я использовал swift extensions
и вычислял свойства для создания реального свойства cornerRadii
, которое заботится об автоматическом обновлении маски при прокладке слоя.
Это было достигнуто с помощью Peter Steinberg great Aspects библиотека для swizzling.
Полный код находится здесь:
extension CALayer {
// This will hold the keys for the runtime property associations
private struct AssociationKey {
static var CornerRect:Int8 = 1 // for the UIRectCorner argument
static var CornerRadius:Int8 = 2 // for the radius argument
}
// new computed property on CALayer
// You send the corners you want to round (ex. [.TopLeft, .BottomLeft])
// and the radius at which you want the corners to be round
var cornerRadii:(corners: UIRectCorner, radius:CGFloat) {
get {
let number = objc_getAssociatedObject(self, &AssociationKey.CornerRect) as? NSNumber ?? 0
let radius = objc_getAssociatedObject(self, &AssociationKey.CornerRadius) as? NSNumber ?? 0
return (corners: UIRectCorner(rawValue: number.unsignedLongValue), radius: CGFloat(radius.floatValue))
}
set (v) {
let radius = v.radius
let closure:((Void)->Void) = {
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: v.corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.CGPath
self.mask = mask
}
let block: @convention(block) Void -> Void = closure
let objectBlock = unsafeBitCast(block, AnyObject.self)
objc_setAssociatedObject(self, &AssociationKey.CornerRect, NSNumber(unsignedLong: v.corners.rawValue), .OBJC_ASSOCIATION_RETAIN)
objc_setAssociatedObject(self, &AssociationKey.CornerRadius, NSNumber(float: Float(v.radius)), .OBJC_ASSOCIATION_RETAIN)
do { try aspect_hookSelector("layoutSublayers", withOptions: .PositionAfter, usingBlock: objectBlock) }
catch _ { }
}
}
}
Я написал простое сообщение , объясняющее это.
Ответ 16
Самый простой способ - сделать маску с закругленным угловым слоем.
CALayer *maskLayer = [CALayer layer];
maskLayer.frame = CGRectMake(0,0,maskWidth ,maskHeight);
maskLayer.contents = (__bridge id)[[UIImage imageNamed:@"maskImageWithRoundedCorners.png"] CGImage];
aUIView.layer.mask = maskLayer;
И не забывайте:
#import <QuartzCore/QuartzCore.h>
Ответ 17
Так вы можете установить радиус угла для каждого угла кнопки с Xamarin в С#:
var maskPath = UIBezierPath.FromRoundedRect(MyButton.Bounds, UIRectCorner.BottomLeft | UIRectCorner.BottomRight,
new CGSize(10.0, 10.0));
var maskLayer = new CAShapeLayer
{
Frame = MyButton.Bounds,
Path = maskPath.CGPath
};
MyButton.Layer.Mask = maskLayer;
Ответ 18
Прекрасное расширение для повторного использования решения Yunus Nedim Mehel
Swift 2.3
extension UIView {
func roundCornersWithLayerMask(cornerRadii: CGFloat, corners: UIRectCorner) {
let path = UIBezierPath(roundedRect: bounds,
byRoundingCorners: corners,
cornerRadii: CGSize(width: cornerRadii, height: cornerRadii))
let maskLayer = CAShapeLayer()
maskLayer.path = path.CGPath
layer.mask = maskLayer
} }
Использование
let view = UIView()
view.roundCornersWithLayerMask(10,[.TopLeft,.TopRight])
Ответ 19
После изменения немного кода @apinho В Swift 4.3 работает нормально
extension UIView {
func roundCornersWithLayerMask(cornerRadii: CGFloat, corners: UIRectCorner) {
let path = UIBezierPath(roundedRect: bounds,
byRoundingCorners: corners,
cornerRadii: CGSize(width: cornerRadii, height: cornerRadii))
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
layer.mask = maskLayer
}
}
Чтобы использовать эту функцию для просмотра
YourViewName. roundCornersWithLayerMask(cornerRadii: 20,corners: [.topLeft,.topRight])
Ответ 20
Другая версия ответа Стефана.
import UIKit
class RoundCornerView: UIView {
var corners : UIRectCorner = [.topLeft,.topRight,.bottomLeft,.bottomRight]
var roundCornerRadius : CGFloat = 0.0
override func layoutSubviews() {
super.layoutSubviews()
if corners.rawValue > 0 && roundCornerRadius > 0.0 {
self.roundCorners(corners: corners, radius: roundCornerRadius)
}
}
private func roundCorners(corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
layer.mask = mask
}
}
Ответ 21
В Swift 4.2 создайте его с помощью @IBDesignable
следующим образом:
@IBDesignable
class DesignableViewCustomCorner: UIView {
@IBInspectable var cornerRadious: CGFloat = 0 {
didSet {
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: cornerRadious, height: cornerRadious))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
}
}
Ответ 22
И самый простой способ сделать это, вам нужно 2 просмотра
![введите описание изображения здесь]()