前回は、SwiftUIで、ベーシックな TabView と画像を回転させるアプリケーションの
開発記事を紹介しました。
今回は、SwiftUIで、上部Tab制御 & 3種類の画像ファイル選択方法を利用した
アプリケーションを開発する記事を紹介しようと思います。
習得内容
今回、SwiftUIで、上部Tab制御 & 3種類の画像ファイル選択方法を利用したアプリケーション
を作成する事で、下記の内容を習得する事が出来ます。
- HeaderBar:TabView は、下部に Tab を配置していますが、HeaderBar を実装する事で、上部に Tab を配置して、TabView を制御します。
- Picker:画像ファイル選択方法を、メニューと回転ホイールで実現します。
- DropDown:画像ファイル選択方法を、ドロップダウン(プルダウン)で実現します。
- AnyTransition:ドロップダウン(プルダウン)の表示・非表示の切り替えは、トランジション(transition)で実現します。
ドロップダウン(プルダウン)
Swift では、複数の選択肢から1つの値を選択する場合、標準コンポーネントとして、
Picker が搭載されています。
通常なら、Picker を利用すれば、要件を満たして事足りるのですが、顧客の指定で、
ドロップダウン(プルダウン)を要求する場合も出て来ます。
(顧客への提案時に経験しました…)
Swift には、標準コンポーネントとして、DropDown が搭載されていないので、
今回、ForEach、Button、transition を利用して、ドロップダウン(プルダウン)と
ドロワーの作り込みをしています。
動作環境
今回も、アプリが動作する環境は下記になります。
- mac OS:Sequoia 15.6.1
- iOS:26.0
- Xcode:26.0.1
- Swift:6.2.1
NavigationStack
NavigationStack については、過去の記事で詳しく説明しましたので、今回も、
詳細説明を省略させて頂きます。
NavigationStack → TabBarView → Menu/Wheel/DropDown
NavigationStack で、配列コントロールを実現する為に、View を作成して行きます。
- TabBarView:上部に Tab を配置して、TabView を制御します。下部は、画像ファイル選択方法と選択された画像を表示します。
- HeaderBarView:上部の Tab制御を担当します。
- MenuPickerView:画像ファイル選択方法を、メニューで実現します。
- WheelPickerView:画像ファイル選択方法を、回転ホイールで実現します。
- DropDownView:画像ファイル選択方法を、ドロップダウン(プルダウン)で実現します。
- DropDownList:DropDownView から呼び出される、ドロワー(drawer)の部品です。
Xcode の上部タブメニューより、File → New → File from Template を選択します。
SwiftUI View を選択します。
名称は、TabBarView を入力してみます。
Create ボタンを押して、TabBarView.swift を作成します。
同様に、HeaderBarView.swift、MenuPickerView.swift、WheelPickerView.swift、
DropDownView.swift、DropDownList.swift を作成します。
ContentView:メインメニュー(ランチャー)
メインメニュー(ランチャー):ContentView を確認します。
import SwiftUI
struct ContentView: View {
@State var isPopupView_1 = false
@State var isPopupView_2 = false
@State var isPopupView_3 = false
@State var isPopupView_4 = false
@State var isPopupView_5 = false
var body: some View {
VStack{
Button {
self.isPopupView_1.toggle()
} label: {
Text("QRCodeView")
.font(.title2)
}
.fullScreenCover(isPresented: $isPopupView_1, content: {
QRCodeView(isPopupView_1: $isPopupView_1)
})
.padding()
Button {
self.isPopupView_2.toggle()
} label: {
Text("ColorPickerView")
.font(.title2)
}
.sheet(isPresented: $isPopupView_2, content: {
ColorPickerView(isPopupView_2: $isPopupView_2)
})
.padding()
Button {
self.isPopupView_3.toggle()
} label: {
Text("ColorSliderRGBView")
.font(.title2)
}
.sheet(isPresented: $isPopupView_3, content: {
ColorSliderRGBView(isPopupView_3: $isPopupView_3)
})
.padding()
Button {
self.isPopupView_4.toggle()
} label: {
Text("ColorSliderHSBView")
.font(.title2)
}
.sheet(isPresented: $isPopupView_4, content: {
ColorSliderHSBView(isPopupView_4: $isPopupView_4)
})
.padding()
Button {
self.isPopupView_5.toggle()
} label: {
Text("NavigationListView")
.font(.title2)
}
.sheet(isPresented: $isPopupView_5, content: {
NavigationListView(isPopupView_5: $isPopupView_5)
})
.padding()
}
}
}
#Preview {
ContentView()
}
メインメニュー(ランチャー)は、以下の内容です。
- QRCodeView
- ColorPickerView
- ColorSliderRGBView
- ColorSliderHSBView
- NavigationListView
今回も、メインメニュー(ランチャー):ContentView に変更は有りませんので、
このまま利用して行きます。
NavigationListView:配列コントロール
NavigationListVeiw のソースに、追記・修正をして行きます。
ソース例:NavigationListVeiw(配列コントロール)
前回の記事で、BaseTabVeiw(path: $path)、SelectTabView(path: $path) を
追加した NavigationListVeiw のソースを確認してみます。
import SwiftUI
struct NavigationListView: View {
@Binding var isPopupView_5: Bool
@State var path: [String] = []
var navi_lists: [String] = [
"SwipeView",
"CarouselView",
"BaseTabView",
"TabBarView"
]
var body: some View {
VStack {
NavigationStack(path: $path) {
List(navi_lists, id: \.self) { navi_list in
NavigationLink(navi_list, value: navi_list)
.font(.system(size: 22))
}
.navigationDestination(for: String.self) { navi_list in
switch (navi_list) {
case "SwipeView":
SwipeView(path: $path)
.navigationTitle(navi_list)
.navigationBarTitleDisplayMode(.inline)
case "SwipeDetailView":
SwipeDetailView(path: $path)
.navigationTitle(navi_list)
.navigationBarTitleDisplayMode(.inline)
case "CarouselView":
CarouselView(path: $path)
.navigationTitle(navi_list)
.navigationBarTitleDisplayMode(.inline)
case "BaseTabView":
BaseTabView(path: $path)
.navigationTitle(navi_list)
.navigationBarTitleDisplayMode(.inline)
case "SelectTabView":
SelectTabView(path: $path)
.navigationTitle(navi_list)
.navigationBarTitleDisplayMode(.inline)
case "TabBarView":
Text(navi_list)
.font(.system(size: 22))
.foregroundColor(.orange)
.padding()
default:
Text(navi_list)
.font(.system(size: 22))
.foregroundColor(.blue)
.padding()
}
}
.navigationTitle("NavigationList")
.font(.system(size: 22))
.foregroundColor(.purple)
}
}
Button(action: {
withAnimation {
self.isPopupView_5.toggle()
}
}, label: {
Text("Close")
.font(.title2)
.foregroundColor(.black)
})
.padding()
}
}
#Preview {
NavigationListView(isPopupView_5: .constant(false))
}
ソース例:NavigationListVeiw(配列コントロール:追加・修正版)
NavigationListVeiw のソースに、追記・修正をしたソースを紹介します。
import SwiftUI
struct NavigationListView: View {
@Binding var isPopupView_5: Bool
@State var path: [String] = []
var navi_lists: [String] = [
"SwipeView",
"CarouselView",
"BaseTabView",
"TabBarView"
]
var body: some View {
VStack {
NavigationStack(path: $path) {
List(navi_lists, id: \.self) { navi_list in
NavigationLink(navi_list, value: navi_list)
.font(.system(size: 22))
}
.navigationDestination(for: String.self) { navi_list in
switch (navi_list) {
case "SwipeView":
SwipeView(path: $path)
.navigationTitle(navi_list)
.navigationBarTitleDisplayMode(.inline)
case "SwipeDetailView":
SwipeDetailView(path: $path)
.navigationTitle(navi_list)
.navigationBarTitleDisplayMode(.inline)
case "CarouselView":
CarouselView(path: $path)
.navigationTitle(navi_list)
.navigationBarTitleDisplayMode(.inline)
case "BaseTabView":
BaseTabView(path: $path)
.navigationTitle(navi_list)
.navigationBarTitleDisplayMode(.inline)
case "SelectTabView":
SelectTabView(path: $path)
.navigationTitle(navi_list)
.navigationBarTitleDisplayMode(.inline)
case "TabBarView":
TabBarView(path: $path)
.navigationTitle(navi_list)
.navigationBarTitleDisplayMode(.inline)
default:
Text(navi_list)
.font(.system(size: 22))
.foregroundColor(.blue)
.padding()
}
}
.navigationTitle("NavigationList")
.font(.system(size: 22))
.foregroundColor(.purple)
}
}
Button(action: {
withAnimation {
self.isPopupView_5.toggle()
}
}, label: {
Text("Close")
.font(.title2)
.foregroundColor(.black)
})
.padding()
}
}
#Preview {
NavigationListView(isPopupView_5: .constant(false))
}
追記・修正をした部分を説明します。
- TabBarView(path: $path):TabBarView に、path の引数を渡しています。
TabBarView → MenuPicker/WheelPicker/DropDown
今回は、View で利用する画像(写真)は Xcode に追加せず、前回までに Assets 内に
保存した画像(写真)を利用します。
ソース例:TabBarView
NavigationList から TabBarView を選択して、表示します。
TabBarView は、
- HeaderBarView
- MenuPickerView
- WheelPickerView
- DropDownView
の4つの Veiw を組み合わせています。
import SwiftUI
struct TabBarView: View {
@Binding var path: [String]
@State private var selectedTab: Int = 1
var body: some View {
ZStack {
Color.white
.edgesIgnoringSafeArea(.all)
VStack {
HeaderBarView(selectedTab: $selectedTab)
TabView(selection: $selectedTab) {
MenuPickerView()
.tag(1)
WheelPickerView()
.tag(2)
DropDownView()
.tag(3)
}
.tabViewStyle(.page(indexDisplayMode: .never))
}
}
}
}
#Preview {
TabBarView(path: .constant(["TabBarView"]))
}
- @State private var selectedTab:選択の Tab を宣言しています。
- HeaderBarView(selectedTab: $selectedTab):HeaderBarView に、selectedTab の引数を渡して呼び出しています。VStack で、上部に配置しています。
- TabView(selection: $selectedTab) {:TabView に、selectedTab の引数を渡しています。TabView で切り替える画面に tag 修飾子を付与し、引数に番号を指定します。
- MenuPickerView().tag(1):MenuPickerView を呼び出して、通常の Picker で画像(写真)のファイル名を選択します。tag:1 を指定しています。
- WheelPickerView().tag(2):WheelPickerView を呼び出して、回転ホイールで画像(写真)のファイル名を選択します。tag:2 を指定しています。
- DropDownView().tag(3):DropDownView を呼び出して、ドロップダウン(プルダウン)で画像(写真)のファイル名を選択します。tag:3 を指定しています。
- .tabViewStyle(.page(indexDisplayMode: .never)):tabViewStyle の page で、indexDisplayMode: .never を指定することで、TabView の下に標準で配置しているPageControl を非表示にします。
4つの Veiw は、前回までのように NavigationStack から、switch 文でコントロール
するのではなく、TabBarView から直接呼び出しています。
ソース例:HeaderBarView
TabBarView の上部に配置する、HeaderBarView のソースを紹介します。
import SwiftUI
struct HeaderBarView: View {
@Binding var selectedTab: Int
var body: some View {
HStack {
Spacer()
HStack {
Image(systemName: "cat")
Text("MenuPicker")
}
.foregroundColor(selectedTab == 1 ? Color.blue : Color.gray)
.onTapGesture {
withAnimation {
selectedTab = 1
}
}
Spacer()
HStack {
Image(systemName: "cat.fill")
Text("WheelPicker")
}
.foregroundColor(selectedTab == 2 ? Color.green : Color.gray)
.onTapGesture {
withAnimation {
selectedTab = 2
}
}
Spacer()
HStack {
Image(systemName: "pawprint")
Text("DropDown")
}
.foregroundColor(selectedTab == 3 ? Color.pink : Color.gray)
.onTapGesture {
withAnimation {
selectedTab = 3
}
}
Spacer()
}
}
}
#Preview {
HeaderBarView(selectedTab: .constant(1))
}
- @Binding var selectedTab: Int:@State を指定した親View(TabBarView)から渡される selectedTab が利用出来るように宣言しています。
- HStack { Image(systemName: “cat”) Text(“MenuPicker”) }:SF Symbols の猫のアイコンと、“MenuPicker” の文字列を水平に設定しています。
- .foregroundColor(selectedTab == 1 ? Color.blue : Color.gray):selectedTab が1なら青色で表示、それ以外はグレーで表示しています。
- .onTapGesture { withAnimation { selectedTab = 1 }}:タップした時に、selectedTab に1を代入しています。
- HStack { Image(systemName: “cat.fill”) Text(“WheelPicker”) }:SF Symbols の黒猫のアイコンと、“WheelPicker” の文字列を水平に設定しています。
- .foregroundColor(selectedTab == 2 ? Color.green : Color.gray):selectedTab が2なら緑色で表示、それ以外はグレーで表示しています。
- .onTapGesture { withAnimation { selectedTab = 2 }}:タップした時に、selectedTab に2を代入しています。
- HStack { Image(systemName: “pawprint”) Text(“DropDown”) }:SF Symbols の足跡のアイコンと、“DropDown” の文字列を水平に設定しています。
- .foregroundColor(selectedTab == 3 ? Color.pink : Color.gray):selectedTab が3ならピンク色で表示、それ以外はグレーで表示しています。
- .onTapGesture { withAnimation { selectedTab = 3 }}:タップした時に、selectedTab に3を代入しています。
ソース例:MenuPickerView
TabBarView の下部で1番目に配置する、MenuPickerView のソースを紹介します。
import SwiftUI
struct MenuPickerView: View {
@State private var selectIndex: Int = 0
@State var cat_image: String = "IMG_0057"
var imageNames: [String] = [
"IMG_0057",
"IMG_0230",
"IMG_0405",
"IMG_0402",
"IMG_0411",
"IMG_0412",
]
var body: some View {
ZStack {
Color.white
.edgesIgnoringSafeArea(.all)
VStack {
Picker("cat", selection: $selectIndex) {
ForEach(0..<imageNames.count, id: \.self) { imageIndex in
withAnimation {
Text(imageNames[imageIndex])
}
}
}
.pickerStyle(.menu)
.onChange(of: selectIndex) {
withAnimation {
cat_image = imageNames[selectIndex]
}
}
.padding()
Image(cat_image)
.resizable()
.scaledToFill()
}
}
}
}
#Preview {
MenuPickerView()
}
- @State private var selectIndex: Int = 0:selectIndex を宣言して、初期値に0を代入しています。
- @State var cat_image: String = “IMG_0057”:cat_image を宣言して、初期値に “IMG_0057” を代入しています。
- var imageNames: [String] = [ “IMG_0057”, “IMG_0230”, …]:Assets に保存した複数の画像(写真)の名称を利用する為に、配列で宣言しています。
- Picker(“cat”, selection: $selectIndex) {:Picker を設定しています。
- ForEach(0..<imageNames.count, id: \.self) { imageIndex in:Assets に保存した画像(写真)を、ForEach() で配列の画像(写真)を繰り返し生成して表示しています。
- Text(imageNames[imageIndex]):選択された画像(写真)の名称を設定しています。
- .pickerStyle(.menu):pickerStyle を menu に設定する事で、メニュー表示が実現します。
- .onChange(of: selectIndex) {:画像(写真)の名称を変更した時の処理を記載します。
- cat_image = imageNames[selectIndex]:cat_image に、選択された画像(写真)の名称を設定しています。
- Image(cat_image):Image に、選択された画像(写真)を設定しています。
ソース例:WheelPickerVirew
TabBarView の下部で2番目に配置する、WheelPickerView のソースを紹介します。
import SwiftUI
struct WheelPickerView: View {
@State private var selectIndex: Int = 0
@State var cat_image: String = "IMG_0088"
var imageNames: [String] = [
"IMG_0088",
"IMG_0148",
"IMG_0234",
"IMG_0096",
"IMG_0090",
"IMG_0976",
]
var body: some View {
ZStack {
Color.white
.edgesIgnoringSafeArea(.all)
VStack {
Picker("cat", selection: $selectIndex) {
ForEach(0..<imageNames.count, id: \.self) { imageIndex in
withAnimation {
Text(imageNames[imageIndex])
}
}
}
.pickerStyle(.wheel)
.onChange(of: selectIndex) {
withAnimation {
cat_image = imageNames[selectIndex]
}
}
.padding()
Image(cat_image)
.resizable()
.scaledToFill()
}
}
}
}
#Preview {
WheelPickerView()
}
- @State private var selectIndex: Int = 0:selectIndex を宣言して、初期値に0を代入しています。
- @State var cat_image: String = “IMG_0088”:cat_image を宣言して、初期値に “IMG_0088” を代入しています。
- var imageNames: [String] = [ “IMG_0088”, “IMG_0148”, …]:Assets に保存した複数の画像(写真)の名称を利用する為に、配列で宣言しています。
- Picker(“cat”, selection: $selectIndex) {:Picker を設定しています。
- ForEach(0..<imageNames.count, id: \.self) { imageIndex in:Assets に保存した画像(写真)を、ForEach() で配列の画像(写真)を繰り返し生成して表示しています。
- Text(imageNames[imageIndex]):選択された画像(写真)の名称を設定しています。
- .pickerStyle(.wheel):pickerStyle を wheel に設定する事で、回転ホイール表示が実現します。
- .onChange(of: selectIndex) {:画像(写真)の名称を変更した時の処理を記載します。
- cat_image = imageNames[selectIndex]:cat_image に、選択された画像(写真)の名称を設定しています。
- Image(cat_image):Image に、選択された画像(写真)を設定しています。
DropDownView → DropDownList
DropDownView は、DropDownList と組み合わせて表示しています。
ソース例:DropDownView
TabBarView の下部で3番目に配置する、DropDownView のソースを紹介します。
import SwiftUI
struct DropDownView: View {
@State private var isExpanded = false
@State private var selectedItem = "IMG_0981"
@State private var dropdown_height: CGFloat = 0.1
@State private var imageNames: [String] = [
"IMG_0981",
"IMG_0059",
"IMG_0232",
"IMG_0688",
"IMG_0541",
"IMG_0058",
]
var body: some View {
GeometryReader { geometry in
let geo_width: CGFloat = geometry.size.width
ZStack {
Color.white
.edgesIgnoringSafeArea(.all)
VStack(spacing: 20) {
Button {
withAnimation {
isExpanded.toggle()
}
} label: {
HStack {
Text(selectedItem)
.foregroundColor(.black)
Spacer()
Image(systemName: "chevron.down")
.rotationEffect(.degrees(isExpanded ? 180 : 0))
}
.padding()
.background(
RoundedRectangle(cornerRadius: 8)
.stroke(Color.gray)
)
}
.frame(width: geo_width * 0.6)
Image(selectedItem)
.resizable()
.scaledToFit()
}
if isExpanded {
Color.black.opacity(0.001)
.ignoresSafeArea()
.onTapGesture {
withAnimation {
isExpanded = false
}
}
DropDownList(items: $imageNames, selectedItem: $selectedItem, isExpanded: $isExpanded, dropdown_height: $dropdown_height)
.transition(.move(edge: .top).combined(with: .opacity))
.frame(width: geo_width * 0.6)
}
}
}
}
}
#Preview {
DropDownView()
}
- @State private var isExpanded = false:isExpanded を宣言して、初期値に false を 代入しています。ボタンを押した(タップした)かどうかの判定に利用します。
- @State var selectedItem: String = “IMG_0981”:selectedItem を宣言して、初期値に “IMG_0981” を代入しています。
- @State private var dropdown_height: CGFloat = 0.1:dropdown_height を宣言して、初期値に0.1を代入しています。
- var imageNames: [String] = [ “IMG_0981”, “IMG_0059”, …]:Assets に保存した複数の画像(写真)の名称を利用する為に、配列で宣言しています。
- GeometryReader { geometry in:画面サイズを取得する為に利用します。
- let geo_width: CGFloat = geometry.size.width:画面の幅を、geo_width に代入しています。
- Button {:ボタンを押した(タップした)時の処理を記載します。
- isExpanded.toggle():isExpanded の値を反転させています。
- Text(selectedItem): Text に selectedItem を設定しています。
- Image(systemName: “chevron.down”):SF Sybols で、chevron.down のアイコンを設定しています。
- .rotationEffect(.degrees(isExpanded ? 180 : 0)):isExpanded が true の場合、chevron.down のアイコンを180度回転(上下を反転)させます。
- RoundedRectangle(cornerRadius: 8):ボタンの半径を 8 で指定した角丸四角形を設定しています。
- .frame(width: geo_width * 0.6):ボタンの幅を、画面の幅の0.6倍に設定しています。
- Image(selectedItem):Image に selectedItem を設定しています。
- if isExpanded {:isExpanded が true の場合の処理を記載します。
- .onTapGesture { withAnimation { isExpanded = false }}:タップした時に、isExpanded に false を代入しています。isExpanded.toggle() の記載でも大丈夫ですが、今回は明確に false を代入しています。
- DropDownList(items: $imageNames,…):DropDownList() を呼び出しています。
- .transition(.move(edge: .top).combined(with: .opacity)):ドロップダウン(プルダウン)の表示・非表示の切り替えで、transition を指定しています。 move(edge: .top)で、上(top)から表示・非表示(戻る)を実現し、opacity と組み合わせる(combined)事で、透明な状態からじわじわとドロップダウン(プルダウン)が出現したり、消えたりします。
- .frame(width: geo_width * 0.6):ドロップダウン(プルダウン)の幅を、画面の幅の0.6倍に設定しています。
AnyTransition:表示・非表示の切り替え
Viewの表示・非表示の切り替えに、transition(トランジション)を利用しています。
transition(トランジション)の主なタイプは、下記になります。
- .slide:左からスライドして出現し、右へスライドして消えて行きます。
- .opacity:透明な状態からじわじわと出現し、消える時もじわじわと透明になって行きます。
- .scale:拡大しながら表示、縮小しながら消えていきます。
- .move(edge: Edge):edge で指定された方向(.top/.leading/.bottom/.trailing)から出現して、指定された同方向へ消えて行きます。
- .offset(CGSize):CGSize で指定されたオフセット位置から、移動しながら表示して、同じ位置へ移動しながら非表示になります。
- .identity:transition(トランジション)の効果は、行いません。
AnyTransition については、下記を参考にしています。
ソース例:DropDownList
DropDownView からドロワー(drawer)として呼び出される、DropDownList の
ソースを紹介します。
import SwiftUI
struct DropDownList: View {
@Binding var items: [String]
@Binding var selectedItem: String
@Binding var isExpanded: Bool
@Binding var dropdown_height: CGFloat
var body: some View {
GeometryReader { geometry in
let geo_height: CGFloat = geometry.size.height
VStack(spacing: 0) {
ForEach(items, id: \.self) {item in
Button {
selectedItem = item
withAnimation {
isExpanded = false
}
} label: {
HStack {
Text(item)
.foregroundColor(.black)
Spacer()
}
.padding()
.background(Color.white)
}
if item != items.last {
Divider()
}
}
}
.background(
RoundedRectangle(cornerRadius: 8)
.fill(Color.white)
.shadow(radius: 5)
)
.padding(.horizontal, 16)
.offset(y: geo_height * dropdown_height)
}
}
}
#Preview {
DropDownList(items: .constant(["IMG_0981"]), selectedItem: .constant("IMG_0981"), isExpanded: .constant(false), dropdown_height: .constant(0.1))
}
- @Binding var items:[String]:@State を指定した親View(DropDownView)から渡される items が利用出来るように宣言しています。
- @Binding var selectedItem: String:@State を指定した親View(DropDownView)から渡される selectedItem が利用出来るように宣言しています。
- @Binding var isExpanded: Bool:@State を指定した親View(DropDownView)から渡される isExpanded が利用出来るように宣言しています。
- @Binding var dropdown_height: CGFloat:@State を指定した親View(DropDownView)から渡される dropdown_height が利用出来るように宣言しています。
- GeometryReader { geometry in:画面サイズを取得する為に利用します。
- let geo_height: CGFloat = geometry.size.height:画面の高さを、geo_height に代入しています。
- ForEach(items, id: \.self) {item in:ForEach() で、親View(DropDownView)から渡された items を繰り返し表示しています。
- Button { selectedItem = item withAnimation { isExpanded = false } }:ボタンを押した(タップした)時は、selectedItem に選択した item を代入し、isExpanded に false を代入しています。
- if item != items.last { Divider() }:item が items の最終データで無い場合は、仕切り線を挿入しています。
- RoundedRectangle(cornerRadius: 8):ボタンの半径を 8 で指定した角丸四角形を設定しています。
- .offset(y: geo_height * dropdown_height):ドロップダウン(プルダウン)の高さの位置を、geo_height * dropdown_height で設定しています。dropdown_height には、親View(DropDownView)から0.1が渡されてきます。ドロップダウン(プルダウン)のボタンとドロワー(drawer)の隙間を狭くする場合は、geo_height * dropdown_height の値を調整してみて下さい。
アプリ実行:シミュレータ起動
では、実際にアプリを実行してみます。
Xcode の上部タブメニューより、Product → Run を選択するか、command + R を
押してみて下さい。
エラーが無ければ、iPhoneシミュレータが起動します。
ContntVeiw(メインメニュー)が表示されました。
NavigationListView:ナビゲーション画面
続けて、NavigationListViewボタンを押してみます(タップします)。
ContntVeiw(メインメニュー)の上に NavigationListVeiw(ナビゲーション機能)が
重なって、表示されました。
- SwipeView
- CarouselView
- BaseTabVeiw
- TabBarView
現在の 配列(path) の状態は、下記になります。
- path = []
TabBarView:上部Tab制御 & 3種類の画像ファイル選択方法
では、TabBarView を操作してみます。
MenuPicker
NavigationList の4段目の TabBarView を押してみます(タップします)。
画面上部には、TabBarView のタイトルが表示されていますが、
NavigationListVeiw で、タイトルを表示するように設定していました。
タイトルの下には、分かりにくいかもしれませんが、上部Tabが表示されています。
- 上部Tabの左側には、青色で猫のアイコンと MenuPicker の文字が表示されています。
- 上部Tabの中央には、グレー色で猫のアイコンと WheelPicker の文字が表示されています。
- 上部Tabの右側には、グレー色で足跡のアイコンと DropDown の文字が表示されています。
上部Tabの下には、IMG_0057 と画像のファイル名でボタンが表示されていますので、
押してみます(タップします)。
複数の画像のファイル名で、選択肢が表示された事が分かると思います。
複数の選択肢から、別の画像を選んでみます。
ボタンの下の猫の画像(IMG_0405)が、入れ替わっていると思います。
WheelPicker
次に、上部Tabの中央(WheelPicker)を押してみます(タップします)。
- 上部Tabの左側は、グレー色の猫のアイコンと MenuPicker に切り替わりました。
- 上部Tabの中央は、緑色の猫のアイコンと WheelPicker に切り替わりました。
- 上部Tabの右側は、グレー色の足跡のアイコンと DropDown の文字はそのままです。
上部Tabの下には、IMG_0088 と画像のファイル名で回転ホイールが表示されていますので、
スクロールして、複数の選択肢から、別の画像を選んでみます。
回転ホイールの下の猫の画像(IMG_0234)が、入れ替わっていると思います。
更にスクロールして、複数の選択肢から、別の画像を選んでみます。
回転ホイールの下の猫の画像(IMG_0976)が、入れ替わった事が分かると思います。
DropDown
次に、上部Tabの右側(DropDown)を押してみます(タップします)。
- 上部Tabの左側は、グレー色の猫のアイコンと MenuPicker の文字はそのままです。
- 上部Tabの中央は、グレー色に猫のアイコンと WheelPicker に切り替わりました。
- 上部Tabの右側は、ピンク色の足跡のアイコンと DropDown に切り替わりました。
上部Tabの下には、IMG_0981 と画像のファイル名がボタンに表示されていますので、
ファイル名を押してみます(タップします)。
ボタンの下に、ドロワー(drawer)が表示された事が分かると思います。
複数の選択肢から、別の画像を選んでみます。
ボタンの下の猫の画像(IMG_0688)が、入れ替わっていると思います。
上部Tab制御 & 3種類(MenuPicker/WheelPicker/DropDown)の画像ファイル選択方法を
利用して、猫の画像を入れ替えてみました。
まとめ
今回は、SwiftUIで、上部Tab制御 & 3種類の画像ファイル選択方法を利用した
アプリケーションを開発する記事を紹介しました。
次回は、SwiftUIで、マルチ言語を切り替えるアプリケーションを開発する記事を
紹介しようと思います。
- イラスト:いらすとや より引用

























コメント