dasukoの技術ブログ

現役エンジニアのブログです。

【SwiftUI】テキストのAlignmentについて(左に寄せる方法)

はじめに

今回はView(特にText)を左に寄せたり、右に寄せたりする方法をご紹介します。

SwiftUIでのプロジェクトの作り方は以下の記事でご紹介しています。

dasuko.hatenadiary.jp

 

VStackやHStackについてはこちらの記事で解説しています。

dasuko.hatenadiary.jp

multilineTextAlignment

multilineTextAlignmentを使えばテキストを左寄せ、真ん中寄せ、右寄せにすることができます。

Sets the alignment of multiline text in this view. このビューで複数行のテキストの配置を設定します。

とあるようにテキストのView内での配置を指定できます。

import SwiftUI

struct ContentView: View {
    @State private var isPlaying: Bool = false
    
    var body: some View {
        Text("Text\nThis is Text")
            .multilineTextAlignment(.leading)
    }
}

プレビューはこんな感じになります。

f:id:dasuko:20210220145256p:plain

ちなみに真ん中寄せにした場合

import SwiftUI

struct ContentView: View {
    @State private var isPlaying: Bool = false
    
    var body: some View {
        Text("Text\nThis is Text")
            .multilineTextAlignment(.center)
    }
}

struct LeftAligned: ViewModifier {
    func body(content: Content) -> some View {
        HStack {
            content
            Spacer()
        }
    }
}

f:id:dasuko:20210220145413p:plain

View全体を左端に寄せたい場合

View全体をどこかに寄せたい場合はスペースを作りたいところにSpacerを指定することで実現できます。

import SwiftUI

struct ContentView: View {
    @State private var isPlaying: Bool = false
    
    var body: some View {
        Text("Text\nThis is Text")
            .leftAligned()
    }
}

struct LeftAligned: ViewModifier {
    func body(content: Content) -> some View {
        HStack {
            content
            Spacer()
        }
    }
}

extension View {
    func leftAligned() -> some View {
        return self.modifier(LeftAligned())
    }
}

プレビューはこんな感じになります。

画面の左端にテキストが寄っていることがわかります。

f:id:dasuko:20210220150031p:plain

もちろん右端に寄せることも可能です。

import SwiftUI

struct ContentView: View {
    @State private var isPlaying: Bool = false
    
    var body: some View {
        Text("Text\nThis is Text")
            .rightAligned()
    }
}

struct RightAligned: ViewModifier {
    func body(content: Content) -> some View {
        HStack {
            Spacer()
            content
        }
    }
}

extension View {
    func rightAligned() -> some View {
        return self.modifier(RightAligned())
    }
}

プレビューはこんな感じです。

右端に寄っているのがわかるかと思います。

f:id:dasuko:20210220150418p:plain

参考

ios - SwiftUI text-alignment - Stack Overflow

Apple Developer Documentation

【SwiftUI】@Stateと@Bindingの関係

SwiftUIでのプロジェクトの作り方、導入についてはこちらで紹介しています。

dasuko.hatenadiary.jp

StateとBinding

SwiftUIのViewはstructなのでプロパティの値を変更できません。

View間でプロパティのやりとりをしたい場合はStateBindingを使います。

 

SwiftUIでは、親Viewで宣言したStateプロパティを子Viewに渡し、子Viewでそのプロパティ値を変更することができます。

これはStateプロパティが単なる値ではなく、ここで宣言された変数はSwiftUIフレームワークによってメモリ管理されます。

SwiftUIによって実値が管理される読み書きが可能なプロパティーラッパーという感じです。

プロパティの本来の値を直接参照したい場合はwrappedValueを参照します。

 

SwiftUIでは、Viewをbody内で定義しますが、StateプロパティやBindingプロパティの値が変更されると

SwiftUIは自動的にbody内を再構築します。

State

SwiftUIでStateプロパティの変数をViewに渡すには$をつけて渡します。

import SwiftUI

struct ContentView: View {
    @State private var text = ""
    
    var body: some View {
        TextField("Text", text: $text)
    }
}

 

Stateプロパティの値はこのように参照することも可能です

@State private var isPlaying: Bool = false

...

if isPlaying == true {
    Text("isPlaying")
}

