मैंने अपनी बड़ी परियोजना का केवल एक छोटा सा हिस्सा निकालने की पूरी कोशिश की जो इस अजीब व्यवहार को प्रदर्शित करता है। इरादा एक यादृच्छिक संख्या को सरणी में जोड़ने और हर 3 सेकंड में प्रदर्शित करने का है। IOS 13 में प्रत्येक नंबर हर 3 सेकंड में बाईं ओर से स्लाइड करता है और सब कुछ उम्मीद के मुताबिक काम करता है। IOS 14 में मैं जो देखता हूं वह यह है कि हर 3 सेकंड में 4 नंबर जोड़े जाते हैं। क्या कोई समझता है कि ऐसा क्यों हो रहा होगा? अग्रिम में धन्यवाद!

import SwiftUI

struct ContentView: View {

    @State private var calledNumbers = CalledNumbers()
    @State private var timer = Timer.publish(every: 3, tolerance: 0.5, on: .main, in: .common).autoconnect()
    @State private var inProgress = false

    var body: some View {
        Button(action: {
            if !self.inProgress {
                self.calledNumbers.startOver()
                print("Start timer")
                self.timer = Timer.publish(every: 3, tolerance: 0.5, on: .main, in: .common).autoconnect()
            }
            else {
                print("Stop timer")
                self.timer.upstream.connect().cancel()
            }
            self.inProgress.toggle()
        })
        {
            if(self.inProgress == false) {
                Text("S T A R T")
                    .font(.system(size: 22))
                    .fontWeight(.heavy)
                    .frame(width: 200, height: 35, alignment: .center)
                    .background(Capsule()
                        .fill(Color.green))
                    .cornerRadius(35)
                    .foregroundColor(.white)
                    .padding(.bottom, 2)
            }
            else {
                Text("S T O P")
                    .font(.system(size: 22))
                    .fontWeight(.heavy)
                    .frame(width: 200, height: 35, alignment: .center)
                    .background(Color.red)
                    .foregroundColor(.white)
                    .cornerRadius(35)
                    .onReceive(self.timer) { _ in
                        self.timer.upstream.connect().cancel()
                        print("CALL NEXT NUMBER")
                        self.calledNumbers.callNextNumber()
                        self.timer = Timer.publish(every: 3, tolerance: 0.5, on: .main, in: .common).autoconnect()
                    }
            }
        }
        ZStack {
            RoundedRectangle(cornerRadius: 35)
                .frame(width: UIScreen.main.bounds.size.width - 19, height: 40, alignment: .center)
                .foregroundColor(.clear)
                .padding(.bottom, 2)
            HStack {
                ForEach(self.calledNumbers.calledNumberList.reversed().filter {self.checkCount(number: $0)}, id: \.self) { number in
                    Text("\(String(number))")
                        .font(.custom("Menlo", size: 20))
                        .fontWeight(.black)
                        .frame(width: 40, height: 40, alignment: .center)
                        .background(Color.red)
                        .clipShape(Circle())
                        .foregroundColor(.white)
                        .transition(AnyTransition.offset(x: (number == self.calledNumbers.calledNumberList.last) ? -250 : 250))
                        .animation(Animation.linear(duration: 1).repeatCount(1))
                }
            }
        }
    }
    
    func checkCount(number: Int) -> Bool {
        let count = self.calledNumbers.calledNumberList.count
        if (count <= 8) {
            return true
        }
        else {
            guard let index = self.calledNumbers.calledNumberList.firstIndex(of: number) else { return false }
            if (count - index > 8) { return false }
            else { return true }
        }
    }
}

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

यह फ़ाइल xcode 12 द्वारा जोड़ी गई थी (मैंने इस प्रोजेक्ट का नाम Test2 रखा है):

import SwiftUI

@main
struct Test2App: App {
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

कॉल किए गए नंबरों के लिए कक्षा

//
//  class.swift
//  Test2
//

import Foundation

class CalledNumbers {
    
    @Published var calledNumberList: [Int]
            
    init() {
        calledNumberList = [Int]()
    }
    
