try! Swift Tokyoのライブ翻訳アプリのApple Vision Pro版を改善してみる

先週、try! Swift Tokyo 2025が開催されました。

https://x.com/tryswiftconf/status/1910664800562274440

このイベントではライブ翻訳アプリが活用されました。各参加者が自身のデバイスにアプリをインストールして利用します。FlittoというサービスのSDKをtry! Swift公式アプリに組み込む形で導入されました。

![スマホ版のビデオ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/f9cb0634-e266-4dad-99c8-2597da620383.gif)

この公式アプリにはApple Vision Pro版があります。

![Apple Vision Pro版のApp Storeのスクショ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/012aaaf5-f1dd-44d2-aec4-557ccca012d9.jpeg)

ライブ翻訳機能はApple Vision Pro版でも利用できます。

![Apple Vision Pro版のライブ翻訳のスクショ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/2c3e0097-c5a0-4339-b813-d44bdeadda30.jpeg)

実際に私がApple Vision Pro版でライブ翻訳機能を会場で利用してみました。
(iOS版と異なり)翻訳を見るために頭を下げる必要が無いので、非常に快適でした。

![Apple Vision Pro版のライブ翻訳のビデオ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/8ee154b8-2044-4511-bf73-7f1d401b6db9.gif)

ただ、「Apple Vision Proアプリ」としては、いくつか改善する余地がありそうでした。
本記事では、Apple Vision Proの特性を活かす改善案を3つ挙げてみます。


# 3つの改善案
## ① 独立したウインドウとしてポップアウトできるようにする
visionOSでは、macOSのようにマルチウインドウを活用できます。
YouTube LiveのようにチャットUIを独立したウインドウとしてポップアウトできるようにすると良いでしょう。

![YouTubeLiveのようなウインドウポップアウトのスクショ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/295465a6-af2f-46e3-b69f-74ef346c6b0b.png)


これらのメリットがあります。
- ユーザーがウインドウを配置しやすくなる。
- ライブ翻訳を表示しながら、メインウインドウでタイムテーブルを確認することができる。
- 複数の言語を見比べたり、最新情報を表示しつつ遡りやすくしたりできる。

![ウインドウポップアウトのスクショ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/b117fe1d-6d13-452a-aff6-1c4e17d76995.png)


```swift
WindowGroup(id: "liveTranslationOnly") {
  AppView(...)
}
.defaultWindowPlacement { _, context in
  .init(.trailing(context.windows.first!))
}
```

```swift
@Environment(\.openWindow) var openWindow

* * *

Button("Detach window") {
  self.openWindow(id: "liveTranslationOnly")
}
```


## ② 視線に自動的に反応するUIを非表示にする
ユーザーはライブ翻訳を利用する時に、ステージと翻訳ウインドウの間を繰り返し視線を移動させます。その際にvisionOSアプリに「視線に反応するUI」があるとユーザーにストレスを与えます。そのため、ライブ翻訳を表示している間は「視線に反応するUI」を非表示にした方が良いでしょう。
try! Swiftアプリにおいては「ウインドウバー」と「Tabバー」がその対象です。

![視線に反応するウインドウバーの動画](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/e46978b3-a634-4ba1-9f4d-76bb64fd8e29.gif)

![視線に反応するTabバーの動画](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/bf90f51e-8212-40f6-a47d-afd318b19587.gif)

### ウインドウバー
ウインドウの下部に白いバーが表示されます。ユーザーはこれでウインドウの位置を変更できます。このウインドウバーは視線に反応してしまいます。

![ウインドウバー非表示の比較のスクショ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/c59dd585-6a69-49f3-9fa4-751d770a3fe2.png)

以下のSwiftUIのコードでウインドウバーを非表示にできます。

```swift
@State var isWindowBarHidden: Bool = false

* * *

Toggle("Hide window bar", isOn: self.$isWindowBarHidden)
  .persistentSystemOverlays(self.isWindowBarHidden ? .hidden : .visible)
```


### Tabバー
Tabバーも視線に反応してしまいます。