Binding

Stateプロパティで宣言された値は、Viewに渡すときに$をつけてBindingプロパティとして渡します。

 

これにより、親Viewのプロパティのバインディングが作成されます。

こちらはAppleのドキュメンに載っているサンプルとほとんど同じですが、

クリックする度にボタンの画像が次のように変化します。

再生中ボタン<->停止ボタン

import SwiftUI

struct ContentView: View {
    @State private var isPlaying: Bool = false
    
    var body: some View {
        VStack {
            PlayButton(isPlaying: $isPlaying)
        }
    }
}

struct PlayButton: View {
    @Binding var isPlaying: Bool
    
    var body: some View {
        Button(action: {
            self.isPlaying.toggle()
        }, label: {
            Image(systemName: isPlaying ? "pause.circle" : "play.circle")
        })
    }
}

 

プレビューはこんな感じです。

gyazo.com

このサンプルではContentViewの子ViewであるPlayButtonの中でしかisPlayingを変更していませんが、

もちろんContentViewで値を変更した場合もPlayButtonに反映されます。

 

例えばこんな感じでContentViewでToggleも定義し、

ToggleでもisPlayingの値を変更できるようにしてみます。

 

import SwiftUI

struct ContentView: View {
    @State private var isPlaying: Bool = false
    
    var body: some View {
        VStack {
            Toggle("Play", isOn: $isPlaying)
                .padding(50)
            
            PlayButton(isPlaying: $isPlaying)
        }
    }
}

struct PlayButton: View {
    @Binding var isPlaying: Bool
    
    var body: some View {
        Button(action: {
            self.isPlaying.toggle()
        }, label: {
            Image(systemName: isPlaying ? "pause.circle" : "play.circle")
        })
    }
}

 

プレビューはこのようになり、PlayButtonにも値の変更が反映されているのがわかるかと思います。

gyazo.com

最後に

値が変更されたときにViewを自動的に再構築するSwiftUI最高すぎますね!!!

値を更新するときにViewの更新を気にする必要がないということなので、

ロジック部分の開発により注力できるようになるのかなと思います!

参考

Apple Developer Documentation

【プログラミング】プログラマー、実は仕事中あまりプログラミングしていない件について

はじめに

正直人による。組織によるとは思うが、

職種がエンジニアプログラマーという職種であっても

あまり仕事中にコーディングしていないという人は少なくないのではないかと思う。

 

私もその一人である。

 

これは学生や、プログラマー以外の職種の人から見れば意外なのではないかと思う。

 

 

私も学生の時は「プログラマーは仕事中ずっとコーディングしてるんだろうなー」と思っていた。

正直今では就活を終えた大学生の方がコーディングする時間はずっと多いと思う。。。。

 

ちなみに私の仕事の割合で言うと、

約8割は以下のような感じである。

  • 実装に関する質問に答える
  • 後輩の教育
  • よくわからない会議

 

それ以外の2割はコーディングしている

※割合は日による

 

ということで一旦良書を紹介してお茶を濁しておく。

 

実装に関する質問

これは、まあ正直仕様書とか見るより開発している当人であるプログラマー(エンジニア)に聞く方が最新の正しい回答が得られるだろうということなのだと思う。

ただ、多くの場合相手がプログラマー(エンジニア)以外の職種なので、

説明するコストは、もちろん相手がプログラマー(エンジニア)である場合と比べると高い。

(技術がわかる人なら別)

 

そして、多くの場合、プログラマーも頭に全て仕様が入っているというわけではないので、

実際にコードを読み返してみたり、本番環境でテストしてみたりしなければならないことが多々ある。

そのため、非常に多くの時間がかかる。

 

後輩の教育

これに関してはどの職種でもあると思う。

ただ、技術職である分、教えるのにも時間がかかる。

そもそもある程度知識が必要だったり、考えないとできないタスクが多かったり、ある程度経験が必要なタスクが多いからだ。

よくわからない会議

これに関しても他のどの職種でもあると思う。

しかし、本来物を作るのに時間や頭を使わなければならないエンジニアが

会議前に無駄に共有資料の作成に凝らなければならないという空気を感じ、それに時間をかけなければならないということが多くある。

