Ios 如何显示活动指示器,直到数据提取并显示在我的采集视图中

Ios 如何显示活动指示器,直到数据提取并显示在我的采集视图中,ios,swift,uiactivityindicatorview,Ios,Swift,Uiactivityindicatorview,我有一个收藏视图。我从API中获取一些数据,并将其显示在我的采集视图中。一切正常。但当我加载屏幕时,首先显示屏幕,仅在延迟5到6秒后,数据才会填充到我的采集视图中。为了解决这个问题,我做了一些调度主线程,以快速获取数据 但有时基于用户手机的数据连接,数据显示会延迟。例如,如果用户的数据连接速度较慢,则在“我的采集”视图中显示数据大约需要30秒(假设) 所以,我需要的是-如何显示活动指示器-直到我的数据显示在我的收集视图中。 我知道如何创建一个虚拟的活动指示器,并显示1到30秒。但我必须动态地这样

我有一个收藏视图。我从API中获取一些数据,并将其显示在我的采集视图中。一切正常。但当我加载屏幕时,首先显示屏幕,仅在延迟5到6秒后,数据才会填充到我的采集视图中。为了解决这个问题,我做了一些
调度主线程
,以快速获取数据

但有时基于用户手机的数据连接,数据显示会延迟。例如,如果用户的数据连接速度较慢,则在“我的采集”视图中显示数据大约需要30秒(假设)

所以,我需要的是-如何显示活动指示器-直到我的数据显示在我的收集视图中。 我知道如何创建一个虚拟的
活动指示器
,并显示1到30秒。但我必须动态地这样做

这意味着,我需要显示活动指示器,直到数据显示在我的集合视图中。它不应取决于用户的数据连接速度

如何做到这一点

这是我的密码:

 var BTdata = [BTData]()
 override func viewDidLoad()
    {
        super.viewDidLoad()

 ListBusinessTypes()

}
// Values from Api for Business Types
    func ListBusinessTypes()
    {
        let token = NSUserDefaults.standardUserDefaults().valueForKey("access_token") as! String

        let headers = ["x-access-token": token]

        let request = NSMutableURLRequest(URL: NSURL(string: “some url“)!,
                                          cachePolicy: .UseProtocolCachePolicy,
                                          timeoutInterval: 10.0)
        request.HTTPMethod = "GET"
        request.allHTTPHeaderFields = headers

        let session = NSURLSession.sharedSession()
        let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
            if (error != nil)
            {
                print(error)

                let ErrorAlert = UIAlertController(title: "Error", message: "Problem with internet connectivity or server, please try after some time", preferredStyle: UIAlertControllerStyle.Alert)

                // add an action (button)
                ErrorAlert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))

                // show the alert
                self.presentViewController(ErrorAlert, animated: true, completion: nil)
            }
            else
            {
                if let json = (try? NSJSONSerialization.JSONObjectWithData(data!, options: [])) as? Dictionary<String,AnyObject>
                {
                    let success = json["success"] as? Int

                    if(success == 1)
                    {

                        if let typeValues = json["data"] as? [NSDictionary]
                        {
                            dispatch_async(dispatch_get_main_queue(),{

                                for item in typeValues
                                {
                                    self.BTdata.append(BTData(json:item))
                                }

                                self.collectionView1!.reloadData()
                            })
                        }
                    }
                    else
                    {
                        let message = json["message"] as? String

                        let ServerAlert = UIAlertController(title: "Error", message: message, preferredStyle: UIAlertControllerStyle.Alert)

                        // add an action (button)
                        ServerAlert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))

                        // show the alert
                        self.presentViewController(ServerAlert, animated: true, completion: nil)
                    }
                }
            }
        })

        dataTask.resume()
    }
