この記事は、iOSアプリ開発から公開までの流れ の第13章です。
本稿では、SwiftUI による端末の傾きによって画面レイアウトを変更する手順を記載します。
swiftUIで画面回転に対応してみる を流用させていただいただけなのでサラッと流します。
##1. 対象画面
今回作成する Ping アプリのログビューワーは以下のように Text Area と 3 つの Button から構成されます。
ログが折り返され見難い場合に、横向きにすると以下のように Button が画面の大部分を占めてしまい非常に使いにくくなります。
##2. 傾き検知方法
横向きにした時に Button 部分を非表示にしたいと思います。
####2-1. UIInterfaceOrientation 変数の用意
ObservableObject の自作クラス(環境設定情報の管理用クラス)に UIInterfaceOrientation 変数を追加します。
ググってみると「Model」というクラス名が一般的のようですが、既存の自作クラスに取り込みました。
(SwiftUI のプラグラミング作法としては不適切なのかもしれません)
:
final class SocPingSharedObject: ObservableObject {
@Published var orientation: UIInterfaceOrientation = .unknown. // コレ
@Published var pid = UInt16(getpid() & 0xFFFF)
@Published var isProcessing: Bool = false
:
####2-2. インスタンスの宣言と変数セット
SceneDelegate.swift でインスタンスを宣言し、先ほどの変数をセットします。
(コピペしただけなので技術的な解説はできません)
:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
@ObservedObject(initialValue: SocPingSharedObject()) var object: SocPingSharedObject // 追加
var window: UIWindow?
:
// 追加
func windowScene(_ windowScene: UIWindowScene, didUpdate previousCoordinateSpace: UICoordinateSpace, interfaceOrientation previousInterfaceOrientation: UIInterfaceOrientation, traitCollection previousTraitCollection: UITraitCollection) {
withAnimation {
object.orientation = windowScene.interfaceOrientation
}
}
}
####2-3. 画面レイアウトの実装
UIInterfaceOrientation 変数の isPortrait が真(画面が縦向き)の場合のみ、Button を表示するようにします。
:
fileprivate struct SocPingLogViewer: View {
@EnvironmentObject var object: SocPingSharedObject
@State var text: String = ""
:
var body: some View {
ZStack {
VStack(spacing: 0) {
SocPingScreen(text: self.$text)
if object.orientation.isPortrait { // 縦向きの場合
Form {
Button(action: { ...中略... }) {
:
}
Button(action: { ...中略... }) {
:
}
Button(action: { ...中略... }) {
:
}
}
.frame(height: 200)
}
}
.navigationBarTitle(Text("Log Viewer"), displayMode: .inline)
:
終わり。