SwiftUI/BuildingListsAndNavigation
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
&tag(SwiftUI/BuildingListsAndNavigation);
*目次 [#ac7c317e]
#contents
*関連ページ [#j7b818d6]
*参考情報 [#q2213c87]
-[[Building Lists and Navigation — SwiftUI Tutorials | Ap...
-CreatingAndCombiningViewsの最後のLandmarkプロジェクトを...
-Resourcesフォルダはダウンロードした奴を上書きしたほうが...
*Create a Landmark Model [#zd6e543b]
-データを保持するためのモデルを作成する。
-landmarkData.jsonをプロジェクトのResourcesフォルダ以下に...
-New > FileでLandmark.swiftを追加。
-以下のように定義する。
#pre{{
struct Landmark: Hashable, Codable {
var id: Int
var name: String
var park: String
var state: String
var description: String
}
}}
-画像の関連付け
#pre{{
struct Landmark: Hashable, Codable {
var id: Int
var name: String
var park: String
var state: String
var description: String
private var imageName: String
var image: Image {
Image(imageName)
}
}
}}
-coordinatesを追加。最終的に以下のように。
#pre{{
struct Landmark: Hashable, Codable {
var id: Int
var name: String
var park: String
var state: String
var description: String
private var imageName: String
var image: Image {
Image(imageName)
}
private var coordinates: Coordinates
var locationCoordinate: CLLocationCoordinate2D {
CLLocationCoordinate2D(
latitude: coordinates.latitude,
longitude: coordinates.longitude)
}
struct Coordinates: Hashable, Codable {
var latitude: Double
var longitude: Double
}
}
}}
-ModelData.swiftを追加。load関数を作成する。
#pre{{
var landmarks: [Landmark] = load("landmarkData.json")
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filenam...
else {
fatalError("Couldn't find \(filename) in main bun...
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main b...
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.sel...
}
}}
-ViewsグループにContentView.swift、CircleImage.swift、Map...
*Create the Row View [#b33d2799]
-LandmarkRow.swiftを追加。以下のように作成。
#pre{{
struct LandmarkRow: View {
var landmark: Landmark
var body: some View {
HStack {
landmark.image
.resizable()
.frame(width: 50, height: 50)
Text(landmark.name)
Spacer()
}
}
}
struct LandmarkRow_Previews: PreviewProvider {
static var previews: some View {
LandmarkRow(landmark: landmarks[0]);
}
}
}}
*Customize the Row Preview [#h9c2b5ac]
-プレビューの変更
#pre{{
struct LandmarkRow_Previews: PreviewProvider {
static var previews: some View {
LandmarkRow(landmark: landmarks[1]).previewLayout...
}
}
}}
-二つ表示
#pre{{
Group {
LandmarkRow(landmark: landmarks[0])
.previewLayout(.fixed(width: 300, height:...
LandmarkRow(landmark: landmarks[1])
.previewLayout(.fixed(width: 300, height:...
}
}}
*Create the List of Landmarks [#kf86c1ab]
リストビューを実装する。
-SwiftUIファイルのLandmarkList.swiftを作成。
#pre{{
struct LandmarkList: View {
var body: some View {
List {
LandmarkRow(landmark: landmarks[0])
LandmarkRow(landmark: landmarks[1])
}
}
}
}}
*Make the List Dynamic [#h089389e]
Listにコレクションを表示。
-LandmarkListを変更。
#pre{{
struct LandmarkList: View {
var body: some View {
List(landmarks, id: \.id) { landmark in
LandmarkRow(landmark: landmark)
}
}
}}
-もしくはLandmarkを変更してIdentifiableを実装。これでプレ...
*Set Up Navigation Between List and Detail [#i2b23d8a]
リストと詳細をナビゲートできるようにする。
-SwiftUI ViewのLandmarkDetailを追加。
-ContentViewの内容を移植。
#pre{{
struct LandmarkDetail: View {
var body: some View {
VStack {
MapView()
.ignoresSafeArea(edges: .top)
.frame(height: 300)
CircleImage()
.offset(y: -130)
.padding(.bottom, -130)
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
.foregroundColor(.primary)
HStack {
Text("Joshua Tree National Park")
Spacer()
Text("California")
}
.font(.subheadline)
.foregroundColor(.secondary)
Divider()
Text("About Turtle Rock")
.font(.title2)
Text("Descriptive text goes here.")
}
.padding()
Spacer()
}
}
}
}}
-ContentViewでLandmarkListを生成。
#pre{{
struct ContentView: View {
var body: some View {
LandmarkList()
}
}
}}
-LandmarkListの中にNavigationViewを入れる。プレビューの上...
#pre{{
struct LandmarkList: View {
var body: some View {
NavigationView {
List(landmarks) { landmark in
NavigationLink(destination: LandmarkDetai...
LandmarkRow(landmark: landmark)
}
}
.navigationTitle("Landmarks")
}
}
}
-ライブプレビューで遷移を確認可能。
}}
*Pass Data into Child Views [#oaf4708d]
詳細ビューにデータを引き渡す。
-CircleImageでimageを格納する。
#pre{{
struct CircleImage: View {
var image: Image
var body: some View {
image
.clipShape(Circle())
.overlay(Circle().stroke(Color.white, lineWid...
.shadow(radius: 7)
}
}
struct CircleImage_Previews: PreviewProvider {
static var previews: some View {
CircleImage(image: Image("turtlerock"))
}
}
}}
-MapViewにcoordinateプロパティを追加。
#pre{{
struct MapView: View {
var coordinate: CLLocationCoordinate2D
@State private var region = MKCoordinateRegion()
var body: some View {
Map(coordinateRegion: $region)
.onAppear {
setRegion(coordinate)
}
}
private func setRegion(_ coordinate: CLLocationCoordi...
region = MKCoordinateRegion(
center: coordinate,
span: MKCoordinateSpan(latitudeDelta: 0.2, lo...
)
}
}
struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapView(coordinate: CLLocationCoordinate2D(latitu...
}
}
}}
-LandmarkDetailにlandmarkプロパティを追加。修正。
#pre{{
struct LandmarkDetail: View {
var landmark: Landmark
var body: some View {
ScrollView {
MapView(coordinate: landmark.locationCoordina...
.ignoresSafeArea(edges: .top)
.frame(height: 300)
CircleImage(image: landmark.image)
.offset(y: -130)
.padding(.bottom, -130)
VStack(alignment: .leading) {
Text(landmark.name)
.font(.title)
.foregroundColor(.primary)
HStack {
Text(landmark.park)
Spacer()
Text(landmark.state)
}
.font(.subheadline)
.foregroundColor(.secondary)
Divider()
Text("About \(landmark.name)")
.font(.title2)
Text(landmark.description)
}
.padding()
}
.navigationTitle(landmark.name)
.navigationBarTitleDisplayMode(.inline)
}
}
struct LandmarkDetail_Previews: PreviewProvider {
static var previews: some View {
Group {
LandmarkDetail(landmark: landmarks[0])
}
}
}
}}
*Generate Previews Dynamically [#ofc48995]
プレビューを修正する。
-LandmarkListを修正。まとめてプレビューできる。
#pre{{
struct LandmarkList: View {
var body: some View {
NavigationView {
List(landmarks) { landmark in
NavigationLink(destination: LandmarkDetai...
LandmarkRow(landmark: landmark)
}
}
.navigationTitle("Landmarks")
}
}
}
struct LandmarkList_Previews: PreviewProvider {
static var previews: some View {
ForEach(["iPhone SE (2nd generation)", "iPhone XS...
LandmarkList()
.previewDevice(PreviewDevice(rawValue: de...
.previewDisplayName(deviceName)
}
}
}
}}
終了行:
&tag(SwiftUI/BuildingListsAndNavigation);
*目次 [#ac7c317e]
#contents
*関連ページ [#j7b818d6]
*参考情報 [#q2213c87]
-[[Building Lists and Navigation — SwiftUI Tutorials | Ap...
-CreatingAndCombiningViewsの最後のLandmarkプロジェクトを...
-Resourcesフォルダはダウンロードした奴を上書きしたほうが...
*Create a Landmark Model [#zd6e543b]
-データを保持するためのモデルを作成する。
-landmarkData.jsonをプロジェクトのResourcesフォルダ以下に...
-New > FileでLandmark.swiftを追加。
-以下のように定義する。
#pre{{
struct Landmark: Hashable, Codable {
var id: Int
var name: String
var park: String
var state: String
var description: String
}
}}
-画像の関連付け
#pre{{
struct Landmark: Hashable, Codable {
var id: Int
var name: String
var park: String
var state: String
var description: String
private var imageName: String
var image: Image {
Image(imageName)
}
}
}}
-coordinatesを追加。最終的に以下のように。
#pre{{
struct Landmark: Hashable, Codable {
var id: Int
var name: String
var park: String
var state: String
var description: String
private var imageName: String
var image: Image {
Image(imageName)
}
private var coordinates: Coordinates
var locationCoordinate: CLLocationCoordinate2D {
CLLocationCoordinate2D(
latitude: coordinates.latitude,
longitude: coordinates.longitude)
}
struct Coordinates: Hashable, Codable {
var latitude: Double
var longitude: Double
}
}
}}
-ModelData.swiftを追加。load関数を作成する。
#pre{{
var landmarks: [Landmark] = load("landmarkData.json")
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filenam...
else {
fatalError("Couldn't find \(filename) in main bun...
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main b...
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.sel...
}
}}
-ViewsグループにContentView.swift、CircleImage.swift、Map...
*Create the Row View [#b33d2799]
-LandmarkRow.swiftを追加。以下のように作成。
#pre{{
struct LandmarkRow: View {
var landmark: Landmark
var body: some View {
HStack {
landmark.image
.resizable()
.frame(width: 50, height: 50)
Text(landmark.name)
Spacer()
}
}
}
struct LandmarkRow_Previews: PreviewProvider {
static var previews: some View {
LandmarkRow(landmark: landmarks[0]);
}
}
}}
*Customize the Row Preview [#h9c2b5ac]
-プレビューの変更
#pre{{
struct LandmarkRow_Previews: PreviewProvider {
static var previews: some View {
LandmarkRow(landmark: landmarks[1]).previewLayout...
}
}
}}
-二つ表示
#pre{{
Group {
LandmarkRow(landmark: landmarks[0])
.previewLayout(.fixed(width: 300, height:...
LandmarkRow(landmark: landmarks[1])
.previewLayout(.fixed(width: 300, height:...
}
}}
*Create the List of Landmarks [#kf86c1ab]
リストビューを実装する。
-SwiftUIファイルのLandmarkList.swiftを作成。
#pre{{
struct LandmarkList: View {
var body: some View {
List {
LandmarkRow(landmark: landmarks[0])
LandmarkRow(landmark: landmarks[1])
}
}
}
}}
*Make the List Dynamic [#h089389e]
Listにコレクションを表示。
-LandmarkListを変更。
#pre{{
struct LandmarkList: View {
var body: some View {
List(landmarks, id: \.id) { landmark in
LandmarkRow(landmark: landmark)
}
}
}}
-もしくはLandmarkを変更してIdentifiableを実装。これでプレ...
*Set Up Navigation Between List and Detail [#i2b23d8a]
リストと詳細をナビゲートできるようにする。
-SwiftUI ViewのLandmarkDetailを追加。
-ContentViewの内容を移植。
#pre{{
struct LandmarkDetail: View {
var body: some View {
VStack {
MapView()
.ignoresSafeArea(edges: .top)
.frame(height: 300)
CircleImage()
.offset(y: -130)
.padding(.bottom, -130)
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
.foregroundColor(.primary)
HStack {
Text("Joshua Tree National Park")
Spacer()
Text("California")
}
.font(.subheadline)
.foregroundColor(.secondary)
Divider()
Text("About Turtle Rock")
.font(.title2)
Text("Descriptive text goes here.")
}
.padding()
Spacer()
}
}
}
}}
-ContentViewでLandmarkListを生成。
#pre{{
struct ContentView: View {
var body: some View {
LandmarkList()
}
}
}}
-LandmarkListの中にNavigationViewを入れる。プレビューの上...
#pre{{
struct LandmarkList: View {
var body: some View {
NavigationView {
List(landmarks) { landmark in
NavigationLink(destination: LandmarkDetai...
LandmarkRow(landmark: landmark)
}
}
.navigationTitle("Landmarks")
}
}
}
-ライブプレビューで遷移を確認可能。
}}
*Pass Data into Child Views [#oaf4708d]
詳細ビューにデータを引き渡す。
-CircleImageでimageを格納する。
#pre{{
struct CircleImage: View {
var image: Image
var body: some View {
image
.clipShape(Circle())
.overlay(Circle().stroke(Color.white, lineWid...
.shadow(radius: 7)
}
}
struct CircleImage_Previews: PreviewProvider {
static var previews: some View {
CircleImage(image: Image("turtlerock"))
}
}
}}
-MapViewにcoordinateプロパティを追加。
#pre{{
struct MapView: View {
var coordinate: CLLocationCoordinate2D
@State private var region = MKCoordinateRegion()
var body: some View {
Map(coordinateRegion: $region)
.onAppear {
setRegion(coordinate)
}
}
private func setRegion(_ coordinate: CLLocationCoordi...
region = MKCoordinateRegion(
center: coordinate,
span: MKCoordinateSpan(latitudeDelta: 0.2, lo...
)
}
}
struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapView(coordinate: CLLocationCoordinate2D(latitu...
}
}
}}
-LandmarkDetailにlandmarkプロパティを追加。修正。
#pre{{
struct LandmarkDetail: View {
var landmark: Landmark
var body: some View {
ScrollView {
MapView(coordinate: landmark.locationCoordina...
.ignoresSafeArea(edges: .top)
.frame(height: 300)
CircleImage(image: landmark.image)
.offset(y: -130)
.padding(.bottom, -130)
VStack(alignment: .leading) {
Text(landmark.name)
.font(.title)
.foregroundColor(.primary)
HStack {
Text(landmark.park)
Spacer()
Text(landmark.state)
}
.font(.subheadline)
.foregroundColor(.secondary)
Divider()
Text("About \(landmark.name)")
.font(.title2)
Text(landmark.description)
}
.padding()
}
.navigationTitle(landmark.name)
.navigationBarTitleDisplayMode(.inline)
}
}
struct LandmarkDetail_Previews: PreviewProvider {
static var previews: some View {
Group {
LandmarkDetail(landmark: landmarks[0])
}
}
}
}}
*Generate Previews Dynamically [#ofc48995]
プレビューを修正する。
-LandmarkListを修正。まとめてプレビューできる。
#pre{{
struct LandmarkList: View {
var body: some View {
NavigationView {
List(landmarks) { landmark in
NavigationLink(destination: LandmarkDetai...
LandmarkRow(landmark: landmark)
}
}
.navigationTitle("Landmarks")
}
}
}
struct LandmarkList_Previews: PreviewProvider {
static var previews: some View {
ForEach(["iPhone SE (2nd generation)", "iPhone XS...
LandmarkList()
.previewDevice(PreviewDevice(rawValue: de...
.previewDisplayName(deviceName)
}
}
}
}}
ページ名: