SwiftUI

[SwiftUI]이미지(Image) 뷰 클래스 기본 사용법 및 예제 총정리

frame(width:50, height:50) 파란색 정사각형
import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack {
            Image("squid-game")
            Image("squid-game").frame(width: 50, height: 50)
            Image("squid-game").frame(width: 100, height: 100)
//            Image("pokemon_640").frame(width: 50, height: 50)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
.previewInterfaceOrientation(.landscapeLeft)
    }
}

프레임 사이즈를 가로와 세로 사이즈를 200으로 변경하면 다음과 같이 이미지가 겹치지않는 것을 볼 수 있습니다.

    var body: some View {
        HStack {
            Image("squid-game")
            Image("squid-game").frame(width: 50, height: 50)
            Image("squid-game").frame(width: 200, height: 200)
        }
    }
frame(width:200, height:200) 파란색 정사각형

이미지의 크기를 변경하는 방법

resizable 수식어를 적용하여 변경가능하며, frame 수식어와 함께 사용해야합니다. 이미지 클래스에서만 사용가능한 수식어입니다.

그럼으로 .frame 수식어보다 먼저 적용되어야 합니다. (그렇지 않으면 오류 발생)

import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack {
            Image("squid-game").resizable()
            Image("squid-game").resizable().frame(width: 50, height: 50)
            Image("squid-game").frame(width: 200, height: 200)
        }
    }
}

위 예제코드에서 frame수식어를 사용하지 않은 이미지의 경우 화면 크기에 꽉 채워집니다. (첫번째 이미지 참고)

기본값으로 Scale to Fill이 적용된 것인데, 비율과 관계없이 이미지를 늘려서 주어진 공간을 가득 채웁니다.

이미지의 특정 영역 확대하는 방법

resizable 수식어는 UIKit의 UIImage에서 resizableImage 메서드와 동일한 역할을 수행합니다. capInset 매개 변수에 이미지의 특정 영역만 지정해 늘려 주는 것도 가능합니다.

아래 예제코드의 프리뷰 결과에서 왼쪽은 특정 영역을 늘린 것이고 오른쪽 이미지는 원본 이미지 입니다.

import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack {
            Image("squid-game").resizable(capInsets: .init(top:0, leading: 90
            	, bottom: 0, trailing: 0)).frame(width: 150, height: 150)
            Image("squid-game").resizable().frame(width: 150, height: 150)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
.previewInterfaceOrientation(.landscapeLeft)
    }
}

참고로 ResizingMode를 생략하면 기본적으로 stretch가 기본값으로 적용됨

tile 적용 예제는 다음과 같습니다.

import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack {
//            Image("squid-game").resizable().frame(width: 150, height: 150)
//            Image("squid-game").resizable(resizingMode: .stretch).frame(width: 150, height: 150)
            Image("squid-game").resizable(resizingMode: .tile) // .stretch
        }
    }
}

<tile 적용했을 경우>

만약 아래 이미지와 같이 이미지 슬라이싱(Slicing)을 적용한 경우 resizable 수식어를 사용하지 않아도 이미 적용된 것처럼 동작합니다.

<출처 : 스윗한 SwiftUI 전자책>

이미지 원본 비율을 유지한 상태에서 가능한 최대크기까지 늘리는 방법

  • scaledToFit() 수식어 또는 scaledToFill() 수식어를 사용
  • scaledToFit() 너비와 높이 중 작은 값을 기준으로 확대됨
  • scaledToFill() 수식어는 큰값 기준으로 확대됨
  • scaledToFill()이미지 일부가 주어진 공간을 벗어나 더 크게 보여질 수 있음
import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack {
            Image("squid-game")
                .resizable()
            
            Image("squid-game")
                .resizable()
                .scaledToFit()
                .frame(width: 100, height: 150)
            
            
            Image("squid-game")
                .resizable()
                .scaledToFill()
                .frame(width: 100, height: 150)
                .clipped() // 프레임을 벗어난 이미지 제거 ClipsToBounds효과
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
.previewInterfaceOrientation(.landscapeLeft)
    }
}

[프리뷰 결과]

첫번째 이미지는 Scale to Fill 기본값 적용됨

두번째 이미지는 scaledToFit() 수식어 적용

세번째 이미지는 scaledToFill() 수식어 적용 후 clipped() 적용 예시


<ContentMode 비교>

이미지 비율을 변경하는 방법(aspectRatio)

aspectRatio 수식어를 사용해야합니다. 위 ContentMode가 반영된 상태에서 추가로 이미지의 너비와 높이의 비율을 조정합니다.

import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack {
            Image("squid-game")
                .resizable()
                .aspectRatio(CGSize(width: 2.5, height: 1), contentMode: .fit)
                .frame(width: 100, height: 150)
            
            Image("squid-game")
                .resizable()
                .aspectRatio(0.2, contentMode: .fill)
                .frame(width: 100, height: 150)
                .clipped()
 
        }
    }
}

첫번째 이미지는 scaleToFit 콘텐츠 모드를 적용 후 너비가 높이보다 2.5배 비율 적용

두번째 이미지는 scaleToFill 적용 후 너비가 높이보다 0.2배 비율을 가지도록 적용한 예제입니다.

비율값을 높이거나 줄여가며 프리뷰를 확인해보시면 이해가 더 빠르게 다가오니 테스트해보세요.

이미지 모양을 변경하는 방법(Clipshape)

Clipshape 수식어를 사용하여 원하는 모양(사각형, 원형, 타원형 등)으로 만들 수 있어요.

import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack {
            Image("squid-game")
                .clipShape(Rectangle().inset(by: 20)) //이미지 4면에서 20씩 줄인 사각형
            
            Image("squid-game")
                .resizable()
                .frame(width: 200, height: 100)
                .clipShape(Circle()) //원
            
            // 크기와 위치를 직접 지정한 타원
            Image("squid-game")
                .clipShape(
                    Ellipse().path(in: CGRect(x: 10, y: 10, width: 100, height: 150))
                )
 
        }
    }
}

이미지 렌더링 모드 2가지(renderingMode)

original template
이미지 원본 색상 유지 이미지의 불투명 영역의 색을 변경하여 템플릿 이미지로 활용
렌더링 모드 생략시 기본값
struct ContentView: View {
    var body: some View {
        HStack {
            //렌더링 모드 생략시 시스템이 결정
            Image("squid-game")
            
            // 원본 이미지 유지
            Image("squid-game")
                .renderingMode(.original)
            
            // 템플릿 적용
            Image("squid-game")
                .renderingMode(.template)
        }
//        .foregroundColor(.blue)
    }
        
}

<오른쪽 끝 템플릿 적용시 이미지>

<포그라운드색상 값 변경시>

위 포스팅 내용들은 “스윗한 SwiftUI(이봉원 지음)” 전자책을 보고 스터디 및 실습한 내용들을 기록하였습니다.

Leave a Reply

error: Content is protected !!