feat: 订阅状态栏初步修改
This commit is contained in:
parent
e74040a444
commit
35e7454695
@ -54,17 +54,19 @@ struct SubscriptionStatusBar: View {
|
|||||||
let status: SubscriptionStatus
|
let status: SubscriptionStatus
|
||||||
let onSubscribeTap: (() -> Void)?
|
let onSubscribeTap: (() -> Void)?
|
||||||
private let height: CGFloat
|
private let height: CGFloat
|
||||||
|
private let backgroundColor: Color?
|
||||||
|
|
||||||
init(status: SubscriptionStatus, height: CGFloat? = nil, onSubscribeTap: (() -> Void)? = nil) {
|
init(status: SubscriptionStatus, height: CGFloat? = nil, backgroundColor: Color? = nil, onSubscribeTap: (() -> Void)? = nil) {
|
||||||
self.status = status
|
self.status = status
|
||||||
self.height = height ?? 155 // 默认高度为155
|
self.height = height ?? 155 // 默认高度为155
|
||||||
|
self.backgroundColor = backgroundColor
|
||||||
self.onSubscribeTap = onSubscribeTap
|
self.onSubscribeTap = onSubscribeTap
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack(alignment: .leading) {
|
ZStack(alignment: .leading) {
|
||||||
// SwiftUI 绘制的背景
|
// SwiftUI 绘制的背景
|
||||||
SubscriptionBackground(status: status)
|
SubscriptionBackground(status: status, customBackground: backgroundColor)
|
||||||
.frame(maxWidth: .infinity, minHeight: 120)
|
.frame(maxWidth: .infinity, minHeight: 120)
|
||||||
.clipped()
|
.clipped()
|
||||||
|
|
||||||
@ -110,30 +112,80 @@ struct SubscriptionStatusBar: View {
|
|||||||
// MARK: - 背景绘制
|
// MARK: - 背景绘制
|
||||||
private struct SubscriptionBackground: View {
|
private struct SubscriptionBackground: View {
|
||||||
let status: SubscriptionStatus
|
let status: SubscriptionStatus
|
||||||
|
let customBackground: Color?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack(alignment: .topTrailing) {
|
ZStack {
|
||||||
RoundedRectangle(cornerRadius: 20)
|
// 背景底板:自定义颜色优先,否则根据状态给出渐变
|
||||||
.fill(background)
|
if let color = customBackground {
|
||||||
.shadow(color: Color.black.opacity(0.06), radius: 10, x: 0, y: 6)
|
RoundedRectangle(cornerRadius: 20)
|
||||||
|
.fill(color)
|
||||||
// 装饰元素(右上角)
|
.shadow(color: Color.black.opacity(0.06), radius: 10, x: 0, y: 6)
|
||||||
if case .pioneer = status {
|
|
||||||
Circle()
|
|
||||||
.fill(Color.black.opacity(0.08))
|
|
||||||
.frame(width: 90, height: 90)
|
|
||||||
.offset(x: 12, y: -12)
|
|
||||||
} else {
|
} else {
|
||||||
Circle()
|
RoundedRectangle(cornerRadius: 20)
|
||||||
.fill(Color.black.opacity(0.04))
|
.fill(defaultBackground)
|
||||||
.frame(width: 70, height: 70)
|
.shadow(color: Color.black.opacity(0.06), radius: 10, x: 0, y: 6)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 左上角斜条纹(装饰)
|
||||||
|
VStack {
|
||||||
|
HStack {
|
||||||
|
ParallelogramRow(
|
||||||
|
count: 6,
|
||||||
|
itemSize: CGSize(width: 16, height: 18),
|
||||||
|
shear: -0.35,
|
||||||
|
cornerRadius: 2,
|
||||||
|
color: .black.opacity(0.85),
|
||||||
|
spacing: 1
|
||||||
|
)
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding(.top, 12)
|
||||||
|
.padding(.leading, 16)
|
||||||
|
|
||||||
|
// 右下角斜条纹(装饰)
|
||||||
|
VStack {
|
||||||
|
Spacer()
|
||||||
|
HStack {
|
||||||
|
Spacer()
|
||||||
|
ParallelogramRow(
|
||||||
|
count: 3,
|
||||||
|
itemSize: CGSize(width: 16, height: 18),
|
||||||
|
shear: -0.35,
|
||||||
|
cornerRadius: 2,
|
||||||
|
color: .black.opacity(0.85),
|
||||||
|
spacing: 1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.bottom, 14)
|
||||||
|
.padding(.trailing, 16)
|
||||||
|
|
||||||
|
// 右上角圆形徽标 + 三角指针(与示例类似)
|
||||||
|
VStack {
|
||||||
|
HStack {
|
||||||
|
Spacer()
|
||||||
|
ZStack {
|
||||||
|
CircleView(diameter: 100, color: .black)
|
||||||
|
TriangleView(
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
direction: .right,
|
||||||
|
color: Color(white: 0.9),
|
||||||
|
rotation: .degrees(157)
|
||||||
|
)
|
||||||
|
}
|
||||||
.offset(x: 12, y: -12)
|
.offset(x: 12, y: -12)
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.clipShape(RoundedRectangle(cornerRadius: 20))
|
.clipShape(RoundedRectangle(cornerRadius: 20))
|
||||||
}
|
}
|
||||||
|
|
||||||
private var background: some ShapeStyle {
|
private var defaultBackground: LinearGradient {
|
||||||
switch status {
|
switch status {
|
||||||
case .free:
|
case .free:
|
||||||
return LinearGradient(colors: [Color.white, Color.white.opacity(0.96)], startPoint: .topLeading, endPoint: .bottomTrailing)
|
return LinearGradient(colors: [Color.white, Color.white.opacity(0.96)], startPoint: .topLeading, endPoint: .bottomTrailing)
|
||||||
@ -149,6 +201,7 @@ private struct SubscriptionBackground: View {
|
|||||||
// Free status preview
|
// Free status preview
|
||||||
SubscriptionStatusBar(
|
SubscriptionStatusBar(
|
||||||
status: .free,
|
status: .free,
|
||||||
|
backgroundColor: Color(white: 0.98),
|
||||||
onSubscribeTap: {
|
onSubscribeTap: {
|
||||||
print("Subscribe tapped")
|
print("Subscribe tapped")
|
||||||
}
|
}
|
||||||
@ -159,7 +212,8 @@ private struct SubscriptionBackground: View {
|
|||||||
SubscriptionStatusBar(
|
SubscriptionStatusBar(
|
||||||
status: .pioneer(
|
status: .pioneer(
|
||||||
expiryDate: Calendar.current.date(byAdding: .month, value: 6, to: Date()) ?? Date()
|
expiryDate: Calendar.current.date(byAdding: .month, value: 6, to: Date()) ?? Date()
|
||||||
)
|
),
|
||||||
|
backgroundColor: Color.orange.opacity(0.9)
|
||||||
)
|
)
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user