見出し画像

SwiftUIでいこう!- スタンフォード大学Lecture 5: Properties Layout @ViewBuilder

この回ではアクセスコントロールの追加、構造体名の変更、計算プロパティ(computed property)でコードをスリムに、あとはGeometryReader でレイアウトを決めていきます。

まずprivate(set)を理解する必要があります。読み取り専用とすることができます。

アクセスコントロールを説明して変更していきます。

typealiasを使ってわかりやすいコードとしています。

ContentViewの名前を変更します。

画像1

リネームする場合は変更したい名前の上で⌘ + クリックで上記編集画面が出てくるので、"Rename"を選択します。

画像2

この画面で名前を変更します。

計算プロパティ を使います。

  private var indexOfTheOneAndOnlyFaceUpCard:Int?{

}

最終的には

    private var indexOfTheOneAndOnlyFaceUpCard:Int?{
       get{cards.indices.filter({cards[$0].isFaceUp}).onAndOnly}

       set{cards.indices.forEach({cards[$0].isFaceUp = ($0 == newValue)})}
    }

2ラインとスリムにしています。2ラインにした時のArrayを拡張して使っています。

extension Array{
   var onAndOnly:Element?{
       if self.count == 1{
           return self.first
       }else{
           return nil
       }
   }
}

Layout

レイアウトを整理していきます。

カードを表示させるためのコード"CardView()"を編集します。 "GeometryReader"を使います。

   var body: some View{
       
       GeometryReader(content: { geometry in
           ZStack{
               let shape =  RoundedRectangle(cornerRadius: 20.0)
               if card.isFaceUp{
                   shape
                       .fill()
                       .foregroundColor(.white)
                   shape
                       .stroke(lineWidth: 3)
                   Text(card.content)
                       .font(.system(size: min(geometry.size.width,geometry.size.height)*0.8))
               }else if card.isMatched{
                   shape.opacity(0)
               }
               else{
                   shape
                       .fill()
               }
           }
       })
   }
min(geometry.size.width,geometry.size.height)*0.8))

でサイズを決めます。実行すると以下のようにいい感じな大きさとなっています。(GeometryReaderのcontent: は消しても問題なし)

画像3

別で定義している構造体 Card:Identifiable{}を

var isFaceUp:Bool=true

と変えておくと初期画面で絵文字が見えるようになります。

もう少し整理していきます。fontのパラメータの整理

 private func font(in size:CGSize)->Font{
       Font.system(size: min(size.width,size.height)*DrawingConstants.fontScale)
   }

指定しる数値の整理

private struct DrawingConstants{
       static let cornerRadius:CGFloat = 20
       static let lineWidth:CGFloat = 3
       static let fontScale:CGFloat = 0.8
 }

これを当てはめていきます。

   GeometryReader{ geometry in
           ZStack{
               let shape =  RoundedRectangle(cornerRadius: DrawingConstants.cornerRadius)
               if card.isFaceUp{
                   shape
                       .fill()
                       .foregroundColor(.white)
                   shape
                       .stroke(lineWidth: DrawingConstants.lineWidth)
                   Text(card.content)
                       .font(font(in: geometry.size))
               }else if card.isMatched{
                   shape.opacity(0)
               }
               else{
                   shape
                       .fill()
               }
           }
       }

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