[Swift] 뷰의 특정 모서리에 round 처리하기 + border

2022. 3. 10. 21:39iOS/Swift

보통 뷰의 모서리를 다 둥글게 한다.

 

가끔 특정 모서리만 둥글게 하고 싶을 때도 있다.

 

근데 테두리도 넣어야한다?

구글링구글링..

 

 

 

모서리를 그리는 방법에는 두가지가 있다.

 

UIBezierPath와 CACornerMask

 

후자는 iOS 11이상부터 사용가능하다고 한다.

 

BezierPath로 둥근 모서리 만들기

let path = UIBezierPath(roundedRect: rectCornerView.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 12, height: 12))
let mask = CAShapeLayer()
mask.path = path.cgPath
rectCornerView.layer.mask = mask
rectCornerView.layer.masksToBounds = true

byRoundingCorners에 라운드 처리가 되길 바라는 부분들을 입럭한다.

직관적이라서 좋음

 

 

CACornerMask로 둥근 모서리 만들기

cornerMaskView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
cornerMaskView.layer.cornerRadius = 12
cornerMaskView.layer.masksToBounds = true

maskedCorners에 라운드 처리가 되길 바라는 부분을 입력한다.

(처음 봤을때는 ..? 였음)

당황하지 말자.

0 과 1 이라고 생각하면 된다.

 

min은 0 max 는 1로 생각하면 상대적으로 편하다.

 

 

결과물

잘 나오는군

끝~

 

 

이제 테두리를 넣어볼까?

 

let path = UIBezierPath(roundedRect: rectCornerView.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 12, height: 12))
let mask = CAShapeLayer()
mask.path = path.cgPath
rectCornerView.layer.borderColor = UIColor.red.cgColor
rectCornerView.layer.borderWidth = 1
rectCornerView.layer.mask = mask
rectCornerView.layer.masksToBounds = true

cornerMaskView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
cornerMaskView.layer.cornerRadius = 12
cornerMaskView.layer.borderColor = UIColor.red.cgColor
cornerMaskView.layer.borderWidth = 1
cornerMaskView.layer.masksToBounds = true

 

묘하게 이상하다

BezierPath에 border를 저렇게 넣으면 안되는군 음 음..

 

let mask = CAShapeLayer()
mask.path = path.cgPath
mask.lineWidth = 1
mask.fillColor = UIColor.clear.cgColor
mask.strokeColor = UIColor.red.cgColor
mask.frame = rectCornerView.bounds

 

?

시작은 가볍게 이런 방법있으니까 이렇게 쓰세요~ 였는데.. 

BezierPath 공부를 다시해야겠다 ㅎㅎ

strokeColor 넣어주면 되겠지~ 했는데 ..

 

 

구글링하다가 어떤 분 깃헙을 찾음...

 

Round specified corners of UIView

Round specified corners of UIView. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

흠.. 이분거 보면 round와 addborder를 따로 해준다.

addSublayer로..

 

func round(corners: UIRectCorner, radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
    let mask = round(corners: corners, radius: radius)
    addBorder(mask: mask, borderColor: borderColor, borderWidth: borderWidth)
}

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

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

흠.. 같이 쓰면 안되나부다

CAShapeLayer도 공부해야겠군...

묘하네 또..

뭔가 라인 너비가 다른거 같아서 색상을 투명으로 바꿔봤다.

 

다르다.. width는 둘 다 1이다..

 

위 부분에 대해선 더 알아봐야겠다..

 

혹시나 이유 아시는 분 있으면 댓글 좀..ㅜㅜ..

 

자신감 하락...ㅠ