我只是想知道制作 Ui 设计卡片的组件是什么。因为我在 pinterest 上看到了很多很酷的卡片设计,我想知道如何制作它。比如用 SwiftUI 进行这样的设计需要哪些组件
我已经试过了!我进一步扩展图像是这样的
import SwiftUI
struct RoundedCorners: Shape {
var radius: CGFloat = 25.0
var corners: UIRectCorner = .allCorners
func path(in rect: CGRect) -> Path {
let path = UIBezierPath(
roundedRect: rect,
byRoundingCorners: corners,
cornerRadii: CGSize(width: radius, height: radius)
)
return Path(path.cgPath)
}
}
struct ContentView: View {
var body: some View {
Image("images")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 200, height: 200) // Set your desired image size
.clipShape(RoundedCorners(radius: 50, corners: [.topLeft, .bottomRight]))
.shadow(radius: 5)
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
我已经尝试过这个但不能。如果有人知道如何用标准来制作这个。
可以通过创建路径并向其添加圆弧来构建基本形状。
一种方法是创建自定义
Shape
,就像您最初所做的那样。然而,这样做的话,很难在左上角保留正确的空间来显示标签,当然除非标签的大小是固定的。
如果您想显示一个可以包含不同大小的文本并适应动态字体大小的标签,那么另一种方法是使用
Canvas
。然后,您可以将标签作为“符号”传入画布以供使用。
A
Canvas
接收 GraphicsContext
作为参数,这可以让您测量图像和其他符号的大小。因此,这使得构建一条完全适合标签尺寸的路径成为可能。
绘制曲线的一个简单方法是使用 addArc(tangent1End:tangent2End:radius:transform:)。在这里,您只需传入在绘制带有方角而不是圆角的形状时将使用的点。
我发现无法将点击手势附加到传递到
Canvas
的符号上。因此,对于右下角的圆形按钮,我建议将尺寸传递到画布,以便可以保留正确的空间量。然后将按钮显示为具有对齐方式的覆盖层 .bottomTrailing
。
这里有一个示例来展示它的工作方式:
struct CardWithInsetCorners: View {
let label: String
let image: Image
let roundButtonDiameter: CGFloat
let roundedCornerRadius: CGFloat = 10
let gapToCornerItems: CGFloat = 3
var body: some View {
Canvas { ctx, size in
if let label = ctx.resolveSymbol(id: "label") {
// Draw the label in the top-left corner
let wLabel = label.size.width + gapToCornerItems
let hLabel = label.size.height + gapToCornerItems
ctx.draw(
label,
in: CGRect(origin: .zero, size: label.size)
)
// Build a path with rounded corners
let wButton = roundButtonDiameter + gapToCornerItems
let hButton = roundButtonDiameter + gapToCornerItems
let path = Path { path in
// Begin half-way down the left side
path.move(to: CGPoint(x: 0, y: size.height / 2))
// Rounded-corner bottom-left of label
path.addArc(
tangent1End: CGPoint(x: 0, y: hLabel),
tangent2End: CGPoint(x: wLabel, y: hLabel),
radius: roundedCornerRadius
)
// Rounded-corner bottom-right of label
path.addArc(
tangent1End: CGPoint(x: wLabel, y: hLabel),
tangent2End: CGPoint(x: wLabel, y: 0),
radius: hLabel / 2
)
// Rounded-corner top-right of label
path.addArc(
tangent1End: CGPoint(x: wLabel, y: 0),
tangent2End: CGPoint(x: size.width, y: 0),
radius: roundedCornerRadius
)
// Rounded-corner top-right
path.addArc(
tangent1End: CGPoint(x: size.width, y: 0),
tangent2End: CGPoint(x: size.width, y: size.height - hButton),
radius: roundedCornerRadius
)
// Rounded-corner top-right of rounded button
path.addArc(
tangent1End: CGPoint(x: size.width, y: size.height - hButton),
tangent2End: CGPoint(x: size.width - wButton, y: size.height - hButton),
radius: roundedCornerRadius
)
// Rounded-corner top-left of rounded button
path.addArc(
tangent1End: CGPoint(x: size.width - wButton, y: size.height - hButton),
tangent2End: CGPoint(x: size.width - wButton, y: size.height),
radius: wButton / 2
)
// Rounded-corner bottom-left of rounded button
path.addArc(
tangent1End: CGPoint(x: size.width - wButton, y: size.height),
tangent2End: CGPoint(x: 0, y: size.height),
radius: roundedCornerRadius
)
// Rounded-corner bottom-left
path.addArc(
tangent1End: CGPoint(x: 0, y: size.height),
tangent2End: CGPoint(x: 0, y: size.height / 2),
radius: roundedCornerRadius
)
path.closeSubpath()
}
// Use the path as clip shape for subsequent drawing operations
ctx.clip(to: path)
// Compute the size for the image when scaled to fill
let resolvedImage = ctx.resolve(image)
let wImage = resolvedImage.size.width
let hImage = resolvedImage.size.height
let scalingFactor = max(size.width / wImage, size.height / hImage)
let w = wImage * scalingFactor
let h = hImage * scalingFactor
let xImage = (size.width - w) / 2
let yImage = (size.height - h) / 2
// Show the image
ctx.draw(
resolvedImage,
in: CGRect(origin: CGPoint(x: xImage, y: yImage), size: CGSize(width: w, height: h))
)
}
} symbols: {
Text(label)
.font(.subheadline)
.padding(.horizontal, 20)
.padding(.vertical, 6)
.background {
Capsule()
.fill(Color(.systemGray5))
}
.tag("label")
}
}
}
struct ContentView: View {
let roundButtonDiameter: CGFloat = 44
var body: some View {
CardWithInsetCorners(
label: "Music",
image: Image(.image3),
roundButtonDiameter: roundButtonDiameter
)
.overlay(alignment: .bottomTrailing) {
Image(systemName: "heart")
.resizable()
.scaledToFit()
.padding(12)
.frame(width: roundButtonDiameter, height: roundButtonDiameter)
.background {
Circle()
.fill(Color(.systemGray5))
}
.onTapGesture {
print("+like")
}
}
.frame(height: 350)
.frame(maxHeight: .infinity, alignment: .top)
}
}