我希望你們都做得很好。我對這個社區很陌生,我希望我們可以互相幫助成長。
我目前正在使用 swiftUI 構建一個 MacOS 應用程式,并且我有這個膠囊形狀,里面有一個水影片。水影片只是使用可影片資料和路徑創建的水平移動的波浪。我的問題是,我在螢屏上還有兩個按鈕,一個播放按鈕和一個停止按鈕。他們應該分別開始用水填充膠囊并停止這樣做,他們這樣做了,但他們應該用影片來做到這一點,但事實并非如此。
以下是我的代碼以獲取更多詳細資訊。提前致謝。
GeometryReader { geometry in
VStack {
Spacer()
BreathingWave(progress: $progressValue, phase: phase)
.fill(Color(#colorLiteral(red: 0.14848575, green: 0.6356075406, blue: 0.5744615197, alpha: 1)))
.clipShape(Capsule())
.border(Color.gray, width: 3)
.frame(width: geometry.size.width / 12)
.onAppear {
withAnimation(.linear(duration: 1).repeatForever(autoreverses: false)) {
self.phase = .pi * 2
}
}
HStack {
Spacer()
Image(systemName: "play.circle.fill")
.resizable()
.renderingMode(.template)
.frame(width: 50, height: 50)
.foregroundColor(Color(#colorLiteral(red: 0.14848575, green: 0.6356075406, blue: 0.5744615197, alpha: 1)))
.scaleEffect(scalePlay ? 1.25 : 1)
.onHover(perform: { scalPlay in
withAnimation(.linear(duration: 0.1)) {
scalePlay = scalPlay
}
})
.onTapGesture {
withAnimation(
.easeInOut(duration: duration)
.repeatForever(autoreverses: true)) {
if(progressValue < 1) {
progressValue = 0.1
}
else {
progressValue = progressValue
}
}
}
Spacer()
Image(systemName: "stop.circle.fill")
.resizable()
.renderingMode(.template)
.frame(width: 50, height: 50)
.foregroundColor(Color(#colorLiteral(red: 0.14848575, green: 0.6356075406, blue: 0.5744615197, alpha: 1)))
.scaleEffect(scaleStop ? 1.25 : 1)
.onHover(perform: { scalStop in
withAnimation(.linear(duration: 0.1)) {
scaleStop = scalStop
}
})
.onTapGesture {
withAnimation(.linear) {
progressValue = 0.0
}
}
Spacer()
}
.padding(.bottom, 50)
}
}
這是 BreathingWave 的代碼
struct BreathingWave: Shape {
@Binding var progress: Float
var applitude: CGFloat = 10
var waveLength: CGFloat = 20
var phase: CGFloat
var animatableData: CGFloat {
get { phase }
set { phase = newValue }
}
func path(in rect: CGRect) -> Path {
var path = Path()
let width = rect.width
let height = rect.height
let minWidth = width / 2
let progressHeight = height * (1 - CGFloat(progress))
path.move(to: CGPoint(x: 0, y: progressHeight))
for x in stride(from: 0, to: width 5, by: 5) {
let relativeX = x / waveLength
let normalizedLength = (x - minWidth) / minWidth
let y = progressHeight sin(phase relativeX) * applitude * normalizedLength
path.addLine(to: CGPoint(x: x, y: y))
}
path.addLine(to: CGPoint(x: width, y: progressHeight))
path.addLine(to: CGPoint(x: width, y: height))
path.addLine(to: CGPoint(x: 0, y: height))
path.addLine(to: CGPoint(x: 0, y: progressHeight))
return path
}
}
uj5u.com熱心網友回復:
您遇到的問題只是您從未告訴過BreathingWave如何制作影片以取得進展。當您真的希望它在二維中設定影片時,您可以設定一維影片。修復很簡單:用于AnimatablePair將變數提供給animatableData.
struct BreathingWave: Shape {
var applitude: CGFloat = 10
var waveLength: CGFloat = 20
// progress is no longer a Binding. Using @Binding never did anything
// as you were not changing the value to be used in the parent view.
var progress: Float
var phase: CGFloat
var animatableData: AnimatablePair<Float, CGFloat> { // <- AnimatablePair here
get { AnimatablePair(progress, phase) } // <- the getter returns the pair
set { progress = newValue.first // <- the setter sets each individually from
phase = newValue.second // the pair.
}
}
func path(in rect: CGRect) -> Path {
...
}
}
最后,你現在這樣稱呼它:
BreathingWave(progress: progressValue, phase: phase)
最后一件事。請在未來提供一個最小可重現示例 (MRE) 。有很多代碼不需要除錯它,我必須實作結構頭來運行它。盡可能多地剝離,但給我們一些可以復制、粘貼和運行的東西。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/459932.html
