Created
February 17, 2024 01:28
-
-
Save HonmaMasaru/e6329a9f1e8c6709975926f637168ba5 to your computer and use it in GitHub Desktop.
ボタンを円形に展開する。Swift Playground用。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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