clyne의 개발 기록

[Swift] 특정 모서리만 코너 Round주기 (corner, border) 본문

iOS/Swift

[Swift] 특정 모서리만 코너 Round주기 (corner, border)

clyne_dev 2021. 4. 30. 17:50

안녕하세요.

iOS 개발자 CNOO입니다!

     

오늘은 iOS 중, UIView의 특정 모서리에 코너를 주는 방법에 대해서 알아보도록 하겠습니다.

일반적으로 모든 모서리에 코너를 주는 방법은 아주 쉽습니다. (구글링하면 쏟아집니다..)

 

self.view.layer.cornerRadius = 8

 

이러한 코드 한줄이면 OK이죠

 

 

그런데 우리가 하고싶은 것은,  네 모서리에 다르게 값을 주거나, 특정 모서리에만  코너링을 주는 것이죠.!!

 

보통은  디자이너분께서 에셋을 잘 그려서 보내주시기도 하지만,

개발자가 직접 그려야하는 경우도 무지 많답니다! 

 

자! 그럼 결과물 먼저 보도록 하겠습니다.

 

 

 


결과물

 

특정 모서리에만 Radius를 주었습니다.

 

 

 

 

이런 모양의 뷰를 그리고싶다! 하면 계속해서 포스팅을 읽어주세요 ㅎㅎ

 

 

 


 

1. 3개의 뷰 객체 생성

먼저, UIView를  3개 생성해주도록 합니다.

(저는 여기서 Then 이라는 모듈을 썼는데, 굳이 안쓰시고  UIView의 배경을 설정하는 코드 넣어주셔도 됩니다!

 

 


lazy var myView01 = UIView().then {
    $0.backgroundColor = .systemPink
}

lazy var myView02 = UIView().then {
    $0.backgroundColor = .blue
}

lazy var myView02_inner = UIView().then {
    $0.backgroundColor = .systemBackground
}

myView01은 위에서 보신 빨간색 뷰 이구요,

myView02는  파란색 뷰예요!

inner는   02 뷰의 내부를 채워줄 뷰 입니다.

02뷰 자체에  borderWidth를 주면 되지 않느냐? 라는 질문을 하신다면!

포스팅 맨 아래쪽에   해당 방법으로 그리면 왜 안되는지 아실 수 있습니다 ㅎㅎ

 

 

 

 

2. 뷰 위치시켜주기

1번에서 3개의 뷰를 생성하셨다면, 이 3개의 뷰를  뷰 컨트롤러의 view 안에 추가해주도록 합시다.


override func viewDidLoad() {
    super.viewDidLoad()
    
    self.view.addSubview(myView01)
    self.view.addSubview(myView02)
    
    myView01.snp.makeConstraints {
        $0.centerX.equalToSuperview()
        $0.centerY.equalToSuperview().offset(80)
        $0.width.equalTo(180)
        $0.height.equalTo(100)
    }
    
    myView02.snp.makeConstraints {
        $0.centerX.equalToSuperview()
        $0.centerY.equalToSuperview().offset(-80)
        $0.width.equalTo(180)
        $0.height.equalTo(100)
    }
    
    myView02.addSubview(myView02_inner)
    let borderWidth = 10
    myView02_inner.snp.makeConstraints {
        $0.edges.equalToSuperview().offset(borderWidth)
        $0.bottom.right.equalToSuperview().offset(-borderWidth)
    }
    
}

저는 개인적으로 SnapKit을 굉장히 선호해서  스냅킷만 씁니다 ㅎㅎ

꼭 스냅킷 안쓰셔도 되고, 각자의 방식으로  뷰를 화면에 그려주시면 됩니다.

 

이렇게 다 그리셨으면..!!

 

이제 대망의  코너링!!

 

 

3. 특정 모서리에 라운드 주기

먼저, UIView의 확장함수로 roundCorners 라는 함수를 생성해주도록 하겠습니다.


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

자, UIView의 확장함수를 생성하셨다면,  이제 다시 뷰 컨트롤러로 돌아오셔서,   앞서 그려놓은 뷰에  적용시켜보도록 하겠습니다.

 


DispatchQueue.main.async {
    self.myView01.roundCorners(corners: [.topRight, .bottomLeft], radius:40)
    self.myView02.roundCorners(corners: [.bottomRight, .topLeft], radius:35)
    self.myView02_inner.roundCorners(corners: [.bottomRight, .topLeft], radius:28)
}

이 코드를 ViewDIdLoad에 넣어주시면  적용완료됩니다.

뷰를 그려주는 코드이기때문에

꼭!!!!   메인스레드에서 동작해야한다는 점!!  잊지마세요

 

끝!!!!

 

 

 

 


번외

위에서 말씀드린 내용중에 borderWidth 를 주면 안되는지 궁금해하셨던 분들께 해답을 드리겠습니다.

lazy var myView01 = UIView().then {
// 	$0.backgroundColor = .systemPink
    $0.layer.borderWidth = 10
    $0.layer.borderColor = .init(red: 1, green: 0, blue: 0, alpha: 1)
}
DispatchQueue.main.async {
    self.myView01.roundCorners(corners: [.topRight, .bottomLeft], radius:40)
}

이렇게 코드를 짜신다면, 아래와 같은 결과물을 보실 수 있습니다...

 

 

짤리죠 .. ㅎㅎㅎ

 

그래서  뷰 안에 또 뷰를 넣어서 만들었습니다..!

혹시 제가 소개해드린 방법 말고  테두리 실선에 Round를 주는 더 좋은 방법이 있다면 소개해주세요!!!

저도 더 쉽고 간결한 코드가 있으면   개선하고싶네용


원하시는 컴포넌트가 UIView가 아니더라도,  UIView를 상속받는 모든 뷰들은 동일하게 사용 가능합니다 ㅎㅎㅎ

오늘도 도움이 되었으면 좋겠습니다.

 

그럼 다음시간에 만나요~~