var BTdata=[BTdata]()
重写func viewDidLoad()
{
super.viewDidLoad()
ListBusinessTypes()
}
//来自业务类型Api的值
func ListBusinessTypes()
{
让token=NSUserDefaults.standardUserDefaults().valueForKey(“访问令牌”)作为!字符串
let headers=[“x-access-token”:token]
let request=NSMutableURLRequest(URL:NSURL(字符串:“某些URL”)!,
cachePolicy:.UseProtocolCachePolicy,
timeoutInterval:10.0)
request.HTTPMethod=“GET”
request.allHTTPHeaderFields=标题
let session=NSURLSession.sharedSession()
让dataTask=session.dataTaskWithRequest(请求,completionHandler:{(数据,响应,错误)->中的Void
如果(错误!=nil)
{
打印(错误)
让ErrorAlert=UIAlertController(标题:“错误”,消息:“internet连接或服务器出现问题,请稍后再试”,首选样式:UIAlertControllerStyle.Alert)
//添加操作(按钮)
ErrorAlert.addAction(UIAlertAction(标题:“确定”,样式:UIAlertActionStyle.Default,处理程序:nil))
//显示警报
self.presentViewController(ErrorAlert,动画:true,完成:nil)
}
其他的
{
如果让json=(尝试?NSJSONSerialization.JSONObjectWithData(data!,选项:[]))作为字典
{
将success=json[“success”]设为?Int
如果(成功==1)
{
如果让typeValues=json[“数据”]as?[NSDictionary]
{
dispatch\u async(dispatch\u get\u main\u queue(){
对于typeValues中的项
{
self.BTdata.append(BTdata(json:item))
}
self.collectionView1!.reloadData()
})
}
}
其他的
{
让message=json[“message”]作为字符串
让ServerAlert=UIAlertController(标题:“错误”,消息:消息,首选样式:UIAlertControllerStyle.Alert)
//添加操作(按钮)
addAction(UIAlertAction(标题:“确定”,样式:UIAlertActionStyle.Default,处理程序:nil))
//显示警报
self.presentViewController(ServerAlert,动画:true,完成:nil)
}
}
}
})
dataTask.resume()
}

要设置指示器,请创建两种启动和停止指示器的方法。如下所示

首先创建IBOutlet

var activityIndicator:UIActivityIndicatorView = UIActivityIndicatorView()
创建开始方法:

 func startIndicator()
{
    //creating view to background while displaying indicator
    let container: UIView = UIView()
    container.frame = self.view.frame
    container.center = self.view.center
    container.backgroundColor = CONTAINER_VIEW_BACKGROUND_COLOR

    //creating view to display lable and indicator
    let loadingView: UIView = UIView()
    loadingView.frame = CGRectMake(0, 0, 118, 80)
    loadingView.center = self.view.center
    loadingView.backgroundColor =  LOADING_VIEW_BACKGROUND_COLOR
    loadingView.clipsToBounds = true
    loadingView.layer.cornerRadius = 10

    //Preparing activity indicator to load
    self.activityIndicator = UIActivityIndicatorView()
    self.activityIndicator.frame = CGRectMake(40, 12, 40, 40)
    self.activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.WhiteLarge
    loadingView.addSubview(activityIndicator)

    //creating label to display message
    let label = UILabel(frame: CGRectMake(5, 55,120,20))
    label.text = "Loading..."
    label.textColor = UIColor.whiteColor()
    label.bounds = CGRectMake(0, 0, loadingView.frame.size.width / 2, loadingView.frame.size.height / 2)
    label.font = UIFont.systemFontOfSize(12)
    loadingView.addSubview(label)
    container.addSubview(loadingView)
    self.view.addSubview(container)

    self.activityIndicator.startAnimating()
}
创建停止方法:

func stopIndicator()
{
        UIApplication.sharedApplication().endIgnoringInteractionEvents()
        self.activityIndicator.stopAnimating()
        ((self.activityIndicator.superview as UIView!).superview as UIView!).removeFromSuperview()
}
然后调用viewdidload中ListBusinessType方法上方的startIndicator。 然后当您从api获得成功和失败响应时停止它。 这将对您有所帮助。:)


注意:根据应用程序主题更改颜色。

要设置指示器,请创建两种启动和停止指示器的方法。如下所示

首先创建IBOutlet

var activityIndicator:UIActivityIndicatorView = UIActivityIndicatorView()
创建开始方法:

 func startIndicator()
{
    //creating view to background while displaying indicator
    let container: UIView = UIView()
    container.frame = self.view.frame
    container.center = self.view.center
    container.backgroundColor = CONTAINER_VIEW_BACKGROUND_COLOR

    //creating view to display lable and indicator
    let loadingView: UIView = UIView()
    loadingView.frame = CGRectMake(0, 0, 118, 80)
    loadingView.center = self.view.center
    loadingView.backgroundColor =  LOADING_VIEW_BACKGROUND_COLOR
    loadingView.clipsToBounds = true
    loadingView.layer.cornerRadius = 10

    //Preparing activity indicator to load
    self.activityIndicator = UIActivityIndicatorView()
    self.activityIndicator.frame = CGRectMake(40, 12, 40, 40)
    self.activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.WhiteLarge
    loadingView.addSubview(activityIndicator)

    //creating label to display message
    let label = UILabel(frame: CGRectMake(5, 55,120,20))
    label.text = "Loading..."
    label.textColor = UIColor.whiteColor()
    label.bounds = CGRectMake(0, 0, loadingView.frame.size.width / 2, loadingView.frame.size.height / 2)
    label.font = UIFont.systemFontOfSize(12)
    loadingView.addSubview(label)
    container.addSubview(loadingView)
    self.view.addSubview(container)

    self.activityIndicator.startAnimating()
}
创建停止方法:

