SwiftUIX

SwiftUI で不足している機能やコンポーネントを補完するためのプロジェクトです。

細かいドキュメントはWiki (opens new window)にあるそうなのですが、正直読んでも全然わかりません。

明らかに内容が足りていないです。

価格

コンポーネント

いろいろ便利なコンポーネントがあるのですが、個人的には SearchBar と PaginationView が便利だと思います。

LinkPresentationView

Safari で指定された URL を開きます。

import SwiftUI
import SwiftUIX
struct ContentView: View {
    var body: some View {
        LinkPresentationView(url: URL(string: "https://tkgstrator.work/")!)
    }
}
1
2
3
4
5
6
7
8

BetterSafariView の方が便利なので使うことはないと思います。

ActivityIndicator

import SwiftUI
import SwiftUIX
struct ContentView: View {
    var body: some View {
        ActivityIndicator()
    }
}
1
2
3
4
5
6
7
8

ローディング中の画面を表示します。

ただし、SwiftUI2.0 ではProgressView()があるのでこれを利用することは少ないかと。

import SwiftUI
struct ContentView: View {
    var body: some View {
        ProgressView()
    }
}
1
2
3
4
5
6
7

Appearance

visible()という ViewModifier が追加されており、Bool 値を使って View の表示/非表示を切り替えられます。

import SwiftUI
import SwiftUIX
struct ContentView: View {
    @State var isVisible: Bool = true
    var body: some View {
        VStack {
            Button(action: { isVisible.toggle() }, label: {
                Text(isVisible ? "Show" : "Hide")
            })
            Text("Hello, World!")
                .visible(isVisible)
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

SwiftUI2.0 ではhidden()しかなく、この属性は Bool 値で切り替えできなかったのでvisible()は便利だと思います。

PaginationView

ページ送りの View を実装します。

似たようなものに TabView があるのですが、これはなぜか必ず八番目までの View のイニシャライザが呼ばれてしまうという仕様があり、一つ一つの View が重い場合には表示にやたらと時間がかかって不便でした。

PaginationView では常に表示している View のイニシャライザしか呼ばれないので重くなりません。

SwiftUIX でいまのところ一番便利な機能なのではないかと思っています。

import SwiftUI
import SwiftUIX
struct ContentView: View {
    @State var isVisible: Bool = true
    var body: some View {
        PaginationView(axis: .horizontal, transitionStyle: .scroll, showsIndicators: true, content: {
            ForEach(Range(0...100)) { index in
                Text("Hello, World \(index)!")
            }
        })
        .currentPageIndicatorTintColor(.primary)
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

SwiftUI では標準の検索フォームがないのでこれは非常に助かります。

import SwiftUI
import SwiftUIX
struct ContentView: View {
    @State var inputText: String?
    var body: some View {
        SearchBar("Input", text: $inputText)
    }
}
1
2
3
4
5
6
7
8
9
10

これだけでも便利なのですが、SearchBar を NavigationView に埋め込む ViewModifier があります。

import SwiftUI
import SwiftUIX
struct ContentView: View {
    @State var inputText: String?
    var body: some View {
        NavigationView {
            Text("Hello, world!")
                .navigationSearchBar {
                    SearchBar("Input", text: $inputText)
                }
                .navigationTitle("SwiftUIX Demo")
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

ただ、Form と組み合わせると表示が乱れることがあるようです。

VisualEffectBlurView

すりガラス的な効果を提供する View です。

利用できる効果はたくさんあるのでApple のドキュメント (opens new window)を見てください。

PresentationView

使い方は NavigationView に近い、Modal を表示するための View です。

とりあえずルート View に対して属性を付けておきます。こうしないと@Environmentがとってこれないので。

// SwiftUIXDemoApp.swift
import SwiftUI
import SwiftUIX
@main
struct SwiftUIXDemoApp: App {
    var body: some Scene {
        WindowGroup {
            PresentationView {
                ContentView()
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

次に、Modal を表示したい View で@Environmentを宣言して、以下のようにコーディングします。

import SwiftUI
import SwiftUIX
struct ContentView: View {
    @Environment(\.presenter) var presenter
    var body: some View {
        Button(action: present, label: {
            Text("Modal View")
        })
    }
    func present() {
        presenter?.present(
            PresentationView {
                ChildView()
                    .dismissDisabled(true)
            }
        )
    }
}
struct ChildView: View {
    @Environment(\.presenter) var presenter
    var body: some View {
        Button(action: dismiss) {
            Text("Dismiss")
        }
    }
    func dismiss() {
        presenter?.dismissSelf()
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

ただ、画面を回転させるとサイズがバグる問題があるのと、.modalPresentationStyle()が全然効きません。

なのでぼくが開発したSwiftyUI (opens new window)の方がまだまともに動くのではないかと思います(自画自賛)

Enum

SwiftUI では直接アクセスするのがめんどくさい Enum も完備されています。

Screen

デバイスの Screen のサイズをとってこれます。

// SwiftUI
UIScreen.main.bounds.size.width
// SwiftUIX
Screen.size.width
1
2
3
4
5

ちょっとだけ楽にかけます。

UserInterfaceIdiom

アプリが起動しているデバイスの Enum を取得します。

// SwiftUI
UIDevice.current.userInterfaceIdiom
// SwiftUIX
UserInterfaceIdiom.current
1
2
3
4
5

Orientation

// SwiftUI
UIDevice.current.orientation
UIApplication.shared.windows.first?.windowScene?.interfaceOrientation
// SwiftUIX
UserInterfaceOrientation.current
1
2
3
4
5
6

このとき注意しないといけないのはUIDevice.current.orientationは起動直後には.unknownという値が入っていて全く役に立たないということです。

なので SwiftUIX を使ったほうがいいですね。

記事は以上。

価格