    func callNextNumber() {
        var tempNumber = Int.random(in: 1...75)
        
        while calledNumberList.contains(tempNumber) {
            tempNumber = Int.random(in: 1...75)
        }
        calledNumberList.append(tempNumber)
        print("Number added \(tempNumber)")
        
    }
    
    func startOver() {
        
        calledNumberList.removeAll()
        
    }
}
0
CS0521 28 सितंबर 2020, 00:54

1 उत्तर

सबसे बढ़िया उत्तर

ऐसा लगता है कि यह समस्या .onReceived() के Button के अंदर कोड के साथ संलग्न होने के कारण हुई है। .onReceived() को Button में ले जाना समग्र रूप से समस्या का समाधान करता है।

साथ ही, आप आवश्यकता से अधिक टाइमर हेरफेर कर रहे थे। मैंने .onReceive() से टाइमर को रोकना और फिर से चालू करना हटा दिया है।

calledNumbers एक @ObservableObject होना चाहिए।

struct ContentView: View {

    @ObservedObject var calledNumbers = CalledNumbers()
    @State private var timer = Timer.publish(every: 3, tolerance: 0.5, on: .main, in: .common).autoconnect()
    @State private var inProgress = false

    var body: some View {
        Button(action: {
            if !self.inProgress {
                self.calledNumbers.startOver()
                print("Start timer")
                self.timer = Timer.publish(every: 3, tolerance: 0.5, on: .main, in: .common).autoconnect()
            }
            else {
                print("Stop timer")
                self.timer.upstream.connect().cancel()
            }
            self.inProgress.toggle()
        })
        {
            Text(inProgress ? "STOP" : "START")
                .font(.system(size: 22))
                .fontWeight(.heavy)
                .frame(width: 200, height: 35, alignment: .center)
                .cornerRadius(35)
                .foregroundColor(.white)
                .background(Capsule().fill(inProgress ? Color.red : .green))
                .padding(.bottom, 2)
            }
        }
        .onReceive(self.timer) { _ in
            print("CALL NEXT NUMBER")
            self.calledNumbers.callNextNumber()
        }
        .onAppear {
            // Cancel the initial timer
            self.timer.upstream.connect().cancel()
        }

        ZStack {
            RoundedRectangle(cornerRadius: 35)
                .frame(width: UIScreen.main.bounds.size.width - 19, height: 40, alignment: .center)
                .foregroundColor(.clear)
                .padding(.bottom, 2)
            HStack {
                ForEach(self.calledNumbers.calledNumberList.reversed().filter {self.checkCount(number: $0)}, id: \.self) { number in
                    Text("\(String(number))")
                        .font(.custom("Menlo", size: 20))
                        .fontWeight(.black)
                        .frame(width: 40, height: 40, alignment: .center)
                        .background(Color.red)
                        .clipShape(Circle())
                        .foregroundColor(.white)
                        .transition(AnyTransition.offset(x: (number == self.calledNumbers.calledNumberList.last) ? -250 : 250))
                        .animation(Animation.linear(duration: 1).repeatCount(1))
                }
            }
        }
    }
    
    func checkCount(number: Int) -> Bool {
        let count = self.calledNumbers.calledNumberList.count
        if (count <= 8) {
            return true
        }
        else {
            guard let index = self.calledNumbers.calledNumberList.firstIndex(of: number) else { return false }
            if (count - index > 8) { return false }
            else { return true }
        }
    }
}

साथ ही, आपकी CalledNumbers कक्षा एक ObservableObject होनी चाहिए ताकि Published सही ढंग से काम करे:

import Foundation

class CalledNumbers: ObservableObject {
    
    @Published var calledNumberList: [Int]
            
    init() {
        calledNumberList = [Int]()
    }
    
    func callNextNumber() {
        var tempNumber = Int.random(in: 1...75)
        
        while calledNumberList.contains(tempNumber) {
            tempNumber = Int.random(in: 1...75)
        }
        calledNumberList.append(tempNumber)
        print("Number added \(tempNumber)")
        
    }
    
    func startOver() {
        
        calledNumberList.removeAll()
        
    }
}
1
vacawama 28 सितंबर 2020, 01:56