3
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SwiftUIで著名アプリのUIをトレース ~Spotify編~

Last updated at Posted at 2020-09-24

iOS14とXcode12がリリースされ、SF Symbols2が使えるようになったので著名なアプリのUIをトレースするのが簡単になったなぁと思いレイアウトの勉強がてらSpotifyの再生画面をトレースしてみました。

完成品

Simulator Screen Shot - iPhone 8 - 2020-09-24 at 18.53.37.png
厳密には背景がアートワークのグラデーションが薄っすらかかっていますが割愛

もしもSpotifyがライトモードだったら

Simulator Screen Shot - iPhone 8 - 2020-09-24 at 18.53.43.png

SwiftUIが自動でライトモードとダークモード対応してくれるので、こんなもしかしたらな画面も生成できました。
まぁライトモードでこれだと完全トレースとは言えないんですが。。。

コード

PlayerView.swift

import SwiftUI

struct PlayerView: View {
    @Binding var isPresent: Bool
    @State var seekValue = 0.7
    @State var isPlaying = false
    
    var body: some View {
        VStack(spacing: 24) {
            HStack {
                Button(action: {
                    self.isPresent = false
                }, label: {
                    Image(systemName: "chevron.down")
                        .foregroundColor(.primary)
                })
                Spacer()
                Text("834.194")
                    .font(.caption)
                    .fontWeight(.semibold)
                Spacer()
                Image(systemName: "ellipsis")
            }
            Image("artwork")
                .resizable()
                .imageScale(.large)
                .scaledToFit()
            TitleAndSeekControl(seekValue: $seekValue)
            PlayerControl()
            ActionControl()
        }
        .padding(.horizontal)
    }
}

private struct TitleAndSeekControl: View {
    @Binding var seekValue: Double
    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            Text("忘れられないの")
                .font(.title2)
                .fontWeight(.semibold)
            Text("サカナクション")
                .foregroundColor(.secondary)
            Slider(value: $seekValue)
                .accentColor(.secondary)
            HStack {
                Text("2:31")
                Spacer()
                Text("3:43")
            }
            .foregroundColor(.secondary)
            .font(.caption)
        }
    }
}

private struct PlayerControl: View {
    var body: some View {
        HStack {
            Image(systemName: "heart")
            Spacer()
            HStack(spacing: 32) {
                Image(systemName: "backward.end.fill")
                    .font(.title2)
                Image(systemName: "play.circle.fill")
                    .font(.system(size: 48))
                Image(systemName: "forward.end.fill")
                    .font(.title2)
            }

            Spacer()
            Image(systemName: "minus.circle")
        }
        .imageScale(.large)
    }
}

private struct ActionControl: View {
    var body: some View {
        HStack {
            Image(systemName: "tv.and.hifispeaker.fill")
            Spacer()
            Image(systemName: "square.and.arrow.up")
        }
        .imageScale(.medium)
    }
}

struct PlayerView_Previews: PreviewProvider {
    @State static var isPresent: Bool = true
    static var previews: some View {
        PlayerView(isPresent: $isPresent)
    }
}

それとなくStackでグルーピングされてそうな要素を個別のViewに書き出しています。
Viewモディファイアの勉強に既存のアプリのトレースはなかなかいいです。
あくまで見た目上のトレースなので実用するにはバインディングをもうちょっと整理しないといけませんが。

非デザイナーに嬉しいSF Symbols

僕は画面のオブジェクトを自分でデザインとかできないのでSF Symbolsは相当助かります。
SF Symbolsはこんなのもあるの?ってくらい追加されているので、iOSアプリ開発ではFontAwesomeからSF Symbolsに移行していくのではないでしょうか。

3
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?