func stopIndicator()
{
        UIApplication.sharedApplication().endIgnoringInteractionEvents()
        self.activityIndicator.stopAnimating()
        ((self.activityIndicator.superview as UIView!).superview as UIView!).removeFromSuperview()
}
然后调用viewdidload中ListBusinessType方法上方的startIndicator。 然后当您从api获得成功和失败响应时停止它。 这将对您有所帮助。:)


注意:根据你的应用程序主题更改颜色。

我对你的代码做了一些更改,下面就是

将它们用作类变量

var actView: UIView = UIView()
var loadingView: UIView = UIView()
var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
var titleLabel: UILabel = UILabel()
在您的服务调用函数中

showActivity(self.view, myTitle: "Loading...")
let dataTask = session.dataTaskWithRequest(request) {(data, response, error)  in
    dispatch_async(dispatch_get_main_queue(), {
        if response != nil {
            if error != nil {
                print(error)
                removeActivity(self.view)
                let ErrorAlert = UIAlertController(title: "Error", message: "Problem with internet connectivity or server, please try after some time", preferredStyle: UIAlertControllerStyle.Alert)
                // add an action (button)
                ErrorAlert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
                // show the alert
                self.presentViewController(ErrorAlert, animated: true, completion: nil)
            }else {
                if let json = (try? NSJSONSerialization.JSONObjectWithData(data!, options: [])) as? Dictionary<String,AnyObject> {
                    let success = json["success"] as? Int
                    if(success == 1) {
                        if let typeValues = json["data"] as? [NSDictionary] {
                            dispatch_async(dispatch_get_main_queue(),{
                                for item in typeValues {
                                    self.BTdata.append(BTData(json:item))
                                }
                                self.collectionView1!.reloadData()

                                removeActivity(self.view)
                            })
                        } else {
                            removeActivity(self.view)
                        }
                    } else {

                        removeActivity(self.view)

                        let message = json["message"] as? String
                        let ServerAlert = UIAlertController(title: "Error", message: message, preferredStyle: UIAlertControllerStyle.Alert)
                        // add an action (button)
                        ServerAlert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
                        // show the alert
                        self.presentViewController(ServerAlert, animated: true, completion: nil)
                    }
                } else {

                    removeActivity(self.view)
                }
            }
        }
        })

    }

dataTask.resume()
停止设置动画的函数

  func showActivity(myView: UIView, myTitle: String) {
    myView.userInteractionEnabled = false
    myView.window?.userInteractionEnabled = false
    myView.endEditing(true)
    actView.frame = CGRectMake(0, 0, myView.frame.width, myView.frame.height)
    actView.center = myView.center
    actView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.3)

    loadingView.frame = CGRectMake(0, 0, 80, 80)
    loadingView.center = myView.center
    loadingView.backgroundColor = THEME_COLOUR
    loadingView.clipsToBounds = true
    loadingView.layer.cornerRadius = 15

    activityIndicator.frame = CGRectMake(0.0, 0.0, 40.0, 40.0);
    activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.WhiteLarge
    activityIndicator.center = CGPointMake(loadingView.frame.size.width / 2, loadingView.frame.size.height / 2);

    titleLabel.frame = CGRectMake(5, loadingView.frame.height-20, loadingView.frame.width-10, 20)
    titleLabel.textColor = UIColor.whiteColor()
    titleLabel.adjustsFontSizeToFitWidth = true
    titleLabel.textAlignment = NSTextAlignment.Center
    titleLabel.text = myTitle
    titleLabel.font = IH_DELEGATE.BoldAppFontOfSize(10)

    loadingView.addSubview(activityIndicator)
    actView.addSubview(loadingView)
    loadingView.addSubview(titleLabel)
    myView.addSubview(actView)
    activityIndicator.startAnimating()
}
func removeActivity(myView: UIView) {
    myView.userInteractionEnabled = true
    myView.window?.userInteractionEnabled = true
    activityIndicator.stopAnimating()
    actView.removeFromSuperview()
}
编辑 忘了提

