궁금한 내용을 검색해보세요!
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
서근 개발노트
티스토리에 팔로잉
SWIFTUI/Image

SwiftUI : Image

서근
QUOTE THE DAY

-
Written by SeogunSEOGUN

반응형

 

 Image 대해 알아보도록 합시다.

Image

SwiftUI에서는 이미지를 가져오는것이 정말 간단합니다. XcodeAssets 파일안에 사진 파일을 넣어주고 사용하면 됩니다.

기본 옵션

.resizable() //크기조정
.aspectRatio(contentMode: .fit) //종횡비
.cornerRadius(50) //코너반경
.padding(.all) //여백
.clipShape(Circle()) //원
.frame(width:100, height:50) //프레임
.clipped() //프레임을 벗어나는 이미지 제거
.offset(x: ,y: ) //위치 조정
.opacity(0.x) //투명도 

//이미지 넓이를 채우는 방법
* Divider().opacity(0) 
* Rectangle().frame(height: 0)

ClipShape 

이미지 또는 상자를 원하는 모양으로 자르거나 수정할 수 있습니다.

Circle()    //원
Ellipse()   //타원
Capsule()   //캡슐
Rectangle() //직사각형
RoundedRectangle(cornerRadius: 30) //둥근모서리
/* 이미지의 모양을 바꾸기 위해서는 
이미지 밑에 [ .clipShape (  ()) ] 를 추가해주면 된다. */
     Image("국기1")
           .renderingMode(.original)
           .clipShape(Capsule())
           .overlay(Capsule().stroke(Color.black, lineWidth: 1))
           .shadow(color: .black, radius: 5)

화면 전체를 같은 색으로 채우는 방법

.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.green)
.edgesIgnoringSafeArea(.all / .top / .bottom) //SafeArea 까지 채움

frame 으로 전체를 채워 줄 수 있지만, ZStack 으로도 간단하게 채울 수 도 있습니다.

Resizable / AspectRatio

Image("Example")
    .resizable()
    .aspectRatio(contentMode: .fit)
    .frame(width: 300, height: 300)
Image("Example")
    .resizable()
    .aspectRatio(contentMode: .fill)
    .frame(width: 300, height: 300)
Image("Example")
    .resizable()
    //화면은 채워졌는데 비율이 똑같지 않을땐 아래와 같이 1.0을 추가해준다
    .aspectRatio(1.0, contentMode: .fill)
    .clipped()

.aspectRatio(contentMode: ) 두가지 옵션이 있는데 .fit.fill 입니다.

 

고정된 크기의 이미지를 원하는 경우에는 잘 작동하지만, 화면을 채우기 위해 자동으로 확장되는 이미지를 원하는 경우가 많죠?

 

이럴 때는 GeometryReader를 사용하면 됩니다.

RenderingMode

HStack {
Image("SwiftUI")  //랜더링 모드 생략시 시스템이 결정
Image("SwiftUI").renderingMode(.orginal) //원본이미지 색상 유지
Image("SwiftUI").renderingMode(.template) //원하는 색 표현 가능 밑에 코드 추가 해야함.

}
.foregroundColor(.red) //자식 뷰 모두에 일괄 적용 (지금은 template 만 적용됨)

코드를 작성하고 확인해보면 template 모드일 때 이미지가 완전히 빨간색으로 되어있는 것을 확인할 수 있습니다.

 

이미지의 불투명 영역에 대해 색을 다시 입힌 것인데 앞으로도 뷰를 다루면서 종종 보게 될 것입니다.

 

이때는 당황하지 않고,

'이미지의 랜더링 모드를 template으로 설정한 거구나'

라고 생각하고 수동으로 renderingMode수식어에 original로 지정해 주면 됩니다.

SF Symbols

애플에서 제공해주는 SF Symbols 앱에 들어가면 다양한 아이콘의 이름을 알 수 있습니다. 이것을 사용하는 방법에는

Image(systemName: "심볼명")

심벌 이미지의 크기와 색 굵기 등을 설정할 수 있습니다.

