SwiftUI プレビュー画面を作るには

(3) プレビュー画面を作るには
(3.1) ContentView()の例
struct ContentView: View {
// こっちは表示用
}
// これでプレビューができる
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
  ContentView()
}
}
(3.2) LandmarkList()の例
struct LandmarkList: View {
// こっちは表示用
}
 
// これでプレビューができる
struct LandmarksList_Previews: PreviewProvider {
static var previews: some View {
  LandmarkList().environmentObject(UserData())
}
}
 
// プレビューを2つ表示
struct LandmarksList_Previews: PreviewProvider {
static var previews: some View {
  ForEach(["iPhone SE", "iPhone XS Max"], id: \.self) { deviceName in
    LandmarkList()
    .previewDevice(PreviewDevice(rawValue: deviceName))
    .previewDisplayName(deviceName)
  }.environmentObject(UserData())
}
}
(3.3) LandmarkDetail()の例
struct LandmarkDetail: View {
// こっちは表示用
}
 
// これでプレビューができる。表示対象は0番目 landmarks[0]
struct LandmarkDetail_Preview: PreviewProvider {
static var previews: some View {
  let userData = UserData()
  return LandmarkDetail(landmark: userData.landmarks[0])
  .environmentObject(userData)
}
}
 
(3.4) LandmarkRow()の例
struct LandmarkRow: View {
// こっちは表示用
}
 
// これでプレビューができる。表示対象は0,1番目
struct LandmarkRow_Previews: PreviewProvider {
static var previews: some View {
  Group {
    LandmarkRow(landmark: landmarkData[0])
    LandmarkRow(landmark: landmarkData[1])
  }
  .previewLayout(.fixed(width: 300, height: 70))
}
}

SwiftUIで画面に色々表示するには

(2) 画面に色々表示するには
(2.1) ContentView()の例
struct ContentView: View {
var body: some View {
「ここ」に書く
}
}
 
(2.1.1) 表示の中身
struct ContentView: View {
var body: some View {
VStack { // 縦に並べる
  MapView() // 地図
  CircleImage() // 丸いイメージ画像
  VStack {
    Text("文字") // 文字
    HStack { // 横に並べる
      Text("文字") // 文字
      Spacer() // 空白
      Text("文字") // 文字
    }
  }.padding() // 周囲に空白
  Spacer() // 空白
} // VStack
} // some View
} // View
 
(2.2) LandmarkList()の例
struct LandmarkList: View {
@EnvironmentObject private var userData: UserData // UserData()が変更されたら画面が変わる
var body: some View {
「ここ」に書く
}
}
 
(2.2.1) 表示の中身
struct LandmarkList: View {
@EnvironmentObject private var userData: UserData
var body: some View {
NavigationView {
List {
  Toggle(..) {..} // オン・オフできるボタン
  ForEach(並べるもの達) { 1個の表示物 in
    if それが表示対象なら {
      NavigationLink(タップしたら開く画面) {
        表示するもの※
      }
    }
  }
}.navigationBarTitle(表題)
} // NavigationView
} // some View
} // View
 
(2.2.2) タップしたら開く画面
struct LandmarkDetail: View {
@EnvironmentObject var userData: UserData // UserData()が変更されたら画面が変わる
var landmark: Landmark // これで表示対象を受け取る
var body: some View {
VStack { // 縦に並べる
  MapView() // 地図
  CircleImage() // 丸いイメージ画像
  VStack { // 縦に並べる
    HStack { // 横に並べる
      Text("文字") // 文字
      Button(action: {タップしたらすること}) { // ボタン
        ボタンの表示内容★とか☆
      } // Button
    } // HStack
  }.padding() // 周囲に空白
  Spacer() // 空白
} // VStack
} // some View
} // View
 
(2.2.3) 表示するもの※
struct LandmarkRow: View {
var landmark: Landmark // これで表示対象を受け取る
var body: some View {
HStack { // 横に並べる
  landmark.image // 画像
  Text(landmark.name) // 文字
  Spacer() // 空白
  if landmark.isFavorite { // お気に入りなら
    Image() // 星の画像
  }
} // HStack
} // some View
} // View

SwiftUIで最初に開く画面を決めるには

(1) 最初に開く画面を決める
SceneDelegate.swiftの
window.rootViewController = UIHostingController(rootView: 「ここ」)
に書く。
 
// ContentView()を設定する場合
window.rootViewController = UIHostingController(rootView: ContentView())
 
// LandmarkList()を設定する場合
window.rootViewController = UIHostingController(rootView: LandmarkList())
 
// UserData()が変更されたら画面が変わるようにして、LandmarkList()を設定
window.rootViewController = UIHostingController(rootView: LandmarkList().environmentObject(UserData()))

ジェネリクス 型指定の引数

/*
ジェネリクス
型指定の引数
*/
func swapTwoInts(a: inout Int, b: inout Int) {
    let c = a
    a = b
    b = c
}
var p = 1
var q = 2
swapTwoInts(a: &p, b: &q)
print("p = \(p), q = \(q)")
 
func swapTwoValues<T>(a: inout T, b: inout T) {
    let c = a
    a = b
    b = c
}
var r = 1.0
var s = 2.0
swapTwoValues(a: &p, b: &q)
print("p = \(p), q = \(q)")
swapTwoValues(a: &r, b: &s)
print("r = \(r), s = \(s)")
 
// 外部引数名省略
func swapTwoVal<T>(_ a: inout T, _ b: inout T) {
    let c = a
    a = b
    b = c
}
swapTwoVal(&p, &q)
print("p = \(p), q = \(q)")
swapTwoVal(&r, &s)
print("r = \(r), s = \(s)")

asを使って型の判定

/*
  型キャスト
  asを使って型の判定
*/
// var things = Any[]() // error: value of type 'Any.Protocol' has no subscripts
var things : [Any] = []
things.append(0)
things.append(0.0)
for thing in things {
    switch thing {
    case 0 as Int:
        print("zero as an Int")
    case 0 as Double:
        print("zero as a Double")
    default: // TOFIX : error: switch must be exhaustive
        break // TOFIX: error: 'default' label in a 'switch' should have at least one executable statement
    }
}

イニシャライザ

/* イニシャライザ */
struct Color {
    // let red = 0.0, green = 0.0, blue = 0.0 // error: immutable value 'self.red' may only be initialized once
    let red, green, blue : Double
    init(red: Double, green: Double, blue: Double) {
        self.red   = red
        self.green = green
        self.blue  = blue
    }
}
 
let magenta = Color(red: 1.0, green: 0.0, blue: 1.0)

getter/setter

/* getter/setter */
class SpeedLimitedCar: Car {
    override var speed: Double  {
        get {
            return super.speed
        }
        set {
            super.speed = min(newValue, 40.0)
        }
    }
}
 
var limitCar = SpeedLimitedCar()
limitCar.speed = 35.0
print(limitCar.description())
limitCar.speed = 60.0
print(limitCar.description())