![Tabバー非表示の比較のスクショ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/75b02a48-aa87-4585-a1de-1a5b8fe97cd5.png)

以下のSwiftUIのコードでTabバーを非表示にできます。

```swift
@State var isTabBarHidden: Bool = false

* * *

Toggle("Hide tab bar", isOn: self.$isTabBarHidden)
  .toolbar(self.isTabBarHidden ? .hidden : .visible,
           for: .tabBar)
```

もしくは、アプローチ①のウインドウをポップアウトすることでも解決できます。


## ③ ガラスバックグラウンドを非表示にする
visionOSのウインドウにはガラスのようなバックグラウンドがあります。
「ユーザーの好み」や「会場の環境」次第では、このガラス調のバックグラウンドを透明にした方が使いやすくなる場合もあるでしょう。
オプトインのオプションとして、このガラス調のバックグラウンドの透明度を変更できるようにすると良いと思います。

![ガラスバックグラウンド非表示の比較のスクショ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/86b80aea-b343-4a3d-b0b4-81bed66091de.png)

```swift
WindowGroup(id: "liveTranslationOnly") {
  AppView(...)
}
.windowStyle(.plain)
```

```swift
@State var isTransparentBackground: Bool = false

* * *

.background {
  Color.clear
    .glassBackgroundEffect()
    .opacity(self.isTransparentBackground ? 0.1 : 1)
}
```


## ① + ② + ③
![結果のビデオ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/ea1fa6ba-4ffd-4662-9a22-afaa4d395685.gif)


# 「フルスペースは駄目」
visionOSのアプリ構成にはウインドウとフルスペースの2種類があります。
ウインドウの場合、ユーザーは複数のアプリを同時に立ち上げることができます。
フルスペースの場合、アプリ設計の自由度は上がりますが、ユーザーは同時に1つのアプリしか起動できません。

![スクリーンショット 2025-04-16 22.12.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/db6fabc5-d0e6-47f8-b9f6-e04d19572ae7.png)

現在のtry! Swiftの公式アプリは、シンプルな単一ウインドウのvisionOSアプリです。

visionOSにおけるライブ翻訳機能はウインドウで提供した方が良いでしょう。フルスペースは適していないと思います。理由は以下の2点です。

- ユーザーがライブ翻訳を利用する際に、他のアプリを同時に立ち上げる可能性があります。例えば、Safariで調べ物したり、ノートアプリでメモをしたりするかもしれません。
- ライブ翻訳のウインドウの「ベストなポジション」や「ベストなサイズ」は、ユーザーの好みや会場の環境によってケースバイケースでしょう。そのため、それらの調整はユーザーに任せた方が良いでしょう。標準のウインドウであれば、それらが容易に実現できます。


# 余談。visionOSだけでなくiOSやmacOSでも改善すべきこと。
- テキストが更新されるたびに、UIが頻繁に上下に動く挙動がストレスなので、あまり動かないように最適化する。
- 段落のソートを逆にするオプトインオプションを追加する。
- フォントサイズやフォントデザイン、フォントウェイト、テキストの色などを変更するオプトインオプションを追加する。
- 「(翻訳されていない)オリジナルの書き起こし」を見たい。
- 「(翻訳されていない)オリジナルの書き起こし」と「翻訳」を同時に見たい。


# リンク
## try! Swift Tokyo公式アプリ(App Store)
https://apps.apple.com/app/id6479317240

## try! Swift Tokyo公式アプリのソースコード(GitHub)
https://github.com/tryswift/try-swift-tokyo

## try! Swift Tokyo公式サイト
https://tryswift.jp

## Flitto公式サイト
https://www.flitto.com/portal/ja

### ライブ翻訳サービス「Flitto Live Translation」の紹介ページ
https://livetr.flitto.com/ja/

## 私が開発したvisionOS向け置き時計アプリ「SpatialClock」
https://github.com/FlipByBlink/SpatialClock

## 今回のtry! Swift Tokyo 2025で私が登壇したトークの動画
<iframe width="560" height="315" src="https://www.youtube.com/embed/uVgxJpSvp-I?si=pFEUJdN-UsjcbXGV" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>