如何只为UIView的左上角和右上角设置cornerRadius?


407

有没有一种方法可以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;

9
编辑后,需要解决三件事:(1)舍入路径应基于而view.bounds不是frame(2)图层应为CAShapeLayer而不是CALayer;(3)设置图层的path,而不是shadowPath
Kurt Revis '04

1
问题答案的可能重复项。
Stuart

使用Bezier曲线算法,在CGPath上创建曲线。我很确定它是CoreGraphics的一部分。如果不是这样,en.wikipedia.org / wiki /Bézier_curve具有一些出色的定义和动画效果。
Nate Symer


在这里查看我的答案:stackoverflow.com/a/50396485/6246128
wcarhart

Answers:


224

请注意以下事实:如果您附加了布局约束,则必须在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
    }
}

3
这绝对不是一个答案,作者问的是如何使特定的角变圆,而不是如何使角半径与布局更改同步。
凯琳18'Mar

1
这是没有道理的答案。
Tiago Couto

1
答案已在近期得到解决。.@kelin
Michael

2
这肯定圆了。
aznelite89 '19

视图出现后,您必须执行此操作
乔纳森(Jonathan)。

535

我不确定为什么您的解决方案无效,但是以下代码对我有效。创建贝塞尔曲线蒙版并将其应用于您的视图。在下面的代码中,我_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;

Swift版本有一些改进:

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

Swift扩展在这里


2
在文本字段中尝试。左路成功,右路失败

10
@RainerLiao我有同样的问题,我在viewDidLoad方法上做了所有这些viewDidAppear工作,将其移至它并起作用了。
卢乔(Lucho)2015年

如何将其设置为适用于任何设备。这仅适用于simulator情节提要的大小。ex: if the simulator size is 6s it works fine for 6s, but not of others.我该如何克服这个问题。
Chanaka火山口16/09/21

1
Swift 3版本中的小语法错误:path.CGPath应该是path.cgPath
Rob

@RainerLiao如果您不希望它在视图显示时闪烁,请将其更改为viewWillAppear。这也有效。
马修·肯尼彭

263

这是@JohnnyRockex答案的Swift版本

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)

注意

如果您使用的是Auto Layout,则需要将其子类化UIView并调用roundCorners视图的layoutSubviews以获得最佳效果。

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

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

12
很好的扩展。然而:.TopRight.BottomRight不似乎为我工作。
Onichan 2015年

4
Swift 2上view.roundCorners([.TopLeft , .BottomLeft], radius: 10)
fahrulazmi

2
它无法在“右侧”上正常工作,因为您的视图范围尚未使用自动版式很好地定义...我目前也面临着同样的问题。
dosdos

3
@dosdos视图的子类,并在layoutSubviews中围绕自身。
Arbitur

10
如果您使用自动布局,并且尚未对要舍入的视图进行引用.layoutIfNeeded(),则可以调用,然后调用此方法。
zgjie

209

最后…… iOS11中有CACornerMask!使用CACornerMask它可以很容易地完成:

let view = UIView()
view.clipsToBounds = true
view.layer.cornerRadius = 10
view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner] // Top right corner, Top left corner respectively

1
这绝对是最好的。在舍入动态调整tableview单元大小的边缘时,其他解决方案总是存在问题。
–cornr

2
专案必须支援iOS 11以上版本,才能使用该解决方案。
外星人

13
@Aliens和...我提到了。
谢尔盖·贝卢斯

1
其他答案在旋转设备时不起作用,此代码可旋转,并且允许您将某些角转成圆角,这应该是公认的答案。
Cloud9999Strife

1
简单就是美丽
eharo2

99

此处的Swift代码示例:https : //stackoverflow.com/a/35621736/308315


不直接。你不得不:

  1. 创建一个 CAShapeLayer
  2. 将其设置pathCGPathRef基于,view.bounds但只有两个圆角(可能使用+[UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:]
  3. 将您view.layer.mask设为CAShapeLayer

21
请注意,如果您
仅凭

@jjxtra那么,在没有太多性能损失的情况下实现它的最佳方法是什么?我想在UITableViewCell中显示它。
xi.lin

我记得设置layer.shouldRasterize == YES时 @ xi.lin 可以将速度提高5倍左右。但是文档说只有在使用非透明单元格时它才有效。试一试。
codrut

64

这是一个像这样实现的简短方法:

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

设置颜色呢?maskLayer.borderWidth = 10; maskLayer.borderColor = [UIColor redColor] .CGColor; 先生,这对我不起作用。
kiran

1
@kiran面具没有颜色,如果您想有边框,可以添加第二个CAShapeLayer
Johnny Rockex 18'2-20

25

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

如果要在情节提要中使用自动调整大小,请在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
    }
}

1
它不工作的iOS 9,但工作在11
阿里·伊赫桑乌拉尔

iOS 9的任何解决方案?
jey

@jay let rectShape = CAShapeLayer()rectShape.bounds = detailsS​​ubView.frame rectShape.position = detailsS​​ubView.center rectShape.path = UIBezierPath(roundedRect:detailsS​​ubView.bounds,byRoundingCorners:[.topLeft,.topRight],cornerRadii:CGSize(width: 20,高度:20))。cgPath detailsS​​ubView.layer.mask = rectShape此代码适用于iOS 9
iOS

