Округленный UIView с использованием CALayers - только некоторые углы - Как? - PullRequest
119 голосов
/ 15 февраля 2010

В моем приложении четыре кнопки, названные так:

  • Верх - левый
  • Внизу - слева
  • Вверху - справа
  • Внизу - справа

Над кнопками находится вид изображения (или UIView).

Теперь предположим, что пользователь нажимает на верхнюю левую кнопку. Выше изображение / вид должны быть округлены в этом конкретном углу.

У меня возникли сложности с применением закругленных углов к UIView.

Сейчас я использую следующий код, чтобы применить закругленные углы к каждому представлению:

    // imgVUserImg is a image view on IB.
    imgVUserImg.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"any Url Here"];
    CALayer *l = [imgVUserImg layer];
    [l setMasksToBounds:YES];
    [l setCornerRadius:5.0];  
    [l setBorderWidth:2.0];
    [l setBorderColor:[[UIColor darkGrayColor] CGColor]];

Вышеуказанный код применяет округлость к каждому из углов предоставленного вида. Вместо этого я просто хотел применить округлость к выбранным углам, таким как - верх / верх + левый / нижний + правый и т. Д.

Возможно ли это? Как?

Ответы [ 14 ]

2 голосов
/ 21 мая 2015

Скругление только некоторых углов не будет хорошо работать с автоматическим изменением размера или автоматическим макетом.

Поэтому другой вариант - использовать обычный cornerRadius и скрывать углы, которые вам не нужны, под другим видом или за его пределами.границы superview, чтобы убедиться, что он настроен на обрезку содержимого.

1 голос
/ 27 марта 2017

Чтобы добавить к ответу и добавлению , я создал простой, многократно используемый UIView в Swift. В зависимости от вашего варианта использования вы можете захотеть внести изменения (избегайте создания объектов на каждом макете и т. Д.), Но я хотел, чтобы это было как можно проще. Расширение позволяет вам применять это к другим представлениям (например, UIImageView) проще, если вам не нравится подклассы.

extension UIView {

    func roundCorners(_ roundedCorners: UIRectCorner, toRadius radius: CGFloat) {
        roundCorners(roundedCorners, toRadii: CGSize(width: radius, height: radius))
    }

    func roundCorners(_ roundedCorners: UIRectCorner, toRadii cornerRadii: CGSize) {
        let maskBezierPath = UIBezierPath(
            roundedRect: bounds,
            byRoundingCorners: roundedCorners,
            cornerRadii: cornerRadii)
        let maskShapeLayer = CAShapeLayer()
        maskShapeLayer.frame = bounds
        maskShapeLayer.path = maskBezierPath.cgPath
        layer.mask = maskShapeLayer
    }
}

class RoundedCornerView: UIView {

    var roundedCorners: UIRectCorner = UIRectCorner.allCorners
    var roundedCornerRadii: CGSize = CGSize(width: 10.0, height: 10.0)

    override func layoutSubviews() {
        super.layoutSubviews()
        roundCorners(roundedCorners, toRadii: roundedCornerRadii)
    }
}

Вот как бы вы применили его к UIViewController:

class MyViewController: UIViewController {

    private var _view: RoundedCornerView {
        return view as! RoundedCornerView
    }

    override func loadView() {
        view = RoundedCornerView()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        _view.roundedCorners = [.topLeft, .topRight]
        _view.roundedCornerRadii = CGSize(width: 10.0, height: 10.0)
    }
}
0 голосов
/ 31 октября 2018

Я бы предложил определить маску слоя. Сама маска должна быть CAShapeLayer объектом с выделенным путем. Вы можете использовать следующее расширение UIView (Swift 4.2):

extension UIView {
    func round(corners: UIRectCorner, with radius: CGFloat) {
        let maskLayer = CAShapeLayer()
        maskLayer.frame = bounds
        maskLayer.path = UIBezierPath(
            roundedRect: bounds,
            byRoundingCorners: corners,
            cornerRadii: CGSize(width: radius, height: radius)
        ).cgPath
        layer.mask = maskLayer
   }
}
0 голосов
/ 18 июня 2015

Завершая ответ Стюарта, вы можете использовать метод скругления углов следующим образом:

@implementation UIView (RoundCorners)

- (void)applyRoundCorners:(UIRectCorner)corners radius:(CGFloat)radius {
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius, radius)];

    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = self.bounds;
    maskLayer.path = maskPath.CGPath;

    self.layer.mask = maskLayer;
}

@end

Итак, чтобы применить закругление угла, вы просто делаете:

[self.imageView applyRoundCorners:UIRectCornerTopRight|UIRectCornerTopLeft radius:10];
...