비동기로 이미지를 로드하고 보여주는 View.
AsyncImage는 shared URLSession 인스턴스를 사용하여 URL 이미지를 로드하고 보여줄 때 사용합니다.
아래 예시로 한 번 살펴볼까요?
AsyncImage(url: URL(string: "https://example.com/icon.png"))
.frame(width: 200, height: 200)
서버에 저장되어 있는 아이콘 url로 이미지를 로드하고 뷰에 띄울 수 있습니다!
이미지가 바로 바로 불러와진다면, 정말 좋겠지만 🥲
그렇지 않은 경우 이미지가 로드될 때까지, view는 이미지가 들어오는 공간에 placeholder를 띄웁니당.
해당 공간에 이미지가 들어올 것이란 걸 알리고 또 이미지가 불러와지지 않았다고 해서 무작정 비워두진 않는 것이죠.
그리고나서 이미지가 성공적으로 불러와지면, 뷰는 이미지를 보여주기 위해 새로 업데이트 합니다.
아 그리고 placeholder도 커스텀 할 수 있다는 사실을 아시나요!
init(url:scale:content:placeholder:)
⬆️ 요 이니셜라이저를 사용하면, placeholder 커스텀 뿐만 아니라 content 파라미터를 사용해서 이미지 조작도 가능하답니다~
아래 예시를 또 한 번 살펴볼까요?
이 예시는 placeholder 커스텀도 하고 불러온 이미지를 Resizable, 그리고 프레임 크기까지도 설정해줬답니다.
AsyncImage(url: URL(string: "https://example.com/icon.png")) { image in
image.resizable()
} placeholder: {
ProgressView()
}
.frame(width: 50, height: 50)
이 예시의 결과를 보면, ProgressView를 먼저 보여주고 프레임 안에 딱 맞는 image를 보여줍니다~
여기서 중요한 점 !
resizable(capInsets:resizingMode:)과 같은 image-specific 속성을 직접적으로 AsyncImage에 사용할 수 없어요 🥲
대신에, View의 appearnce가 정해졌을 때 content 클로저로 Image 인스턴스에 적용할 수 있답니다!
위에 작성한 예시 코드를 참고하면 이해하기 쉬울 거에요! (1, 2번째 줄)
마지막으로 loading process에서 더 컨트롤할 부분이 필요하면, init(url:scale:transaction:content:) 이니셜라이저를 통해 컨트롤 할 수 있습니다.
이 이니셜라이저는 loading 연산의 현재 상태를 표현하기 위해 AsyncImagePhase를 받는 content 클로저 입니다!
현재 문맥에 맞는 적절한 View를 반환하지요.
아래 예시를 살펴볼까요?
AsyncImage(url: URL(string: "https://example.com/icon.png")) { phase in
if let image = phase.image {
image // Displays the loaded image.
} else if phase.error != nil {
Color.red // Indicates an error.
} else {
Color.blue // Acts as a placeholder.
}
}
content 클로저를 한 번 볼까요?
이미지가 nil이 아니고 제대로 들어왔으면 화면에 보여줍니다.
그러나 이미지가 안들어오고 error가 있다면 빨간색 화면을 보여주라고 하고 있네요.
마지막 else 부분을 보면, 이미지도 없고 에러도 없는 경우에 파란색을 띄우라고 되어 있네요.
즉 placeholder 역할을 수행하게 되겠네요.
좋은 글 감사합니다.