Skip to content

Instantly share code, notes, and snippets.

@HonmaMasaru
Created February 17, 2024 01:28
Show Gist options
  • Save HonmaMasaru/e6329a9f1e8c6709975926f637168ba5 to your computer and use it in GitHub Desktop.
Save HonmaMasaru/e6329a9f1e8c6709975926f637168ba5 to your computer and use it in GitHub Desktop.
ボタンを円形に展開する。Swift Playground用。
import SwiftUI
import PlaygroundSupport
/// ボタン
struct RoundButton: View {
/// サイズ
static let size: CGSize = .init(width: 32, height: 32)
/// 画像
let image: Image
/// アクション
let action: () -> Void
var body: some View {
ZStack {
Circle()
.fill(Color.white)
.shadow(color: .black.opacity(0.2), radius: 1, x: 2, y: 2)
Button(action: action, label: { image })
.background(.white)
}
.frame(width: RoundButton.size.width, height: RoundButton.size.height)
}
}
/// プレビュー
struct ContentView: View {
/// 画面サイズ
private let size: CGSize = .init(width: 500, height: 500)
/// 半径
private let r: CGFloat = 80
/// ボタンデータ
private let buttons: [(image: String, label: LocalizedStringResource)] = [
("a.circle.fill", "a"), ("b.circle.fill", "b"), ("c.circle.fill", "c"), ("d.circle.fill", "d")
]
/// デフォルトのボタン位置
private var defaultButtonPosition: CGPoint {
.init(x: size.width - RoundButton.size.width / 2 - 16, y: size.height - RoundButton.size.height / 2 - 16)
}
/// 拡張フラグ
@State private var isExpanded: Bool = false
var body: some View {
ZStack {
ForEach(0..<buttons.count, id: \.self) { i in
RoundButton(image: .init(systemName: buttons[i].image)) {
print(buttons[i].label)
withAnimation {
isExpanded.toggle()
}
}
.frame(width: RoundButton.size.width, height: RoundButton.size.height)
.position(defaultButtonPosition)
.offset(isExpanded ? expandPosition(position: i) : .zero)
.opacity(isExpanded ? 1 : 0)
}
RoundButton(image: .init(systemName: isExpanded ? "chevron.up.circle" : "chevron.down.circle")) {
withAnimation {
isExpanded.toggle()
}
}
.frame(width: RoundButton.size.width, height: RoundButton.size.height)
.position(defaultButtonPosition)
}
.frame(width: size.width, height: size.height)
}
/// 拡張時の位置
/// - Parameter position: ボタン位置
/// - Returns: 拡張時の位置
private func expandPosition(position: Int) -> CGSize {
let theta = (2.0 * .pi) / 4.0 / CGFloat(buttons.count - 1) * CGFloat(position)
return .init(width: -r * cos(theta), height: -r * sin(theta))
}
}
PlaygroundPage.current.setLiveView(ContentView())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment