在API调用Swift时显示活动指示器

7hiiyaii  于 2023-02-07  发布在  Swift
关注(0)|答案(4)|浏览(150)

我想在执行API调用时显示活动指示器。活动指示器应在收到api响应时停止
但是活动指示器在API调用期间不显示我是swift的新手,这是我的代码。

import UIKit

var ARR_states : NSArray = NSArray()
var activityIndicatorView: UIActivityIndicatorView = UIActivityIndicatorView()
var VW_overlay: UIView = UIView()

class VC_search_Course: UIViewController {

@IBOutlet weak var TBL_states :UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    VW_overlay = UIView(frame: UIScreen.main.bounds)
    VW_overlay.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5)

    activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge)
    activityIndicatorView.frame = CGRect(x: 0, y: 0, width: activityIndicatorView.bounds.size.width, height: activityIndicatorView.bounds.size.height)

    activityIndicatorView.center = VW_overlay.center
    VW_overlay.addSubview(activityIndicatorView)
    VW_overlay.center = view.center
    view.addSubview(VW_overlay)

    activityIndicatorView.startAnimating()
    perform(#selector(self.Places_API), with: activityIndicatorView, afterDelay: 0.01)

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}


@IBAction func button_back(sender: UIButton) {
    self.dismiss(animated: false, completion: nil)
}

func Places_API()
{
    let STR_url = String(format: "%@/search_by_location", SERVER_URL)
    let auth_tok = String(format:"%@",UserDefaults.standard.value(forKey:"auth_token") as! CVarArg)
       if let url = NSURL(string:STR_url) {
        let request = NSMutableURLRequest(url: url as URL)
        request.httpMethod = "GET"
        request.addValue("application/json", forHTTPHeaderField: "Accept")
        request.addValue(auth_tok, forHTTPHeaderField: "auth_token")

        let task = URLSession.shared.dataTask(with: request as URLRequest) {
            data, response, error in
            if error != nil {
                print("\(String(describing: error))")
                return
            }

            let temp_dictin: [AnyHashable: Any]? = ((try? JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers)) as? [AnyHashable: Any])

            ARR_states = temp_dictin?["course_locations"] as! NSArray
            NSLog("States response %@", ARR_states)

        }
        task.resume()
    }

    activityIndicatorView.stopAnimating()
    VW_overlay.isHidden = true
}
}

上面的代码没有显示活动指示器,我试着改变视图背景颜色。和活动指示器颜色,但没有用

ffx8fchx

ffx8fchx1#

雨燕3.0

为此我实现了下面两个函数,希望对你有帮助。

func showLoader(view: UIView) -> UIActivityIndicatorView {

        //Customize as per your need
        let spinner = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height:40))
        spinner.backgroundColor = UIColor.black.withAlphaComponent(0.7)
        spinner.layer.cornerRadius = 3.0
        spinner.clipsToBounds = true
        spinner.hidesWhenStopped = true
        spinner.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.white;
        spinner.center = view.center
        view.addSubview(spinner)
        spinner.startAnimating()
        UIApplication.shared.beginIgnoringInteractionEvents()

        return spinner
    }

和,用于隐藏活动指示器

extension UIActivityIndicatorView {  
     func dismissLoader() {
            self.stopAnimating()
            UIApplication.shared.endIgnoringInteractionEvents()
        } 
 }

并且,您使用指示器的UIViewController如下所示。

//Show
    let spinner = showLoader(view: self.view)

    //Hide
    spinner.dismissLoader()
e5nszbig

e5nszbig2#

删除代码

task.resume()
}

// activityIndicatorView.stopAnimating()
// VW_overlay.isHidden = true

并添加到块中,在以下位置调用代码

let task = URLSession.shared.dataTask(with: request as URLRequest) {
        data, response, error in

       // call here 
       activityIndicatorView.stopAnimating()
        VW_overlay.isHidden = true

        if error != nil {
            print("\(String(describing: error))")
            return
        }
       ......
7ivaypg9

7ivaypg93#

在响应处理程序中停止活动指示器。

func Places_API() {
activityIndicatorView.stopAnimating()
//Handle response here
}
vptzau2j

vptzau2j4#

添加加载器类

struct CircleLoader<Content>: View where Content: View {

// MARK:- variables
let circleTrackGradient = LinearGradient(gradient: .init(colors: [Color.circleTrackStart, Color.circleTrackEnd]), startPoint: .leading, endPoint: .bottomLeading)
let circleRoundGradient = LinearGradient(gradient: .init(colors: [Color.circleRoundStart, Color.circleRoundEnd]), startPoint: .topLeading, endPoint: .trailing)

let trackerRotation: Double = 2
let animationDuration: Double = 0.75

@State var isAnimating: Bool = false
@State var circleStart: CGFloat = 0.17
@State var circleEnd: CGFloat = 0.325

@State var rotationDegree: Angle = Angle.degrees(0)

@Binding var isShowing: Bool
var content: () -> Content

// MARK:- views
var body: some View {
    ZStack(alignment: .center) {
        
        self.content()
            .disabled(self.isShowing)
            .blur(radius: self.isShowing ? 3 : 0)
        
        ZStack {
            Circle()
                .stroke(style: StrokeStyle(lineWidth: 15))
                .fill(circleTrackGradient)
            Circle()
                .trim(from: circleStart, to: circleEnd)
                .stroke(style: StrokeStyle(lineWidth: 12, lineCap: .round))
                .fill(circleRoundGradient)
                .rotationEffect(self.rotationDegree)
        }
        .frame(width: 80, height: 80)
        .onAppear() {
            if isShowing {
                self.animateLoader()
                Timer.scheduledTimer(withTimeInterval: self.trackerRotation * self.animationDuration + (self.animationDuration), repeats: true) { (mainTimer) in
                    self.animateLoader()
                }
            }
        }
        .isHidden(!isShowing)
    }
}

// MARK:- functions
func getRotationAngle() -> Angle {
    return .degrees(360 * self.trackerRotation) + .degrees(120)
}

func animateLoader() {
    withAnimation(Animation.spring(response: animationDuration * 2 )) {
        self.rotationDegree = .degrees(-57.5)
    }
    
    Timer.scheduledTimer(withTimeInterval: animationDuration, repeats: false) { _ in
        withAnimation(Animation.easeInOut(duration: self.trackerRotation * self.animationDuration)) {
            self.rotationDegree += self.getRotationAngle()
        }
    }
    
    Timer.scheduledTimer(withTimeInterval: animationDuration * 1.25, repeats: false) { _ in
        withAnimation(Animation.easeOut(duration: (self.trackerRotation * self.animationDuration) / 2.25 )) {
            self.circleEnd = 0.925
        }
    }
    
    Timer.scheduledTimer(withTimeInterval: trackerRotation * animationDuration, repeats: false) { _ in
        self.rotationDegree = .degrees(47.5)
        withAnimation(Animation.easeOut(duration: self.animationDuration)) {
            self.circleEnd = 0.325
        }
    }
}
}

struct CircleLoader_Previews: PreviewProvider {
static var previews: some View {
    CircleLoader(isShowing: .constant(true)) {
        NavigationView {
            List(["1", "2", "3", "4", "5"], id: \.self) { row in
                Text(row)
            }.navigationBarTitle(Text("Loader Test"), displayMode: .large)
        }
    }
  }
}

用法:

struct LoginView: View {

@StateObject var viewModel = LoginViewModel()
@State private var loyaltyNumber = ""
@Binding var flowView: StartFlow

var body: some View {
    CircleLoader(isShowing: $viewModel.isLoading) {
        //Your API Calling from ViewModel
        }
    }
}

结果:

相关问题