また、会議中も人の話を聞いているのは退屈だし、ほぼ意味がないと思っている。開発に時間を使う方が会社にとっても有益なはずだと思う。

(もちろん有益な会議もある)

コーディングに時間を割けたとして

コーディングに時間を割けたとしても、多くの場合、開発のための調査をするのに時間が必要である。

設計をするのにも時間が必要である。

エンジニアチームで相談しながら進める必要がある。

といったようにちょっとした時間で進められる仕事ではないということを理解してもらいたいと強く思う

(表現下手でごめんなさい)

結果として

プログラマーとしてやらなければならない開発のタスクが多いにも関わらず、開発とは無関係なタスクが多いことから

業務時間中に仕事が終わらず、業務時間後に渋々残業をしなければならないというプログラマー(エンジニア)は多いのではないかと思う。

この、業務時間中にあまりプログラミングしていないというところは、外の人間からすると、意外なのではないかと思う。

ぜひ明日からはプログラマー(エンジニア)の人に優しい声をかけていただければと思います

【SwiftUI】VStack、HStack、ZStackについて

概要

SwiftUIでは複数のViewの配置を定義するためにHStackVStackZStackといったStackViewを使います。

StackViewを使用した場合、デフォルトでコンテンツを中央揃えにし、かつわずかな程よい間隔を挿入してくれます。

HStack

子Viewを水平に配置します。

サンプル

item1item5という5つのテキストを水平に配置したい場合は以下のようになります。

import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack(
            alignment: .top,
            spacing: 10
        ) {
            ForEach(
                1...5,
                id: \.self
            ) {
                Text("Item \($0)")
            }
        }
    }
}

プレビューはこんな感じです。

f:id:dasuko:20210216231757p:plain

 

ちなみにspacing0にするとこんな感じでテキストの間隔がなくなります。

f:id:dasuko:20210216232011p:plain

VStack

子Viewを垂直に配置します。

サンプル

item1item5という5つのテキストを垂直に配置したい場合は以下のようになります。

struct ContentView: View {
    var body: some View {
        VStack(
            alignment: .leading,
            spacing: 10
        ) {
            ForEach(
                1...5,
                id: \.self
            ) {
                Text("Item \($0)")
            }
        }
    }
}

プレビューはこんな感じです。

f:id:dasuko:20210216232445p:plain

ちなみにspacing50にするとこんな感じでテキストの感覚が大きくなります。

f:id:dasuko:20210216232400p:plain

ZStack

子Viewをオーバーレイします。

Stackは子Viewを宣言順にZ方向に重ねます。

後から宣言したViewは前のViewよりも上に表示されます。

サンプル

item1item5というテキストを重ねて表示する場合は以下のようになります。

import SwiftUI

struct ContentView: View {
    var body: some View {
        ZStack {
            ForEach(
                1...5,
                id: \.self
            ) {
                Text("Item \($0)")
            }
        }
    }
}

プレビューはこんな感じです。

上に重なってますね。

f:id:dasuko:20210216233354p:plain

テキストだとわかりづらいので、Appleのドキュメントにあるサンプルをプレビューしてみます。

AppleのドキュメントではRectangle Viewをそれぞれ完全に重ならないように配置しています。

import SwiftUI

struct ContentView: View {
    let colors: [Color] =
        [.red, .orange, .yellow, .green, .blue, .purple]

    var body: some View {
        ZStack {
            ForEach(0..<colors.count) {
                Rectangle()
                    .fill(colors[$0])
                    .frame(width: 100, height: 100)
                    .offset(x: CGFloat($0) * 10.0,
                            y: CGFloat($0) * 10.0)
            }
        }
    }
}

プレビューはこんな感じです。

こっちの方がわかりやすいですね!!!!!!

f:id:dasuko:20210216233709p:plain

VStackとHStackを組み合わせてみる

最後にVStackHStackを組み合わせた場合を見ていきます。

次の例では水平方向に2つ、垂直方向に2つRectangleを配置しています。

