スポンサーリンク

[SwiftUI]ランダムに画像を配置する方法

スポンサーリンク

SwiftUIでは見た目の部分を、縦並び、横並び、前後に配置し、ブロックを積み重ねるように簡単に整えられるのが魅力です。

でも、時には決まった場所ではなく、ランダムに画像やテキストなどのViewを配置したいこともありますよね。今回は、決まった場所じゃなく、適当なところに現れてほしいな〜という時に使える解決方法です。

簡単シンプル、使うのはお馴染みのStackとSpacer()ですよ〜。

開発環境バージョン
Xcode13.4.1
macOSMonterey12.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サイズ指定できるから使える小技でした。

タイトルとURLをコピーしました