Swift初心者がSwiftUIのみでページメニューもどきを作ってみた。
ニュース系のアプリ等は大体画面上部にタブメニューがありますが、そのタブメニューを実装するのに外部ライブラリでは、XLPagerTabStripやPageMenuがあるので、そのライブラリを使用する方が良いのかもしれませんが、Swift習得するための一歩としてSwiftUIのみでページメニューもどきを作ってみました。
目 次
1. 参考とした記事と本
- [SwiftUI][iOS]Button(ボタン)で画面遷移する方法(1 / 2)|ちょげぶろぐ
- SwiftUI ScrollViewで縦方向、横方向スクロールの実装方法!|PYOKROK
- 【SwiftUI】@Stateの使い方|カピ通信
- SwiftUI対応 たった2日でマスターできるiPhoneアプリ開発集中講座 Xcode 12/iOS 14対応
2. 開発環境
- iMac(Late2012)
- macOS Catalina(10.15.7)
- Xcode 12.4
- Swift 5.3.2
- 使用外部ライブラリ なし
3. ページメニューもどき実装内容
簡単に書くと下記のことをしております。
- 画面上部に横スクロールビューを配置。(ScrollView)
- 横スクロールビュー内にボタンを3つ作成する。
- 横スクロールビューの下部全体を切り替えするビューとする。
- 切り替えするビューを3つ作成する。
- ボタンをタップすると文字等を強調表示して画面を切り替える。
※尚、ボタンやビューの部分をそれぞれ増やしていくことでメニューを増やしていくことは出来ますが冗長になってしまいます。
スクリーンショット
4. 全体ソース
全体ソースですが動くことを大前提に作りましたのでかなり無駄が多いソースになっております。
表示するメニュー(ボタン)を増やしていくと、その分コード量も増えていくので実際のアプリに実装するのには全く向いていません。
クラス化したら使えるかもしれませんが、管理人の力量が付いたらやってみるかもしれません。
ほんの少しでも参考になれば嬉しいです。(^^)
<div class="hcb_wrap">
<pre class="prism line-numbers lang-swift" data-lang="Swift"><code>//
// ContentView.swift
// PageMenuView
//
// Created by Assy on 2021/10/03.
//
import SwiftUI
struct ContentView: View {
//列挙体(画面遷移する画面を作成、ここでは3つ)
enum display {
case first
case second
case third
}
//表示する画面の初期値
@State var displayMode = display.first
//ページメニューのボタンとViewを紐付けするプロパティ
@State var page1 = true
@State var page2 = false
@State var page3 = false
var body: some View {
VStack {
ScrollView (.horizontal, showsIndicators: false){
HStack{
//1つ目のボタン
Button(action: {
displayMode = display.first
self.page1 = true
self.page2 = false
self.page3 = false
}) {
if page1 == true {
SelectedMenu("ページ1")
} else if page1 == false {
unSelectedMenu("ページ1")
}
}
//2つ目のボタン
Button(action: {
displayMode = display.second
self.page1 = false
self.page2 = true
self.page3 = false
}) {
if page2 == true {
SelectedMenu("ページ2")
} else if page2 == false {
unSelectedMenu("ページ2")
}
}
//3つ目のボタン
Button(action: {
displayMode = display.third
self.page1 = false
self.page2 = false
self.page3 = true
}) {
if page3 == true {
SelectedMenu("ページ3")
} else if page3 == false {
unSelectedMenu("ページ3")
}
}
}
}
}
Spacer()
//条件分岐で画面を切り替え
if displayMode == display.first {
FirstView(viewMode: $page1)
} else if displayMode == display.second {
SecondView(viewMode: $page2)
} else if displayMode == display.third {
ThirdView(viewMode: $page3)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
//選択ボタンの表示
struct SelectedMenu : View{
let menu:String
init(_ text:String){
self.menu = text
}
var body: some View{
Text(self.menu)
.foregroundColor(Color.white)
.fontWeight(.heavy)
.padding(.horizontal, 15)
.padding(.vertical, 5)
.background(Color.red)
.clipShape(Capsule())
}
}
//非選択ボタンの表示
struct unSelectedMenu : View{
let menu:String
init(_ text:String){
self.menu = text
}
var body: some View{
Text(self.menu)
.foregroundColor(Color.white)
.padding(.horizontal, 10)
.padding(.vertical, 2)
.background(Color.blue)
.clipShape(Capsule())
}
}
//画面1
struct FirstView: View {
@Binding var viewMode: Bool
var body: some View {
Text("FirstView")
Spacer()
}
}
//画面2
struct SecondView: View {
@Binding var viewMode: Bool
var body: some View {
Text("SecondView")
Spacer()
}
}
//画面3
struct ThirdView: View {
@Binding var viewMode: Bool
var body: some View {
Text("ThirdView")
Spacer()
}
}</code></pre>
</div>
5. ソースコードDownload
一応ソースコード(Xcodeプロジェクト)のダウンロードは下記ボタンから。
6. おまけ:最近購入したコスパが良かったもの
スマホ連携の体重計を¥1599で購入したんですが、iOS用の専用アプリを開いて体重計に乗るだけで体重や体脂肪等の計測が出来て保存も出来て、更にはiOSのヘルスケアアプリとも連動するというスグレモノ。
国内メーカーだと、3倍以上の金額するのでかなりコスパが良いかと。
久しぶりに良い買い物したなあ。
体重計 体脂肪 体組成計 高精度 体重/筋肉量/BMIなど20項健康測定可能 強化ガラス採用 iOS/Androidアプリで健康管理 Bluetooth対応 ヘルスケア同期 日本語対応&取扱説明書付き