import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack {
            VStack {
                Rectangle()
                    .fill(Color.red)
                    .frame(width: 100, height: 100)
                
                Rectangle()
                    .fill(Color.orange)
                    .frame(width: 100, height: 100)
            }
            
            VStack {
                Rectangle()
                    .fill(Color.yellow)
                    .frame(width: 100, height: 100)
                
                Rectangle()
                    .fill(Color.green)
                    .frame(width: 100, height: 100)
            }
        }
    }
}

プレビューはこんな感になります。

f:id:dasuko:20210216234316p:plain

参考

Apple Developer Documentation

【SwiftUI】SwiftUIとは?プロジェクトの作り方まで紹介(超初心者向け)

SwiftUIとは

SwiftUIはSwiftで全てのAppleプラットフォーム(iPhoneiPadMacApple Watch...)向けのUI(ユーザインターフェース)をシンプルに構築するためのApple純正のフレームワークです。

Xcode - SwiftUI - Apple Developer

2019年6月にAppleがSwiftUIフレームワークを発表し、2019年9月にSwiftUIフレームワークを含むiOS13が一般公開されました。

SwiftUIのメリット

  • 宣言型シンタックスによりとてもシンプルに記述できる
  • Xcodeのプレビューで確認できるのでUIの確認にシミュレーターや実機が不要
  • Storyboardと比較して実装のしやすさと共に可読性も格段に向上(マージしんどかった...TT)

 

また、下記機能に自動的に対応してくれます。

プレビュー機能について

SwiftUIでは簡単にUIを構築できる点が魅力的なのはもちろんだが、

個人的にはプレビュー機能が特に気に入っています!

コードに変更を加えると、即座に再コンパイルされ、プレビューに反映されます!

(これで開発も捗る!)

f:id:dasuko:20210216213222p:plain

プレビューから編集

ちなみにこんな感じでプレビューからUIを編集することも可能です。

プレビューから編集した場合もコードが更新されます。

(cmd + Clickで起動)

f:id:dasuko:20210216215754p:plain

Embed in VStackを選択すると、該当Viewのコードは以下のように変化します

(具体的な記法については後日書きます)

before

struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
            .padding()
    }
}

after

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Hello, world!")
                .padding()
        }
    }
}

 

めっちゃ便利!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

新規プロジェクト作成方法

ここまでSwiftUIについてざっくり説明したので、プロジェクトの作成方法についてを紹介します!

まずはXcodeを起動し、Create new Xcode Projectを選択し、プロジェクト作成画面を立ち上げます。

次に以下のように設定します。

  • Interface->SwiftUI
  • LifeCycle->SwiftUI App
  • Language -> Swift

f:id:dasuko:20210216213501p:plain

※Product NameやOrganization Identifierはそれぞれ入力してください

   

これでSwiftUIが導入されたプロジェクトを作成できました!

プレビューを起動してみる

SwiftUIのViewを実装したファイルをプロジェクトナビゲーターで選択すると、プレビューウインドウが表示されます プレビューを起動するには以下のResumeボタンを押します

f:id:dasuko:20210216214027p:plain

すると先ほどのようにHello, world!と出力されます

f:id:dasuko:20210216213222p:plain

 

もし、プレビューウインドウが表示されない場合

以下のボタンをクリックします。

f:id:dasuko:20210216214428p:plain

Canvasを選択します。

f:id:dasuko:20210216214512p:plain

 

すると、プレビューが起動します。

f:id:dasuko:20210216213222p:plain

参考

Xcode - SwiftUI - Apple Developer

iOSのDynamic Typeについて - Qiita

【Unity】MenuItemでショーカットキーを設定する

はじめに

UnityにはMenuItemというメインメニューとインスペクターのコンテキストメニューにメニューアイテムを追加することができるAttributeがあります。

MenuItemの公式のドキュメントはこちら

UnityEditor.MenuItem - Unity スクリプトリファレンス

MenuItemの基本的な使い方

以下のようにMenuItemというAttributeを特定のメソッドに追加することにより、メインメニューやコンテキストメニューにメニューアイテムを追加できます。

    [MenuItem("CustomMenu/Do Something")]
    static void DoSomething()
    {
        Debug.Log("Do Something.");
    }

こんな感じでメニューに追加されます。

f:id:dasuko:20201030012901p:plain

これを実行すると、意図した通りにコンソールにログが出力されます。

f:id:dasuko:20201030012823p:plain