let THEME_COLOUR = UIColor (red:0.188, green:0.682, blue:0.886, alpha:1)

我对你的代码做了一些修改,下面就是

将它们用作类变量

var actView: UIView = UIView()
var loadingView: UIView = UIView()
var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
var titleLabel: UILabel = UILabel()
在您的服务调用函数中

showActivity(self.view, myTitle: "Loading...")
let dataTask = session.dataTaskWithRequest(request) {(data, response, error)  in
    dispatch_async(dispatch_get_main_queue(), {
        if response != nil {
            if error != nil {
                print(error)
                removeActivity(self.view)
                let ErrorAlert = UIAlertController(title: "Error", message: "Problem with internet connectivity or server, please try after some time", preferredStyle: UIAlertControllerStyle.Alert)
                // add an action (button)
                ErrorAlert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
                // show the alert
                self.presentViewController(ErrorAlert, animated: true, completion: nil)
            }else {
                if let json = (try? NSJSONSerialization.JSONObjectWithData(data!, options: [])) as? Dictionary<String,AnyObject> {
                    let success = json["success"] as? Int
                    if(success == 1) {
                        if let typeValues = json["data"] as? [NSDictionary] {
                            dispatch_async(dispatch_get_main_queue(),{
                                for item in typeValues {
                                    self.BTdata.append(BTData(json:item))
                                }
                                self.collectionView1!.reloadData()

                                removeActivity(self.view)
                            })
                        } else {
                            removeActivity(self.view)
                        }
                    } else {

                        removeActivity(self.view)

                        let message = json["message"] as? String
                        let ServerAlert = UIAlertController(title: "Error", message: message, preferredStyle: UIAlertControllerStyle.Alert)
                        // add an action (button)
                        ServerAlert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
                        // show the alert
                        self.presentViewController(ServerAlert, animated: true, completion: nil)
                    }
                } else {

                    removeActivity(self.view)
                }
            }
        }
        })

    }

dataTask.resume()
停止设置动画的函数

  func showActivity(myView: UIView, myTitle: String) {
    myView.userInteractionEnabled = false
    myView.window?.userInteractionEnabled = false
    myView.endEditing(true)
    actView.frame = CGRectMake(0, 0, myView.frame.width, myView.frame.height)
    actView.center = myView.center
    actView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.3)

    loadingView.frame = CGRectMake(0, 0, 80, 80)
    loadingView.center = myView.center
    loadingView.backgroundColor = THEME_COLOUR
    loadingView.clipsToBounds = true
    loadingView.layer.cornerRadius = 15

    activityIndicator.frame = CGRectMake(0.0, 0.0, 40.0, 40.0);
    activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.WhiteLarge
    activityIndicator.center = CGPointMake(loadingView.frame.size.width / 2, loadingView.frame.size.height / 2);

    titleLabel.frame = CGRectMake(5, loadingView.frame.height-20, loadingView.frame.width-10, 20)
    titleLabel.textColor = UIColor.whiteColor()
    titleLabel.adjustsFontSizeToFitWidth = true
    titleLabel.textAlignment = NSTextAlignment.Center
    titleLabel.text = myTitle
    titleLabel.font = IH_DELEGATE.BoldAppFontOfSize(10)

    loadingView.addSubview(activityIndicator)
    actView.addSubview(loadingView)
    loadingView.addSubview(titleLabel)
    myView.addSubview(actView)
    activityIndicator.startAnimating()
}
func removeActivity(myView: UIView) {
    myView.userInteractionEnabled = true
    myView.window?.userInteractionEnabled = true
    activityIndicator.stopAnimating()
    actView.removeFromSuperview()
}
编辑 忘了提

let THEME_COLOUR = UIColor (red:0.188, green:0.682, blue:0.886, alpha:1)

谢谢你的解决方案。但是我不知道应该在哪里停止。我的意思是在我的api方法中。所以只有我发布了我的web服务单元方法。你能告诉我应该在代码中的何处停止指示器吗?OK,在打印上方写停止方法(错误),并让success=json[“success”]as?INT你知道了吗?如果你仍然没有得到,那么说吧?非常感谢。我会尝试让你知道。谢谢你的解决方案。但是我不知道应该在哪里停止。我的意思是在我的api方法中。所以只有我发布了我的web服务单元方法。你能告诉我应该在哪里停止代码中的指示器吗?OK,在打印上方写下停止方法(错误)然后让success=json[“success”]作为?你明白了吗?如果你还没有明白,就说出来?非常感谢。我会尽力让你知道的。我需要表演一下