さまざまなダイナミックタイプサイズでレイアウトをプレビューする方法
How to preview your layout at different Dynamic Type sizes
このコードは、極小サイズ、通常サイズ、および可能な最大サイズでのデザインを示しています。
//-----------------------------------
struct ContentView: View {
@Environment(\.sizeCategory) var sizeCategory : ContentSizeCategory
//--------------------------
func getSize() -> String {
switch(self.sizeCategory) {
case .extraSmall:
return "extraSmall"
case .small:
return "small"
case .medium:
return "medium"
case .large:
return "large"
case .extraLarge:
return "extraLarge"
case .extraExtraLarge:
return "extraExtraLarge"
case .extraExtraExtraLarge:
return "extraExtraExtraLarge"
case .accessibilityMedium:
return "accessibilityMedium"
case .accessibilityLarge:
return "accessibilityLarge"
case .accessibilityExtraLarge:
return "accessibilityExtraLarge"
case .accessibilityExtraExtraLarge:
return "accessibilityExtraExtraLarge"
case .accessibilityExtraExtraExtraLarge:
return "accessibilityExtraExtraExtraLarge"
@unknown default:
return "default"
}
}
//--------------------------
var body: some View {
Text(getSize())
}
}
//-----------------------------------
//-----------------------------------
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView()
.environment(\.sizeCategory, .extraSmall)
ContentView()
ContentView()
.environment(\.sizeCategory, .accessibilityExtraExtraExtraLarge)
}
}
}
ライトモードとダークモードでレイアウトをプレビューする方法
How to preview your layout in light and dark mode
Xcode12.0用に更新
Appleのオペレーティングシステムのほとんどは、ライトモードとダークモードの両方のユーザーインターフェイスをサポートしているため、SwiftUIがこの機能をサポートしているのは当然のことです。
さらに良いことに、インターフェイスを設計すると、Xcodeでは\.colorScheme、プレビューで環境値を設定することにより、いずれかの配色でレイアウトをプレビューできます。
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView()
.environment(\.colorScheme, .light)
ContentView()
.environment(\.colorScheme, .dark)
}
}
}
さまざまなデバイスでレイアウトをプレビューする方法
How to preview your layout in different devices
XcodeのSwiftUIプレビューでは、.previewDevice()修飾子を使用して、デザインを複数の画面サイズで同時に表示できます。これには、Xcodeの宛先メニューに表示されるデバイスの正確な名前(「iPhoneXSMax」など)を指定する必要があります。
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView()
.previewDevice(PreviewDevice(rawValue: "iPhone SE"))
.previewDisplayName("iPhone SE")
ContentView()
.previewDevice(PreviewDevice(rawValue: "iPhone XS Max"))
.previewDisplayName("iPhone XS Max")
}
}
}
ナビゲーションビューでレイアウトをプレビューする方法
How to preview your layout in a navigation view
ナビゲーションスタックの一部として表示されることがわかっているビューを設計したが、それ自体にナビゲーションビューが含まれていない場合、デフォルトではナビゲーションバーのタイトルやボタンは表示されません。
幸い、プレビュー内のナビゲーションビューにビューを追加できます。これは、ライブコード用のナビゲーションバーを実際に追加せずに、上部にナビゲーションバーがあることをシミュレートするため、外観を正確に確認できます。
struct ContentView: View {
var body: some View {
Text("Hello World")
.navigationBarTitle("Welcome")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
ContentView()
}
}
}
How to use Instruments to profile your SwiftUI code and identify slow layouts
Instrumentsを使用してSwiftUIコードをプロファイリングし、遅いレイアウトを特定する方法
XcodeのInstrumentsツールには、SwiftUIの素晴らしい分析セットが付属しており、ビューが再描画された頻度、ビューの本体の計算が遅かった回数、さらには状態が時間の経過とともにどのように変化したかを特定できます。
まず、Instrumentsで見ることができる興味深い結果を提供できるものが必要です。 したがって、このコードは、0.01秒ごとにトリガーするタイマーを作成し、ランダムなUUIDを表示するボディビューと、タップするたびに表示される値を増やすボタンを備えています。
シミュレーターでそのコードを実行すると、値が常に変化しているため、コードが絶えず再描画されていることがわかります。
注:これは、Instrumentsが興味深いデータを表示するために、SwiftUIに多くの作業を行わせるために特別に設計されたストレステストです。実際のアプリで上記のコードを使用することは望ましくありません。
コードのインストルメント
次に、Cmd + Iを押してInstrumentsを介してコードを実行し、SwiftUIインスツルメントを選択します。表示されたら、録画ボタンを押してアプリを起動し、視聴を開始します。ボタンを10回ほどクリックしている間、数秒間実行してから、Instrumentsでstopを押します。作業するのに十分なデータがあります。
デフォルトでは、SwiftUIインスツルメントはさまざまなことを教えてくれます。
その間に作成されたビューの数と、それらの作成にかかった時間(「ビューボディ」)
ビューのプロパティとは何か、および時間の経過とともにどのように変化したか(「ビューのプロパティ」)
発生したコアアニメーションコミットの数(「コアアニメーションコミット」)
各関数呼び出しにかかった正確な時間(「タイムプロファイラー」)
これらの各機器は、SwiftUIアプリケーションのパフォーマンスの問題を診断して解決するのに役立つため、時間をかけて試してみる価値があります。
私たちの小さなストレステストサンドボックスでは、ビューボディ、ビュープロパティ、およびコアアニメーションコミットの色の無地の壁が表示されます。これはすぐに赤いフラグです。これは、SwiftUIがビューを絶えず再作成する必要があるだけでなく、プロパティが絶えず変化しているため、コアアニメーションが追いつくために残業しなければならないことを示しています。
以下続く!!!!!!
import Combine
import SwiftUI
//--------------------------------------------
class FrequentUpdater: ObservableObject {
let objectWillChange = PassthroughSubject<Void, Never>()
var timer: Timer?
init() {
timer = Timer.scheduledTimer(
withTimeInterval: 0.01,
repeats: true
) { _ in
self.objectWillChange.send()
}
}
}
//--------------------------------------------
struct ContentView: View {
@ObservedObject var updater = FrequentUpdater()
@State private var tapCount = 0
var body: some View {
VStack {
Text("\(UUID().uuidString)")
Button(action: {
self.tapCount += 1
}) {
Text("Tap count: \(tapCount)")
}
}
}
}
//--------------------------------------------