ホットキーを定義する

MenuItemは、ホットキー(ショートカットキー)を作成することもできます。

以下のような特殊文字を使用するかどうかで表記方法が異なります。

コマンド 特殊文字
cmd %
shift #
alt(option) &

特殊文字を使用する場合

上記の特殊文字を使用する場合は、以下のようにコマンド名の最後にスペースを入れ、その後にショートカットキーを指定します。

(Do SomethingなのでCommand + dにしてみました)

    [MenuItem("CustomMenu/Do Something %d")]
    static void DoSomething()
    {
        Debug.Log("Do Something.");
    }

メニューにもショートカットーキーが表示されます。

f:id:dasuko:20201030171154p:plain

Command + shift + option + dの場合はこんな感じ

f:id:dasuko:20201030171303p:plain

これらのコマンドを打つことで、特定の処理を実行することができます!

特殊文字を使用しない場合

特殊文字を使用しない場合は、コマンド名の最後にスペースを入れ、その後に_ + ショートカットキーを指定します。

    [MenuItem("CustomMenu/Do Something _d")]
    static void DoSomething()
    {
        Debug.Log("Do Something.");
    }

f:id:dasuko:20201030171701p:plain

最後に

MenuItemでメニューを拡張できる上にショートカットを指定できるのは便利ですね。

今回、特殊文字を使用しない例として、dを指定しましたが、

誤って処理を実行してしまう可能性もあるので、cmd + dとかにするのがいいかなと思います。

参考

UnityEditor.MenuItem - Unity スクリプトリファレンス

エンジニアは大きく2つのタイプに分けられるという話

はじめに

これまで10年以上プログラミングをしてきて、エンジニアには大きく2つのタイプがいるなーと感じます。

※基本的にこれらは、個人の意見であり、偏見であり、必ずしもそうという訳ではありません。

エンジニアのタイプ

それはクリエイタータイプと技術者タイプです。

※クリエイターかつ技術者というのも存在します。

※2つじゃなくて3つやないかい!という質問は受け付けておりません。

クリエイタータイプ

このタイプの人は主にBtoC事業の会社に興味を持ちがちです。

なぜなら「誰もが知っていて、誰もが使っていて楽しい使いやすいと思えるサービスを作りたい!」と思っているからです。

最高のものを作って、とにかくみんなに触ってもらいたい!と思います。

ゲーム開発者やアプリ開発者になる人が多いです。

(個人開発者とかは特にこのタイプが多いと思います。)

特徴としては、

  • とにかく時間があれば、いい物を作るために使いたい。改良したいと思う
  • リファクタリングは後からでいいよね!と割り切る
  • プログラミングの勉強の他に企画を考えたり、世の中の面白いものを触るのに時間を使う
  • 技術者タイプの人がちょっと苦手
  • 設計には拘らないが、コードフォーマットは気にしがち
  • プルリクエストのレビューをするときは、コードを見るより動作を見る(動けばオッケー)
  • ゲームをするときでも、そのゲームのどこが面白いのかを分析しがち
  • 個人開発をするときもゲームや面白いアプリを作りがち
  • チームで開発するのが好き
  • ミーティングが好き

技術者タイプ

このタイプの人はBtoC、BtoBどちらにもいます。

企業選びの際は、何を作っているかよりも重要としているポイントがあったりします。

システム開発とかツール開発が好きだったりもします。

特徴としては、

  • 新しい技術を取り入れがち
  • 企画よりもまず、設計や言語や開発環境、ライブラリ選定などに拘る
  • インデントがタブだと鳥肌がたつ
  • 時間があったら新しい技術を試したり、何かを作る
  • ゲームをするときは、この表現をするのにどのような処理をしているのかを考えがち
  • 個人開発をするときはツールやライブラリを作りがち
  • 物理・数学が得意
  • 開発をするときには、できるだけ一人の時間がほしい

技術者かつクリエイタータイプ

技術者タイプとクリエイタータイプのどちらでもある人もいます。

ゲーム開発者に多い印象です。

最後に

あくまで個人の意見であり、偏見なのであまり鵜呑みにしないでください。

クリエイタータイプの人は割と文系思考で、技術者タイプの人は理系思考って感じですかね。