551 Stimmen

Wie kann man den cornerRadius nur für die obere linke und obere rechte Ecke einer UIView festlegen?

Gibt es eine Möglichkeit, den cornerRadius nur für die obere linke und obere rechte Ecke einer UIView zu setzen?

Ich habe Folgendes versucht, aber danach konnte ich die Ansicht nicht mehr sehen.

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;

9 Stimmen

Nach Ihrer Bearbeitung drei Dinge zu beheben: (1) der abgerundete Pfad sollte auf view.bounds basieren, nicht auf frame, (2) die Ebene sollte ein CAShapeLayer sein, nicht CALayer; (3) setzen Sie den path der Ebene, nicht shadowPath.

1 Stimmen

Möglicher Duplikat dieser Frage & Antwort.

0 Stimmen

Verwenden Sie den Bezier-Kurvenalgorithmus, um Kurven auf einem CGPath zu erstellen. Ich bin mir ziemlich sicher, dass es Teil von CoreGraphics ist. Wenn nicht, hat en.wikipedia.org/wiki/Bézier_curve einige großartige Definitionen und Animationen.

565voto

Yunus Nedim Mehel Punkte 11689

Ich weiß nicht, warum Ihre Lösung nicht funktioniert hat, aber der folgende Code funktioniert für mich. Erstellen Sie eine Bezier-Maske und wenden Sie sie auf Ihre Ansicht an. In meinem unten stehenden Code habe ich die unteren Ecken des _backgroundView mit einem Radius von 3 Pixel gerundet. self ist eine benutzerdefinierte 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;

Swift 2.0 Version mit einigen Verbesserungen:

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 Version:

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

Swift-Erweiterung hier

454voto

Sergei Belous Punkte 4358

Und schließlich… gibt es in iOS11 CACornerMask! Mit CACornerMask geht es ziemlich einfach:

let view = UIView()
view.clipsToBounds = true
view.layer.cornerRadius = 10
view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner] // Oben rechts, oben links Ecke jeweils

371voto

Stéphane de Luca Punkte 11632

Achten Sie darauf, dass wenn Sie Layout-Einschränkungen daran angehängt haben, müssen Sie dies wie folgt in Ihrer UIView-Unterklasse aktualisieren:

override func layoutSubviews() {
    super.layoutSubviews()
    roundCorners(corners: [.topLeft, .topRight], radius: 3.0)
}

Sonst wird es nicht angezeigt.


Und um Ecken abzurunden, verwenden Sie die Erweiterung:

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
    }
}


Zusätzlicher ViewController-Fall: Wenn Sie eine Ansicht nicht unterklasse oder nicht unterklasse möchten, können Sie eine Ansicht dennoch abrunden. Machen Sie es von seinem ViewController aus, indem Sie die Funktion viewWillLayoutSubviews() überschreiben, wie folgt:

class MyVC: UIViewController {
    /// Die Ansicht, an der die oberen linken und oberen rechten Ecken abgerundet werden sollen
    let theView: UIView = {
        let v = UIView(frame: CGRect(x: 10, y: 10, width: 200, height: 200))
        v.backgroundColor = .red
        return v
    }()

    override func loadView() {
        super.loadView()
        view.addSubview(theView)
    }

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()

        // Rufen Sie die roundCorners() Funktion direkt dort auf.
        theView.roundCorners(corners: [.topLeft, .topRight], radius: 30)
    }
}

287voto

Arbitur Punkte 37971

Hier ist eine Swift-Version von @JohnnyRockexs Antwort

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)

Notiz

Wenn Sie Auto Layout verwenden, müssen Sie Ihr UIView unterklasse und roundCorners in layoutSubviews des Views aufrufen, um eine optimale Wirkung zu erzielen.

class View: UIView {
    override func layoutSubviews() {
        super.layoutSubviews()

        self.roundCorners([.topLeft, .bottomLeft], radius: 10)
    }
}

102voto

Kurt Revis Punkte 27478

Beispielcode für Swift hier: https://stackoverflow.com/a/35621736/308315


Nicht direkt. Du musst:

  1. Eine CAShapeLayer erstellen
  2. Setze den path auf einen CGPathRef basierend auf view.bounds, aber nur mit zwei abgerundeten Ecken (vermutlich durch Verwendung von +[UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:])
  3. Setze dein view.layer.mask auf die CAShapeLayer

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X