如何使用 SwiftUI 在我的圆段中插入 UIImages?
How can i insert UIImages in my circle segments with SwiftUI?
我在 SwiftUI 中制作了一个 circle/wheel,有 7 个片段,现在我想在每个片段(在片段的中心)中插入图像(它们在一个数组中),我该怎么做?
代码:
struct WheelShape: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
let pieSections = 7
let lineWidth: CGFloat = 0.0
let smaller = rect.insetBy(dx: lineWidth / 2.0, dy: lineWidth / 2.0)
let radius = smaller.width / 2.0
let segmentAngle = 2.0 / CGFloat(pieSections) * CGFloat(Double.pi)
let imageArray: [UIImage] = [
UIImage(systemName: "house.fill")!,
UIImage(systemName: "paintpalette.fill")!,
UIImage(systemName: "airplane")!,
UIImage(systemName: "cloud.fill")!,
UIImage(systemName: "dollarsign.circle.fill")!,
UIImage(systemName: "book.fill")!,
UIImage(systemName: "bicycle")!
]
// Draw segment dividers
for index in 1...pieSections {
let drawAngle = segmentAngle * CGFloat(index) + (360 / 7 / 2 * π / 180)
let x = radius * cos(drawAngle) + rect.width / 2.0
let y = radius * sin(drawAngle) + rect.height / 2.0
let cgpoint = CGPoint(x: rect.width / 2, y: rect.height / 2)
path.move(to: cgpoint)
let cgPointLine = CGPoint(x: x, y: y)
path.addLine(to: cgPointLine)
}
return path
}
}
这是一种将圆圈放在背景中并将 SF 符号放在叠加层中的方法。
WWDC 2019 的演示文稿展示了一圈带有动画的楔形物。这是来源:
Building Custom Views in SwiftUI
struct ContentView: View {
let symbols = ["house.fill", "paintpalette.fill", "airplane", "cloud.fill", "dollarsign.circle.fill", "book.fill", "bicycle"]
var body: some View {
WheelShape(symbols)
.stroke(
Color(.blue), lineWidth: 3.0)
.background(
Circle().stroke(Color(.blue), lineWidth: 6.0))
.overlay(
annotations.foregroundColor(.purple))
}
var annotations : some View {
ZStack {
let theta = CGFloat(2) * .pi / CGFloat(symbols.count)
GeometryReader { geo in
let center = CGPoint(x: geo.size.width / 2, y: geo.size.height / 2)
let radius = min(geo.size.width / 2, geo.size.height / 2) / 1.5
ForEach(0..<symbols.count, id: \.self) { index in
let offset = theta * CGFloat(index) + theta / 2
// place SF Symbol, offset to center, then the radius
Image(systemName: symbols[index])
.offset(x: center.x, y: center.y)
.offset(x: radius * cos(offset), y: radius * sin(offset))
.frame(alignment: .center)
.offset(x: -10, y: -10) // fudge factor to center symbol in wedge
}
}
}
}
struct WheelShape: Shape {
let symbols : [String]
init(_ symbols: [String]) {
self.symbols = symbols
}
func path(in rect: CGRect) -> Path {
// center of the shape we are drawing in
let center = CGPoint(x: rect.size.width / 2, y: rect.size.height / 2)
let radius = min(rect.size.width / 2, rect.size.height / 2)
// each angle offset in radians
let theta = CGFloat(2) * .pi / CGFloat(symbols.count)
var path = Path()
// enumerate the array so index is available
symbols.enumerated().forEach({ (index, symbol) in
let offset = theta * CGFloat(index)
path.move(to: center)
path.addLine(to: CGPoint(x: radius * cos(offset) + center.x, y: radius * sin(offset) + center.y))
})
return path
}
}
}
Symbols centered in wedge
我在 SwiftUI 中制作了一个 circle/wheel,有 7 个片段,现在我想在每个片段(在片段的中心)中插入图像(它们在一个数组中),我该怎么做?
代码:
struct WheelShape: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
let pieSections = 7
let lineWidth: CGFloat = 0.0
let smaller = rect.insetBy(dx: lineWidth / 2.0, dy: lineWidth / 2.0)
let radius = smaller.width / 2.0
let segmentAngle = 2.0 / CGFloat(pieSections) * CGFloat(Double.pi)
let imageArray: [UIImage] = [
UIImage(systemName: "house.fill")!,
UIImage(systemName: "paintpalette.fill")!,
UIImage(systemName: "airplane")!,
UIImage(systemName: "cloud.fill")!,
UIImage(systemName: "dollarsign.circle.fill")!,
UIImage(systemName: "book.fill")!,
UIImage(systemName: "bicycle")!
]
// Draw segment dividers
for index in 1...pieSections {
let drawAngle = segmentAngle * CGFloat(index) + (360 / 7 / 2 * π / 180)
let x = radius * cos(drawAngle) + rect.width / 2.0
let y = radius * sin(drawAngle) + rect.height / 2.0
let cgpoint = CGPoint(x: rect.width / 2, y: rect.height / 2)
path.move(to: cgpoint)
let cgPointLine = CGPoint(x: x, y: y)
path.addLine(to: cgPointLine)
}
return path
}
}
这是一种将圆圈放在背景中并将 SF 符号放在叠加层中的方法。
WWDC 2019 的演示文稿展示了一圈带有动画的楔形物。这是来源: Building Custom Views in SwiftUI
struct ContentView: View {
let symbols = ["house.fill", "paintpalette.fill", "airplane", "cloud.fill", "dollarsign.circle.fill", "book.fill", "bicycle"]
var body: some View {
WheelShape(symbols)
.stroke(
Color(.blue), lineWidth: 3.0)
.background(
Circle().stroke(Color(.blue), lineWidth: 6.0))
.overlay(
annotations.foregroundColor(.purple))
}
var annotations : some View {
ZStack {
let theta = CGFloat(2) * .pi / CGFloat(symbols.count)
GeometryReader { geo in
let center = CGPoint(x: geo.size.width / 2, y: geo.size.height / 2)
let radius = min(geo.size.width / 2, geo.size.height / 2) / 1.5
ForEach(0..<symbols.count, id: \.self) { index in
let offset = theta * CGFloat(index) + theta / 2
// place SF Symbol, offset to center, then the radius
Image(systemName: symbols[index])
.offset(x: center.x, y: center.y)
.offset(x: radius * cos(offset), y: radius * sin(offset))
.frame(alignment: .center)
.offset(x: -10, y: -10) // fudge factor to center symbol in wedge
}
}
}
}
struct WheelShape: Shape {
let symbols : [String]
init(_ symbols: [String]) {
self.symbols = symbols
}
func path(in rect: CGRect) -> Path {
// center of the shape we are drawing in
let center = CGPoint(x: rect.size.width / 2, y: rect.size.height / 2)
let radius = min(rect.size.width / 2, rect.size.height / 2)
// each angle offset in radians
let theta = CGFloat(2) * .pi / CGFloat(symbols.count)
var path = Path()
// enumerate the array so index is available
symbols.enumerated().forEach({ (index, symbol) in
let offset = theta * CGFloat(index)
path.move(to: center)
path.addLine(to: CGPoint(x: radius * cos(offset) + center.x, y: radius * sin(offset) + center.y))
})
return path
}
}
}
Symbols centered in wedge