HStack(spacing: 20) {
Image(systemName: "star.circle")

//첫번째, ImageScale를 통해 크기를 설정
HStack {
Image(systemName: "book,fill").imageScale(.small/medium/large)
.foregroundColor(.blue)

//두번째, Font를 통해
HStack {
Image(systemName: "arrow up".font(.body/title/system(size: 40)

//이미지에는 굵기를 조정할 수 있는 수식어가 없어서 이것을 변경하려면 weight을 사용해야함
HStack {
Image(systemName: "star.fill".font(Font.title.weight(.black/semibold/light/ultraLight))

출처 : 스윗한 SwiftUI

Padding

padding 수식어는 계속 다뤘지만, 적용될 방향과 폭을 지정하면 그 값을 반영하여 여백이 추가됩니다.

 

또, 상하나 좌우 방향으로 한 번에 적용하고 싶을 때는 vertical, horizontal이라는 값을 활용할 수 있어 leading, trailing 또는 top, botto처럼 각각 입력해 주지 않아도 됩니다. 

 

지정하지 않은 경우 .all값이 기본값으로 사용되어 네 방면에 모두 적용됩니다.

.padding(.vertical, nn)      ==  .padding([.top, .bottom], nn)
.padding(.horizontal, nn)    ==  .padding([.leading, .trailing], nn)
.padding() == .padding(.all)  ==  .padding([.vertical, .horizontal])

//이런식으로도 사용가능하다.

.padding([.top, .leading], 12)
.padding(.all, 12)

이미지 또는 도형을 텍스트의 배경으로 사용

background 안에 image를 추가해서 텍스트 뒷 배경으로 사용할 수 있습니다.

        Text("서근 개발 블로그")
            .font(.system(size: 30))
            .fontWeight(.bold)
            .padding(50)
            .background(
                Image("logo")
                    .resizable()
                    .opacity(0.1)
            )

또한, 이미지가 아닌 도형을 추가할 수 도 있습니다.

        Text("서근 개발 블로그")
            .font(.system(size: 30))
            .fontWeight(.bold)
            .padding()
            .background(Circle()
                            .fill(Color.blue)
                            .frame(width: 100, height: 100)
                        )

텍스트의 공간만 보여주고 나머지 배경은 자르고 싶다면 clipped() 수정자를 사용하면 됩니다.

        Text("서근 개발 블로그")
            .font(.system(size: 30))
            .fontWeight(.bold)
            .padding()
            .background(Circle()
                            .fill(Color.blue)
                            .frame(width: 100, height: 100))
            .clipped()
    }

ColorInvert (다크 모드, 일반 모드 자동 지정) ⭐️  

Color.primary.colorInvert()처럼 사용하면 primary의 색을 반전시켜주는 기능이 있습니다.

 

참고로, 여기서 primary는 iOS 13 에서 추가된 다크 모드를 위해 나온 시맨틱 컬러 중 하나로, 고정된 색을 사용하는 대신 라이트 모드에서는 검은색, 다크 모드에서는 흰색으로 상황에 맞게 변합니다.

TIP
 
 

주의
ColorInvert는 Color가 아닌 some View 타입이라는 점입니다. 따라서 background 수식어처럼 뷰를 인수로 전달하는 경우엔 그대로 사용이 가능하지만 foregroundColor 수식어처럼 Color 타입이 필요한 경우에는 다른 방법을 활용해야 합니다.

cornerRadius

cornerRadius 수식어는 뷰의 모서리를 둥글게 하기 위한 것으로 익숙한 기능이지만 UIKit과 한 가지 차이점이 있습니다.

 

기존에는 clipped 수식어와 같은 역할을 하는 clipToBounds 프로퍼티를 별도로 활성화해줘야 했었는데,

 

SwiftUI에서는 cornerRadius 수식어 하나만 사용하는 것만으로도 해당 효과가 적용됩니다.

Shadow

그림자의 기본 색상은 투명도가 0.33 인 검은색이 사용되며, radiusx, y 매개 변수를 통해 그림자의 범위와 위치를 지정할 수 있습니다.

 

Shadow 수식어는 불투명한 상태의 뷰에 모두 그림자 효과를 부여하므로 의도치 않은 결과로 나타날 수 있습니다.

 

SwiftUI에서 가장자리에만 그림자 효과를 넣으려면

  1. 뷰의 배경색을 불투명한 색으로 지정하고.
  2. 이미 작성한 수식어들의 효과를 먼저 반영시킨 뒤.
  3. 해당 뷰에 shadow 수식어를 추가해야 합니다.

활용

출처 : 스윗한 SwiftUI

위와 같은 이미지를 나타내고 싶다면 이 같은 코드를 작성해주면 가능합니다.

 

더보기
HStack {
        Image("apple")
            .resizable()
            .scaledToFill()
            .frame(width: 150)
            .clipped()
        
        VStack(alignment: .leading) {
            Text("백설공주 사과")
                .font(.headline)
                .fontWeight(.medium)
                .padding(.bottom, 6)
            
            Text("달콤한 맛이 좋은 과일은 여왕 사과. 독은 없고 꿀만 가득해요")
                .font(.footnote)
                .foregroundColor(.secondary)
               
            Spacer() //상품정보와 가격 사이의 공간을 떨어뜨림
            
            HStack(spacing: 0) {
                Text("₩").font(.footnote)
                    + Text("2100").font(.headline)
                
                Spacer()
                
                Image(systemName: "heart").imageScale(.large).
                                     foregroundColor(Color("peach"))
                Image(systemName: "cart").foregroundColor(Color("peach"))
            }
        
        }
        .padding(.all, 12)
    }
    .frame(height: 150)
    .background(Color.primary.colorInvert()) //다크모드 일반모드 자동 지정
    .cornerRadius(6)
    .shadow(color: .primary, radius: 1, x: 2, y: 2)
    .padding(.vertical, 8)
  }
}

 

읽어주셔서 감사합니다🤟

 


잘못된 내용이 있으면 언제든 피드백 부탁드립니다.


서근


위처럼 이미지 와 함께 댓글을 작성할 수 있습니다.