見出し画像

SwiftUIでいこう!- スタンフォード大学Lecture 2 - 4 ボタン配置など。

絵文字の数を決める変数を作ります。

var emojicount = 4

これで絵文字の数をコントロールします。

 ForEach(emojis[0..<emojicount], id: \.self){emoji in
                   CardView(content:emoji)
               }

絵文字を増やしたり、減らしたりするボタンを作ります。

Button(action: {
               emojicount += 1
           }, label: {
               VStack{
                   Text("Add")
                   Text("Card")
               }
           })
           
Button(action: {
               emojicount -= 1
           }, label: {
               VStack{
                   Text("Remove")
                   Text("Card")
               }
           })
           

ここまでのコード

struct ContentView: View {
   var emojis = ["✈️","🐶","🐱","🐻","🚁","🚗","🚇"]
   var emojicount = 4
   
   var body: some View {
       VStack{
           HStack{
               ForEach(emojis[0..<emojicount], id: \.self){emoji in
                   CardView(content:emoji)
               }
           }
           HStack{
               Button(action: {
                   emojicount += 1
               }, label: {
                   VStack{
                       Text("Add")
                       Text("Card")
                   }
               })
               Spacer()
               Button(action: {
                   emojicount -= 1
               }, label: {
                   VStack{
                       Text("Remove")
                       Text("Card")
                   }
               })
           }

       }
       
       .padding(.horizontal)
       .foregroundColor(.red)
   }
}

このまま実行すると" Button()"の部分がエラーとなります。

Left side of mutating operator isn't mutable: 'self' is immutable

変数 emojicount のvarの前に@Stateをつけます。

SwiftUIでのViewはstructであるため保持するプロパティを変更することができません。
そこで、@Stateを付与したプロパティはメモリ管理がSwiftUIフレームワークに委譲され、変更が可能となります。
プロパティは値の変更が監視され、変更時に宣言されたViewのbodyが再描画されます。

@State var emojicount = 4

とするとエラーはなくなります。

次に、                                                                                                       

var add:some View{
       Button(action: {
           emojicount += 1
       }, label: {
           VStack{
               Text("Add")
               Text("Card")
           }
       })
   }
   
var remove:some View{
       Button(action: {
           emojicount -= 1
       }, label: {
           VStack{
               Text("Remove")
               Text("Card")
           }
       })
   }

とすると

var body: some View {
       VStack{
           HStack{
               ForEach(emojis[0..<emojicount], id: \.self){emoji in
                   CardView(content:emoji)
               }
           }
           HStack{
               add
               Spacer()
               remove
           }
           padding(.horizontal)
       }
       
       .padding(.horizontal)
       .foregroundColor(.red)
   }

かなりすっきりします。

次に以下のようにボタンの名前が文字になっているのでわかりやすく画像にしたいと思います。

label: {
           VStack{
               Text("Add")
               Text("Card")
           }

SF Symbolsを使います。

追加"add"には

Image(systemName: "plus.circle")

削除"remove"には

Image(systemName: "minus.circle")

を使います。

emojicountを大きくしていくと最後にエラーが出ます。それを出ないように"if"分で文字数(emojis.count)を条件に振り分けす。

if emojicount < emojis.count{
   emojicount += 1
}
 var add:some View{
       Button(action: {
           if emojicount < emojis.count{
               emojicount += 1
           }
       }, label: {
           VStack{
               Image(systemName: "plus.circle")
           }
       })
   }

そして emojicount が小さすぎても エラーとなるので条件をつけます(emojicount は1以上)。

if emojicount > 1{
  emojicount -= 1
}
    var remove:some View{
       Button(action: {
           if emojicount > 1{
           emojicount -= 1
           }
       }, label: {
           VStack{
               Image(systemName: "minus.circle")
           }
       })
   }

実行するとエラーの出ないことを確認できます。

この記事が気に入ったらサポートをしてみませんか?