微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用另一个函数来停止 foreach 循环

如何解决如何使用另一个函数来停止 foreach 循环

我正在使用 foreach 循环调用一个 PHP 页面,该页面发回一个画廊图像的 html。 forEach 循环由函数galleryplayer 触发。图库大小可以是从 1 到 99 张照片的任何大小。

我想使用函数 stopgalPlay 来停止当前迭代中的 foreach 循环。但是,经过一周的尝试解决此问题后,我想不出如何解决

阅读后,一致认为我不应该使用 forEach 循环。如果是这样,我将如何重写 galleryPlayer 函数以使用不同类型的循环和/或合并一些机制来打破循环并执行 stopgalPlay 函数中的代码

我知道打破 foreach 循环的问题已经被回答了一百万次,但我不知道如何将停止播放合并到我的图片库中。

任何帮助将不胜感激。 请注意,我想使用纯 javascript,而没有像 jquery 或其他库这样的库。

//
//  ContentView.swift
//  WaveExample
//
//  Created by Konrad on 28/07/2021.
//  Original tutorial: https://www.hackingwithswift.com/plus/custom-swiftui-components/creating-a-waveview-to-draw-smooth-waveforms
//

import SwiftUI

/**
 Creates wave shape object
 - Parameter strength: How tall the wave should be
 - Parameter frequency: How densly the wave should be packed
 - returns: Shape
 */
struct Wave: Shape {
    // Basic wave characteristics
    var strength: Double    // Height
    var frequency: Double   // Number of hills
    var phase: Double       // Offsets the wave,can be used to animate the view

    // required to define that animation relates to moving the wave from left to right
    var animatableData: Double {
        get { phase }
        set { self.phase = newValue }
    }

    // Path drawing function
    func path(in rect: CGRect) -> Path {
        let path = UIBezierPath()

        // Basic waveline characteristics
        let width = Double(rect.width)
        let height = Double(rect.height)
        let midWidth = width / 2
        let midHeight = height / 2
        let wavelength = width / frequency
        let oneOverMidWidth = 1 / midWidth

        // Path characteristics
        path.move(to: CGPoint(x: 0,y: midHeight))

        // By determines the nmber of calculations,can be decreased to run faster
        for xPosition in stride(from: 0,through: width,by: 1) {
            let relativeX = xPosition / wavelength          // How far we are from the start point
            let distanceFromMidWidth = xPosition - midWidth // distance from the middle of the space
            let normaldistance = distanceFromMidWidth * oneOverMidWidth // Get values from -1 to 1,normalize
            // let parabola = normaldistance // Small waves in the middle
            let parabola = -(normaldistance * normaldistance) + 1 // Big wave in the middle
            let sine = sin(relativeX + phase)       // Offset based on phase
            let yPosition = parabola * strength * sine + midHeight     // Moving this halfway
            path.addLine(to: CGPoint(x: xPosition,y: yPosition))
        }

        return Path(path.cgPath)
    }
}

struct Line: Shape {
    func path(in rect: CGRect) -> Path {

        // Positioning
        let midHeight = rect.height / 2

        let path = UIBezierPath()
        path.move(to: CGPoint(x: 0,y: midHeight))
        path.addLine(to: CGPoint(x: rect.width,y: midHeight))
        return Path(path.cgPath)
    }
}

struct ContentView: View {

    @State private var phase = 0.0                     // Used to animate the wave
    @State private var waveStrength: Double = 10.0     // How tall,change for interesting numbers
    @State private var waveFrequency: Double = 10.0    // How frequent,change for interesting numbers

    @State var isAnimating: Bool = false    // Currently running animation
    @State private var randNum: Int16 = 0   // Random number to keep generating while animating
    @State private var isNumberInteresting: Bool = false // Will take 'true' of the random number has some interesting properties

    // Timer publisher reflecting frequent animation changes
    @State private var timer = Timer.publish(every: 1,on: .main,in: .common).autoconnect()
    // Stop timer
    func stopTimer() {
        self.timer.upstream.connect().cancel()
    }
    // Start timer
    func startTimer() {
        self.timer = Timer.publish(every: 1,in: .common).autoconnect()
    }

    // Check if number is interesting
    func checkNumber(num: Int16) -> Bool {
        var isInteresting: Bool = false
        if num % 2 == 0 {
            isInteresting.toggle()
        }
        return isInteresting
    }

    var body: some View {
        vstack {
            if self.isAnimating {
                vstack {
                    Button("Stop") {
                        self.isAnimating = false
                        stopTimer()
                    }
                    .font(.title)
                    .foregroundColor(Color(.blue))

                    Text("Random number: \(String(randNum)),interesting: \(String(isNumberInteresting))")
                        .onReceive(timer,perform: { _ in
                            randNum = Int16.random(in: 0..<Int16.max)
                            isNumberInteresting = checkNumber(num: randNum)
                        })
                }
            } else {
                Button("Start") {
                    self.isAnimating = true
                    startTimer()
                }
                .font(.title)
                .foregroundColor(Color(.red))
            }
            if self.isAnimating {
                // Animation
                ZStack {
                    ForEach(0..<10) { waveIteration in
                        Wave(strength: waveStrength,frequency: waveFrequency,phase: phase)
                            .stroke(Color.blue.opacity(Double(waveIteration) / 3),linewidth: 1.1)
                            .offset(y: CGFloat(waveIteration) * 10)
                    }
                }
                .onReceive(timer) { _ in
                    // withAnimation requires info on how to animate
                    withAnimation(Animation.linear(duration: 1).repeatForever(autoreverses: false)) {
                        self.phase = .pi * 2 // 180 degrees of sine being calculated
                        if isNumberInteresting {
                            waveFrequency = 50.0
                            waveStrength = 50.0
                        } else {
                            waveFrequency = 10.0
                            waveStrength = 10.0
                        }
                    }
                }
                .frame(height: UIScreen.main.bounds.height * 0.8)
            } else {
                // Static line
                ZStack {
                    Line()
                        .stroke(Color.blue)
                }
                .frame(height: UIScreen.main.bounds.height * 0.8)
            }
            Spacer()
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

解决方法

您可以使用 while 循环。虽然此条件为假,但请执行此操作。或者,您可以将 forEach 循环放在函数内部,并在它应该中断时返回。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。