我有一个专为 320x320 完美设计的 SubView
:)。我想让它缩小到最小 100x100。现在我在每个形状中使用缩放因子。问题:在可重用的 SwiftUI View
中是否有更通用的缩放 Shapes
(尺寸、线条宽度和长度以及矩形宽度和高度)的方法?谢谢。
查看:
代码:
import SwiftUI
private struct SecondsFace: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
let square = CGRect(x: rect.minX, y: rect.minY, width: min(rect.maxX-rect.minX,rect.maxY-rect.minY), height: min(rect.maxX-rect.minX,rect.maxY-rect.minY))
let scaleFactor = CGFloat(square.width / 320.0)
var seconds : Path = Path()
seconds.addLines([CGPoint(x: (320.0/2.0-14.0)*scaleFactor, y: 0),CGPoint(x: (320.0/2-4.0)*scaleFactor, y: 0)])
for i in 0...59 {
path.addPath(seconds, transform: .init(rotationAngle: 2.0 * CGFloat.pi * CGFloat(i)/60.0))
}
return path.offsetBy(dx: (320.0/2.0)*scaleFactor, dy: (320.0/2.0)*scaleFactor)
}
}
private struct HoursFace: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
let square = CGRect(x: rect.minX, y: rect.minY, width: min(rect.maxX-rect.minX,rect.maxY-rect.minY), height: min(rect.maxX-rect.minX,rect.maxY-rect.minY))
let scaleFactor = CGFloat(square.width / 320.0)
var seconds : Path = Path()
seconds.addLines([CGPoint(x: (320.0/2.0-16)*scaleFactor, y: 0),CGPoint(x: (320.0/2.0-2.0)*scaleFactor, y: 0)])
for i in 0...11 {
path.addPath(seconds, transform: .init(rotationAngle: 2.0 * CGFloat.pi * CGFloat(i)/12.0))
}
return path.offsetBy(dx: (320.0/2.0)*scaleFactor, dy: (320.0/2.0)*scaleFactor)
}
}
struct ThreeHoursFace: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
let square = CGRect(x: rect.minX, y: rect.minY, width: min(rect.maxX-rect.minX,rect.maxY-rect.minY), height: min(rect.maxX-rect.minX,rect.maxY-rect.minY))
let scaleFactor = CGFloat(square.width / 320.0)
let threehours : Path = Path(CGRect(x: (320.0/2.0-20.0)*scaleFactor, y: -2.0*scaleFactor, width: 20.0*scaleFactor, height: 4.0*scaleFactor))
for i in 0...3 {
path.addPath(threehours, transform: .init(rotationAngle: 2.0 * CGFloat.pi * CGFloat(i)/4.0))
}
return path.offsetBy(dx: (320.0/2.0)*scaleFactor, dy: (320.0/2.0)*scaleFactor)
}
}
struct SubView: View {
@Binding var color : ColorValue
var body: some View {
ZStack {
SecondsFace()
.stroke(Color.green, style: StrokeStyle(lineWidth: 1, lineCap: .square, lineJoin: .bevel))
HoursFace()
.stroke(Color.red, style: StrokeStyle(lineWidth: 3, lineCap: .square, lineJoin: .bevel))
ThreeHoursFace()
.fill(Color.blue)
}
.aspectRatio(1, contentMode: .fit)
.clipped(antialiased: true)
.background(Color(red: 0.9, green: 0.9, blue: 0.9, opacity: 1.0))
}
}
struct SubViewPreview: PreviewProvider {
@State static var currentColor : ColorValue = ColorValue(color: UIColor.red)
static var previews: some View {
SubView(color: $currentColor)
}
}
重用缩放 View :
(线宽缩放仍然存在一个小问题......)
代码:
import Foundation
import SwiftUI
struct MainView: View {
@State var color = ColorValue(color: UIColor.red)
var body: some View {
VStack {
HStack(spacing: 10) {
SubView(color: $color)
}
.padding(10)
HStack(spacing: 10) {
SubView(color: $color)
SubView(color: $color)
}
.padding(10)
HStack(spacing: 10) {
SubView(color: $color)
SubView(color: $color)
SubView(color: $color)
}
.padding(10)
}
}
}
struct ShapeView_Previews: PreviewProvider {
static var previews: some View {
MainView()
}
}
最佳答案
我现在使用applying(CGAffineTransform(a:, b: , c: , d:, tx: , ty: ))
关于结果path
在Shape
.
代码:
import SwiftUI
private struct SecondsFace: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
let seconds : Path = Path(CGRect(x: (320.0/2.0-14.0), y: -1.0, width: 10.0, height: 2.0))
for i in 0...59 {
path.addPath(seconds, transform: .init(rotationAngle: 2.0 * CGFloat.pi * CGFloat(i)/60.0))
}
let scaleFactor = CGFloat(min(rect.maxX-rect.minX,rect.maxY-rect.minY) / 320.0)
return path.applying(CGAffineTransform(a: scaleFactor, b: 0.0, c: 0.0, d: scaleFactor, tx: (320.0/2.0)*scaleFactor, ty: (320.0/2.0)*scaleFactor))
}
}
private struct HoursFace: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
let seconds : Path = Path(CGRect(x: (320.0/2.0-16.0), y: -2.0, width: 14.0, height: 4.0))
for i in 0...11 {
path.addPath(seconds, transform: .init(rotationAngle: 2.0 * CGFloat.pi * CGFloat(i)/12.0))
}
let scaleFactor = CGFloat(min(rect.maxX-rect.minX,rect.maxY-rect.minY) / 320.0)
return path.applying(CGAffineTransform(a: scaleFactor, b: 0.0, c: 0.0, d: scaleFactor, tx: (320.0/2.0)*scaleFactor, ty: (320.0/2.0)*scaleFactor))
}
}
struct ThreeHoursFace: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
let threehours : Path = Path(CGRect(x: (320.0/2.0-24.0), y: -4.0, width: 24.0, height: 8.0))
for i in 0...3 {
path.addPath(threehours, transform: .init(rotationAngle: 2.0 * CGFloat.pi * CGFloat(i)/4.0))
}
let scaleFactor = CGFloat(min(rect.maxX-rect.minX,rect.maxY-rect.minY) / 320.0)
return path.applying(CGAffineTransform(a: scaleFactor, b: 0.0, c: 0.0, d: scaleFactor, tx: (320.0/2.0)*scaleFactor, ty: (320.0/2.0)*scaleFactor))
}
}
struct SubView: View {
@Binding var color : ColorValue
var body: some View {
ZStack {
SecondsFace()
.fill(Color.green)
HoursFace()
.fill(Color.red)
ThreeHoursFace()
.fill(Color.blue)
}
.aspectRatio(1, contentMode: .fit)
.clipped(antialiased: true)
.background(Color(red: 0.9, green: 0.9, blue: 0.9, opacity: 1.0))
}
}
struct SubViewPreview: PreviewProvider {
@State static var currentColor : ColorValue = ColorValue(color: UIColor.red)
static var previews: some View {
SubView(color: $currentColor)
}
}
看:
关于SwiftUI:缩放 View 中的形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61883546/