커스텀 이미지뷰(Create a Custom Image View)
이름과 위치를 설정함과 함께 다음으로 할 일은 랜드마크에 대한 이미지를 추가하는 것입니다.
파일에 더 많은 코드를 추가하는 대신에 이미지에 마스크, 테두리, 그림자 효과 등을 적용하는 커스텀 뷰를 만들어볼 것입니다.
With the name and location views all set, the next thing to do is to add an image for the landmark.
Instead of adding more code in this file, you’ll create a custom view that applies a mask, border, and drop shadow to the image.
프로젝트 에셋 카탈로그에 이미지를 추가하면서 시작하겠습니다.
Start by adding an image to the project’s asset catalog.
Step 1
위 이미지(turtlerock.jpg)를 다운로드 받으세요 그리고 받은 이미지를 에셋 카탈로그 에디터로 드래그하세요
그러면 엑스코드는 이미지에 대한 새로운 이미지 셋을 생성합니다.
Find turtlerock.png in the project files’ Resources folder; drag it into the asset catalog’s editor. Xcode creates a new image set for the image.
다음은 사용자 정의 이미지뷰에 대한 새로운 SwiftUI 뷰를 생성할 것입니다.
Next, you’ll create a new SwiftUI view for your custom image view.
Step 2
템플릿 선택창을 다시 열기 위해서 File > New > File 을 선택합니다.
User Interface 섹션에서 SwiftUI View를 선택하고 Next버튼을 클릭합니다.
파일명은 CircleImage로 입력하고 Create버튼을 클릭합니다.
Choose File > New > File to open the template selector again. In the User Interface section, click to select SwiftUI View and click Next. Name the file CircleImage.swift and click Create.
이제 원하는 디자인에 맞게 이미지를 삽입하고 디스플레이를 수정할 준비가되었습니다.
You’re ready to insert the image and modify its display to match the desired design.
Step 3
새로 만든 CircleImage.swift파일에 기본으로 구현돼있는 텍스트뷰 자리에 Image(_:) 이니셜라이져를 사용하여 Turtle Rock 이미지로 바꾸세요.
Replace the text view with the image of Turtle Rock by using the Image(_:) initializer.
import SwiftUI
struct CircleImage: View {
var body: some View {
Image("turtlerock")
}
}
struct CircleImage_Preview: PreviewProvider {
static var previews: some View {
CircleImage()
}
}
Step 4
이미지 모양을 원형 클리핑 모양으로 변경하기 위해 clipShape(Circle())를 추가하십시오
원형 타입은 마스크로 사용할 수도 있고 채우거나 스트로크 효과를 주는 뷰로써 사용할 수 있습니다.
Add a call to clipShape(Circle()) to apply the circular clipping shape to the image.
The Circle type is a shape that you can use as a mask, or as a view by giving the circle a stroke or fill.
import SwiftUI
struct CircleImage: View {
var body: some View {
Image("turtlerock")
.clipShape(Circle())
}
}
struct CircleImage_Preview: PreviewProvider {
static var previews: some View {
CircleImage()
}
}
Step 5
회색 선이 있는 다른 원을 만든 다음 오버레이로 추가하여 이미지에 테두리를 만듭니다.
Create another circle with a gray stroke, and then add it as an overlay to give the image a border.
import SwiftUI
struct CircleImage: View {
var body: some View {
Image("turtlerock")
.clipShape(Circle())
.overlay(
Circle().stroke(Color.gray, lineWidth: 4))
}
}
struct CircleImage_Preview: PreviewProvider {
static var previews: some View {
CircleImage()
}
}
Step 6
다음으로 10포인트의 반경의 그림자를 추가합니다.
Next, add a shadow with a 10 point radius.
import SwiftUI
struct CircleImage: View {
var body: some View {
Image("turtlerock")
.clipShape(Circle())
.overlay(
Circle().stroke(Color.white, lineWidth: 4))
.shadow(radius: 10)
}
}
struct CircleImage_Preview: PreviewProvider {
static var previews: some View {
CircleImage()
}
}
Step 7
테두리 색상을 흰색으로 변경해보세요.
그럼 완성입니다 :)
Switch the border color to white.
This completes the image view.
UIKit과 SwiftUI 함께 쓰기(Use UIKit and SwiftUI Views Together)
이제 맵뷰를 생성할 준비가 됐습니다. 지도를 랜더링 하기 위해 MapKit에서 MKMapView를 사용할 수 있습니다.
SwiftUI에서 UIView의 서브클래스를 사용하기 위해서는 UIViewRepresentable 프로토콜을 따르는 SwiftUI 뷰로 래핑 하세요.
SwiftUI에는 WatchKit이나 AppKit뷰에 대한 유사한 프로토콜이 포함되어있습니다.
Now you’re ready to create a map view. You can use the MKMapView class from MapKit to render the map.
To use UIView subclasses from within SwiftUI, you wrap the other view in a SwiftUI view that conforms to the UIViewRepresentable protocol. SwiftUI includes similar protocols for WatchKit and AppKit views.
시작하기 위해 MKMapView를 보여줄 수 있는 새로운 커스텀 뷰를 생성할 것입니다.
To get started, you’ll create a new custom view that can present an MKMapView.
Step 1
File> New> File을 선택하세요, iOS 플랫폼을 선택하시고 SwiftUI View 템플릿을 선택하신 다음 Next 버튼을 누르세요
다음 화면에 나오는 파일명 정의는 MapView로 하시고 Create 버튼을 눌러서 완료합니다.
Choose File > New > File, select iOS as the platform, select the SwiftUI View template, and click Next. Name the new file MapView.swift and click Create.
Step 2
MapKit을 import 합니다. 그리고 MapView타입에 대한 UIViewRepresentable를 선언합니다.
Xcode 에러에 대해서는 걱정하지 마세요 다음 과정을 따라 하시면 자동적으로 고쳐집니다 :)
Add an import statement for MapKit, and declare UIViewRepresentable conformance for the MapView type.
Don’t worry about the error that Xcode displays; you’ll fix that in the next few steps.
import SwiftUI
import MapKit
struct MapView: UIViewRepresentable {
var body: some View {
Text("Hello World")
}
}
struct MapView_Preview: PreviewProvider {
static var previews: some View {
MapView()
}
}
UIViewRepresentable 프로토콜은 두 가지 필요사항이 있습니다.
생성에 필요한 makeUIView(context:) 함수를 추가해야 하며
수정사항 반영에 필요한 updateUIView(_:context:) 함수도 추가해야 합니다.
The UIViewRepresentable protocol has two requirements you need to add: a makeUIView(context:) method that creates an MKMapView, and an updateUIView(_:context:) method that configures the view and responds to any changes.
Step 3
body 프로퍼티를 빈 맵뷰를 반환하는 makeUIView(context:) 메서드로 변경합니다.
Replace the body property with a makeUIView(context:) method that creates and returns an empty MKMapView.
import SwiftUI
import MapKit
struct MapView: UIViewRepresentable {
func makeUIView(context: Context) -> MKMapView {
MKMapView(frame: .zero)
}
}
struct MapView_Preview: PreviewProvider {
static var previews: some View {
MapView()
}
}
Step 4
updateUIView(_:context:) 함수를 생성합니다.
이 함수 내용에서는 Turtle Rock에서 지도를 중앙에 배치하기 위해 맵뷰의 영역을 올바른 좌표로 설정합니다.
Create an updateUIView(_:context:) method that sets the map view’s region to the correct coordinates to center the map on Turtle Rock.
import SwiftUI
import MapKit
struct MapView: UIViewRepresentable {
func makeUIView(context: Context) -> MKMapView {
MKMapView(frame: .zero)
}
func updateUIView(_ view: MKMapView, context: Context) {
let coordinate = CLLocationCoordinate2D(
latitude: 34.011286, longitude: -116.166868)
let span = MKCoordinateSpan(latitudeDelta: 2.0, longitudeDelta: 2.0)
let region = MKCoordinateRegion(center: coordinate, span: span)
view.setRegion(region, animated: true)
}
}
struct MapView_Preview: PreviewProvider {
static var previews: some View {
MapView()
}
}
미리보기가 스테틱 모드일 때는 SwiftUI에 관해서만 랜더링이 됩니다.
왜냐하면 MKMapView는 UIView의 서브 클래스이기 때문에 맵에 대한 미리보기를 보려면 실시간 미리보기로 전환해야 합니다.
When previews are in static mode, they only fully render SwiftUI views. Because MKMapView is a UIView subclass, you’ll need to switch to a live preview to see the map.
Step 5
실시간 미리 보기를 사용하기 위해서 실시간 미리보기 버튼을 클릭합니다. 다시 시도하거나 미리보기 위에 위치한 Resume버튼을 다시 눌러야 할 수도 있습니다.
잠시 후 Tutle Rock이 위치한 죠수아 나무 국립공원을 볼 수 있습니다.
Click the Live Preview button to switch the preview to live mode. You might need to click the Try Again or Resume button above your preview.
In a moment, you’ll see a map of Joshua Tree National Park, home of Turtle Rock.
상세도 작성(Compose the Detail View)
이제 원하는 모든 컨포넌트를 모두 배치했습니다. 이름, 장소, 원형 효과를 준 이미지, 그리고 위치를 나타내기 위한 지도까지!
지금까지 사용한 도구를 사용하여 커스텀 뷰를 결합하여 랜드 마크 상세 뷰의 최종 디자인을 만들 겁니다!
You now have all of the components you need — the name and place, a circular image, and a map for the location.
With the tools you’ve used so far, combine your custom views to create the final design for the landmark detail view.
Step 1
프로젝트 내비게이터에서 ContentView.swift를 선택하세요
In the Project navigator, select the ContentView.swift file.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding()
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Step 2
새 VStack을 추가합니다. 가장 상위에 위치한 VStack 은 두시고 그 안에 있던 3개의 텍스트뷰를 포함시키세요.
Embed a VStack that holds the three text views in another VStack.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack(alignment: .top) {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding()
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Step 3
커스텀 맵뷰를 스택 상단에 추가하시고 frame(width:height:)를 사용하여 맴뷰의 사이즈를 설정하세요.
height 미터만 정의를 하면 자동적으로 콘텐츠의 width가 결정됩니다. 이 경우에는 맵뷰가 가능한 공간에 꽉 차게 설정됩니다.
Add your custom MapView to the top of the stack. Set the size of the MapView with frame(width:height:).
When you specify only the height parameter, the view automatically sizes to the width of its content. In this case, MapView expands to fill the available space.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
MapView()
.frame(height: 300)
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack(alignment: .top) {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding()
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Step 4
작성된 뷰에서 랜더링 된 맵을 보고 싶으시면 실시간 미리 보기 버튼을 클릭하세요
실시간 미리보기가 보이고 있는 와중에도 뷰를 계속 편집할 수도 있습니다.
Click the Live Preview button to see the rendered map in the composed view.
You can continue editing the view while showing a Live Preview.
Step 5
스택에 CircleImage를 추가하세요.
Add the CircleImage view to the stack.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
MapView()
.frame(height: 300)
CircleImage()
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack(alignment: .top) {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding()
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Step 6
맵뷰 위에 이미지뷰를 자리하게 하려면 이미지에 오프셋을 수직적으로 -130, 뷰로부터 하단 패딩(bottom padding) -130을 주세요
이렇게 하면 이미지를 위로 이동시켜서 텍스트에 대한 적절한 공간을 만들어줍니다.
To layer the image view on top of the map view, give the image an offset of -130 points vertically, and padding of -130 points from the bottom of the view.
These adjustments make room for the text by moving the image upwards.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
MapView()
.frame(height: 300)
CircleImage()
.offset(y: -130)
.padding(.bottom, -130)
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack(alignment: .top) {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding()
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Step 7
최상단에 있는 VStack에 spacer를 넣어서 콘텐츠를 화면 상단으로 밉니다.
Add a spacer at the bottom of the outer VStack to push the content to the top of the screen.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
MapView()
.frame(height: 300)
CircleImage()
.offset(y: -130)
.padding(.bottom, -130)
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack(alignment: .top) {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding()
Spacer()
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Step 8
마지막으로, 지도 내용을 화면의 상단 가장자리로 확장하려면 edgeIgnoringSafeArea (.top) 수정자(modifier)를 맵뷰에 추가하십시오.
Finally, to allow the map content to extend to the top edge of the screen, add the edgesIgnoringSafeArea(.top) modifier to the map view.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
MapView()
.edgesIgnoringSafeArea(.top)
.frame(height: 300)
CircleImage()
.offset(y: -130)
.padding(.bottom, -130)
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack(alignment: .top) {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding()
Spacer()
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
#swiftui란
#swiftui 기초
#swiftui 기본
#swiftui 강좌
#swiftui 강의
#swiftui 교육
#swiftui 시작하기
#swiftui 따라하기
#wwdc2019
#ios programming
#swiftui apple tutorial 번역
#swiftui apple 튜토리얼 번역
'IT > Swift' 카테고리의 다른 글
SwiftUI 튜토리얼 2-2 네비게이션과 리스트 만들기 (0) | 2019.10.24 |
---|---|
SwiftUI 튜토리얼 2-1 네비게이션가 리스트 만들기 (0) | 2019.10.22 |
SwiftUI 튜토리얼 1-1 뷰의 생성과 조합 (0) | 2019.10.17 |
SwiftUI - UIHostingController (0) | 2019.10.16 |
SwiftUI 시작하기 (0) | 2019.10.14 |