SwiftUIでは見た目の部分を、縦並び、横並び、前後に配置し、ブロックを積み重ねるように簡単に整えられるのが魅力です。
でも、時には決まった場所ではなく、ランダムに画像やテキストなどのViewを配置したいこともありますよね。今回は、決まった場所じゃなく、適当なところに現れてほしいな〜という時に使える解決方法です。
簡単シンプル、使うのはお馴染みのStackとSpacer()ですよ〜。
開発環境 | バージョン |
---|---|
Xcode | 13.4.1 |
macOS | Monterey12.5 |
SwiftUIでImageをランダムに配置するサンプル
画像をランダムに配置した結果
画像はSFSymbolsの中であんまり使う機会がない葉っぱ(leaf.fill)です。
記事を書いてる現在、もうすぐ秋なので落ち葉の絨毯みたいになるかなーと思って散らしてみました。
ということでこんな感じにランダムに配置されるコードです。
SwiftUIで画像をランダム配置するサンプルコード
簡単な仕組みなので先にコードを載せてしまいます。
編集したファイルはContentView.swiftだけです。
//
// ContentView.swift
// RandomSampleApp
//
// Created by yaguchisato on 2022/08/26.
//
import SwiftUI
struct ContentView: View {
var body: some View {
//画像とSpacerのViewをForEachで100枚重ねる
ZStack {
ForEach(0..<100) { i in
//画像の上下にSpacerを置き、片側だけにランダムなframeサイズを指定
VStack {
Spacer()
.frame(height: .random(in: 50..<UIScreen.main.bounds.size.height ))
//画像の左右にSpacerを置き、片側だけにランダムなframeサイズを指定
HStack {
Spacer()
.frame(width: .random(in: 0...UIScreen.main.bounds.size.width))
//葉っぱの画像
Image(systemName: "leaf.fill")
.resizable()
.scaledToFit()
.frame(width: 100, height: 100)
.foregroundColor(.orange)
.shadow(color: .white, radius: 2)
//ランダムな角度で回転もさせる
.rotationEffect(Angle(degrees: .random(in: 0..<360)))
Spacer()
}
Spacer()
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Spacer()ってframeサイズ指定できたんですね!
【解説】Imageの上下左右をSpacer()で囲む
ランダムな位置に表示したい画像をSpacerで上下左右囲み、Spacerの上下、左右のそれぞれ片側だけ(今回は上と左)を.randomなframeサイズで指定します。
以下はわかりやすいように装飾部分を簡素化したコードです。
Imageの左右をスペースで埋め、スペースの片側だけframeサイズをランダムにする
スペース・画像・スペースと横並びになるようにHStackに入れます。
//画像の左右にSpacerを置き、片側だけにランダムなframeサイズを指定
HStack {
Spacer()
.frame(width: .random(in: 0...UIScreen.main.bounds.size.width))
//画像
Image(systemName: "leaf.fill")
Spacer()
}
Imageの上下をスペースで埋め、スペースの片側だけframeサイズをランダムにする
先ほどの左右をスペースで挟まれた画像を、上下もスペースで挟むようにVStackに入れます。
//画像の上下にSpacerを置き、片側だけにランダムなframeサイズを指定
VStack {
Spacer()
.frame(height: .random(in: 0..<UIScreen.main.bounds.size.height ))
HStack {・・・ //スペース・画像・スペース}
Spacer()
}
frameがサイズ指定されていない方のSpacerは、残ったスペースを自動計算して余白を埋めてくれるので、結果Spacerに挟まれた画像がランダムに配置されます。
画面上の一部範囲でランダム表示したい場合など応用も可能
Spacerのサイズは、今回は0から画面幅いっぱいの間で設定しましたが、この範囲を変更すれば画面の一部でランダム配置も可能です。
.randomってとても便利ですよね。
今回のサンプルでは、複数の画像をランダム表示したかったので、ランダムなframeサイズを指定されたSpacerごとForeachで回してます。
それによって、ZStackで重ねた層ごとに画像の位置が変わって表示されています。
ランダムに表示するViewは一つだけでいいんだけど……という場合は、全体サンプルコードのVStack以内(ZStackとForEachを消す)が対象のコードになります。
Spacerを使っているので、間に挟むことができるViewであれば、テキストなど画像以外のViewもこの方法でランダム配置できるかと思います。
以上、Spacerがframeサイズ指定できるから使える小技でした。