iOS

[iOS] Nine-Patch, 둥근모서리 이미지 소스 사용하기

빨간체리반지 2020. 10. 20. 11:05

Nine-Patch?

 

아래 그림 한장으로 Nine-Patch에 대한 모든 설명이 가능하다.

나인패치를 사용하지 않는 이미지는 크기를 늘렸을 때, 위와 같이 모서리 부분도 같이 늘어난다.

나인패치를 사용하면, 이미지 사이즈가 변해도 모서리 부분을 유지할 수 있다.

 

 


 

 

 

Android Asset Studio를 이용해 Nine-Patch 개념을 더 알아보자.

(Android Asset Studio 사이트는 아래 링크 참고)

 

 

1. Stretch Region

나인패치는 이미지를 아래와 같이 9개의 영역(3x3)으로 나누고,

늘어나는 범위를 설정해 해당 영역만 늘어나도록 하면, 모서리 부분의 이미지는 유지한채 이미지를 늘릴 수 있다.

(파란영역 : 유지되는 영역, 빨간 영역 : 늘어나는 영역)

 

 

2. Contents Padding

또, 늘리는 기능뿐 아니라 패딩박스도 설정할 수 있어서

주로 둥근모서리를 갖는 다양한 버튼을 생성할 때, 사용한다고 한다.

 

 

나인패치의 늘리는 영역 설정 기능과 컨텐츠 패딩 기능을 이용해 생성한 뷰는 아래와 같다.

뷰의 너비와 높이에 따라 컨텐츠(글씨)가 패딩박스에 맞게 들어가고 있다.

 

 

iOS와 Nine-Patch

원래는 Android 비트맵 이미지를 사용할 때 사용하는 기술?기법? 인데...

iOS에도 적용하면 좋지 않을까 싶어서 찾아보았다.

 

UIImage의 resizableImage 함수를 이용하면 Android 처럼 불변 모서리를 지정할 수 있다고 한다.

 

 

 

# 예시 - 소스

import UIKit

class ViewController: UIViewController {

 

    override func viewDidLoad() {

        super.viewDidLoad()

        

        initImg(CGRect(x: 50, y: 50, width: 100, height: 100))

        initImg(CGRect(x: 50, y: 200, width: 70, height: 100))

        initImg(CGRect(x: 50, y: 350, width: 200, height: 70))

    }

 

    private func initImg(_ frame: CGRect) {

        guard var image = UIImage(named: "rounded_square") else {return}

 

        // 1. stretch region 설정

        let inset: CGFloat = 22

        image = image.resizableImage(withCapInsets: UIEdgeInsets(top: inset, left: inset, bottom: inset, right: inset))

        

        let button = UIButton(frame: frame)

        button.setTitle("title here~~~~~", for: .normal)

        button.setTitleColor(.black, for: .normal)

 

        // 2. contents padding 설정

        let titleInset: CGFloat = 10

        button.titleEdgeInsets = UIEdgeInsets(top: titleInset, left: titleInset, bottom: titleInset, right: titleInset)

 

        button.setBackgroundImage(image, for: .normal)

        self.view.addSubview(button)

    }

 

}

 

rounded_square.png
0.01MB

 

 

# 예시 - 결과

아래 처럼 모서리 부분의 늘어짐 없이 원하는 크기로 잘 늘어난 것을 확인할 수 있다.

 

(참고)

어쩌면 당연할 수 있지만... 내가 삽질했기 때문에 기록....

생성할 UIImageView(UIButton 등등) 뷰 객체가 리소스 이미지 사이즈보다 커야만 한다.

내 경우 512x512 이미지 파일로 width: 100, height: 100인 뷰 생성했다가 코너가 너무 크게 보여서

이미지 소스 사이즈를 줄인 후, 다시 해봤더니 잘 됐다.

 

 

 

개인적으로 써보고 느낀점은..

저렇게 간단한 UI의 둥근 모서리 이미지 소스를 쓸 땐, 그냥 rounded corner 없는 이미지 사용하고, 소스로 layer에 cornerRadius, borderWidth 설정하는게 더 편할 수도 있겠다는 생각..!

 

 

 

참고 사이트

 

 

(Android Asset Studio, Nine-Patch)

romannurik.github.io/AndroidAssetStudio/nine-patches.html#&sourceDensity=320&name=example

 

Android Asset Studio - Simple nine-patch generator

Drag or select a source graphic to get started.

romannurik.github.io

(Apple Developer, resizableImageWithCapInsets:)

developer.apple.com/documentation/uikit/uiimage/1624102-resizableimagewithcapinsets?language=objc

 

(이미지 출처)

geeks.ms/waveengineteam/tag/ninepatch/