@jay检查是否未通知我
iOS

不适用于ios9。角落部分没有边框。
jey

24

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
}

您可以在表格视图单元格中使用它。


1
这是当今编码的正确答案。再见,遮罩层。
艾伦·梁

1
这一定是最好的答案!
fujianjin6471

18

这将是最简单的答案:

yourView.layer.cornerRadius = 8
yourView.layer.masksToBounds = true
yourView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]

标记这是适用于iOS 11或更高版本的解决方案
Ankur Lahiry

16

试试这个代码,

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;

15

艾玛(Emma):.TopRight并且.BottomRight对您不起作用,可能是因为计算view.roundCorners了最终调用之前已完成对的调用view bounds。请注意,Bezier Path派生自其调用时的视图范围。例如,如果自动布局会缩小视图范围,则右侧的圆角可能在视图范围之外。尝试在中将其称为viewDidLayoutSubviews最终视图的中调用它。


谢谢。对我来说,解决问题的方法是将对“ Arbitur”给出的实现的调用从viewDidLoad和viewWillAppear移到viewDidAppear。我可以这样做,因为我的控件最初设置为隐藏。
Matti

你是对的。它将产生自动布局问题,您做得很好。
Ashish Kakkad '16

15

1行中的Swift 4 Swift 5简单方法

用法:

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

在Objective-C中

用法:

[self.verticalSeparatorView roundCorners:UIRectCornerTopLeft radius:10.0];

类别中使用的功能(仅一个角):

-(void)roundCorners: (UIRectCorner) corners radius:(CGFloat)radius {
        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius, radius)];
        CAShapeLayer *mask = [[CAShapeLayer alloc] init];
        mask.path = path.CGPath;
        self.layer.mask = mask;
    }

只记住,在完成viewDidLayoutSubviews之后才计算视图的角,因此您应该在其中调用roundCorners函数
Jirson Tavera

您能告诉我如何在此视图中添加阴影吗?
Vadlapalli Masthan

@ShakeelAhmed如果要向视图添加阴影,则此方法将不起作用。
mojtaba al moussawi

首先添加圆角半径,然后添加阴影
Shakeel Ahmed

10

我的快速解决UIView和UITextFiels特定角的解决方案是使用

.layer.cornerRadius

layer.maskedCorners

实际的UIView或UITextFields。

例:

fileprivate func inputTextFieldStyle() {
        inputTextField.layer.masksToBounds = true
        inputTextField.layer.borderWidth = 1
        inputTextField.layer.cornerRadius = 25
        inputTextField.layer.maskedCorners = [.layerMaxXMaxYCorner,.layerMaxXMinYCorner]
        inputTextField.layer.borderColor = UIColor.white.cgColor
    }

并通过使用

.layerMaxXMaxYCorner

.layerMaxXMinYCorner

,我可以指定要舍入的UITextField的右上角和右下角。

您可以在此处查看结果:

在此处输入图片说明


完美的边界和特定角落组合combination
nomnom

8

斯威夫特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
        }
    }
}

在我的情况下,您节省了我的一天,我不得不对特定单元格的表视图进行四舍五入
Shakti,

根据我的要求完美。我使用了所有答案,没有任何帮助,但是您的答案帮助了我,解决了我的问题。
Nikita Patil

6

以编程方式执行此操作的一种方法UIView是在UIView具有圆角的顶部上方创建一个。或者,您可以将顶部隐藏在某些东西下面。


6
它是一个非常丑陋的解决方案:P
Arbitur 2014年

6
    // 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's layer
view.layer.mask = maskLayer;

4

最简单的方法是制作带有圆角层的蒙版。

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>

4

已经给出的所有答案都是非常好的和有效的(尤其是Yunus使用该mask属性的想法)。

但是,我需要更复杂的东西,因为我的图层可能经常更改大小,这意味着我每次都需要调用该屏蔽逻辑,这有点烦人。

我使用了swift extensions和计算属性来构建一个真实cornerRadii属性,该属性负责在布局图层时自动更新蒙版。

这是使用Peter Steinberg出色的Aspects库实现的。

完整代码在这里:

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

我写了一个简单的博客文章来解释这一点。



2

这是使用C#在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;

2

一个很好的扩展,可以重用Yunus Nedim Mehel解决方案

迅捷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])

不错的清洁解决方案
Aggressor

1

更改代码后@apinho在迅速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])

0

Stephane答案的另一个版本。

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
        }

    }

0

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

}

0

简单扩展

extension UIView {
    func roundCorners(corners: UIRectCorner, radius: CGFloat) {
        if #available(iOS 11, *) {
            self.clipsToBounds = true
            self.layer.cornerRadius = radius
            var masked = CACornerMask()
            if corners.contains(.topLeft) { masked.insert(.layerMinXMinYCorner) }
            if corners.contains(.topRight) { masked.insert(.layerMaxXMinYCorner) }
            if corners.contains(.bottomLeft) { masked.insert(.layerMinXMaxYCorner) }
            if corners.contains(.bottomRight) { masked.insert(.layerMaxXMaxYCorner) }
            self.layer.maskedCorners = masked
        }
        else {
            let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
            let mask = CAShapeLayer()
            mask.path = path.cgPath
            layer.mask = mask
        }
    }
}

用法:

view.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 12)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.