【问题标题】:Stop activity indicator after load UITableView加载 UITableView 后停止活动指示器
【发布时间】:2016-04-19 09:01:34
【问题描述】:

如何在按下刷新按钮并在 UITableview JSON 中完成内容加载后自动停止活动指示器

我已经有了开始旋转和按钮的代码

这里是完整代码

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    var json_data_url = "http://www.howtotechworld.com/json_table_view_images%20(1).json"
    var image_base_url = ""
    var isProgressShowing = true;

    var TableData:Array< datastruct > = Array < datastruct >()

    enum ErrorHandler:ErrorType
    {
        case ErrorFetchingResults
    }


    struct datastruct
    {
        var imageurl:String?
        var description:String?
        var image:UIImage? = nil

        init(add: NSDictionary)
        {
            imageurl = add["url"] as? String
            description = add["description"] as? String
        }
    }

    @IBOutlet var tableview: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        tableview.dataSource = self
        tableview.delegate = self

        get_data_from_url(json_data_url)
    }

    override func viewWillAppear(animated: Bool) {
        let barButtonItem = UIBarButtonItem(title: "Refresh", style: .Plain, target: self, action: "refreshTapped");
        self.navigationItem.rightBarButtonItem = barButtonItem;
    }

    func refreshTapped() {
        addProgressIndicator(isProgressShowing);
        get_data_from_url(json_data_url)
    }

    func addProgressIndicator(show : Bool) {
        isProgressShowing = !show;
        if(show) {
            let myActivityIndicator = UIActivityIndicatorView(activityIndicatorStyle:UIActivityIndicatorViewStyle.Gray)
            myActivityIndicator.startAnimating()
            let barButtonItem = UIBarButtonItem(customView: myActivityIndicator)
            self.navigationItem.rightBarButtonItem = barButtonItem
        } else {
            self.navigationItem.rightBarButtonItem = nil;
        }




    }




    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)

        let data = TableData[indexPath.row]


        cell.textLabel?.text = data.description

        if (data.image == nil)
        {
            cell.imageView?.image = UIImage(named:"image.jpg")
            load_image(image_base_url + data.imageurl!, imageview: cell.imageView!, index: indexPath.row)
        }
        else
        {
            cell.imageView?.image = TableData[indexPath.row].image
        }

        return cell

    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return TableData.count
    }







    func get_data_from_url(url:String)
    {


        let url:NSURL = NSURL(string: url)!
        let session = NSURLSession.sharedSession()

        let request = NSMutableURLRequest(URL: url)
        request.HTTPMethod = "GET"
        request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData


        let task = session.dataTaskWithRequest(request) {
            (
            let data, let response, let error) in

            guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
                print("error")
                return
            }

            dispatch_async(dispatch_get_main_queue(), {
                self.extract_json(data!)
                return
            })

        }

        task.resume()

    }


    func extract_json(jsonData:NSData)
    {
        let json: AnyObject?
        do {
            json = try NSJSONSerialization.JSONObjectWithData(jsonData, options: [])
        } catch {
            json = nil
            return
        }

        if let list = json as? NSArray
        {
            for (var i = 0; i < list.count ; i++ )
            {
                if let data_block = list[i] as? NSDictionary
                {

                    TableData.append(datastruct(add: data_block))
                }
            }

            do
            {
                try read()
            }
            catch
            {
            }

            do_table_refresh()

        }


    }




    func do_table_refresh()
    {
        dispatch_async(dispatch_get_main_queue(), {
            self.tableview.reloadData()
            return
        })
    }


    func load_image(urlString:String, imageview:UIImageView, index:NSInteger)
    {

        let url:NSURL = NSURL(string: urlString)!
        let session = NSURLSession.sharedSession()

        let task = session.downloadTaskWithURL(url) {
            (
            let location, let response, let error) in

            guard let _:NSURL = location, let _:NSURLResponse = response where error == nil else {
                print("error")
                return
            }

            let imageData = NSData(contentsOfURL: location!) 

            dispatch_async(dispatch_get_main_queue(), { 


                self.TableData[index].image = UIImage(data: imageData!) 
                self.save(index,image: self.TableData[index].image!) 

                imageview.image = self.TableData[index].image 
                return 
            }) 


        } 

        task.resume() 


    } 




    func read() throws 
    { 

        do 
        { 
            let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate 
            let managedContext = appDelegate.managedObjectContext! 
            let fetchRequest = NSFetchRequest(entityName: "Images") 

            let fetchedResults = try managedContext.executeFetchRequest(fetchRequest) 

            for (var i=0; i < fetchedResults.count; i++) 
            { 
                let single_result = fetchedResults[i] 
                let index = single_result.valueForKey("index") as! NSInteger 
                let img: NSData? = single_result.valueForKey("image") as? NSData 

                TableData[index].image = UIImage(data: img!) 

            } 

        } 
        catch 
        { 
            print("error") 
            throw ErrorHandler.ErrorFetchingResults 
        } 

    } 

    func save(id:Int,image:UIImage) 
    { 
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate 
        let managedContext = appDelegate.managedObjectContext! 

        let entity = NSEntityDescription.entityForName("Images", 
            inManagedObjectContext: managedContext) 
        let options = NSManagedObject(entity: entity!, 
            insertIntoManagedObjectContext:managedContext) 

        let newImageData = UIImageJPEGRepresentation(image,1) 

        options.setValue(id, forKey: "index") 
        options.setValue(newImageData, forKey: "image") 

        do { 
            try managedContext.save() 
        } catch 
        { 
            print("error") 
        } 

    } 


}

【问题讨论】:

  • 你的get_data_from_url(json_data_url)方法怎么样?
  • 无法添加所有代码
  • 在调用 web 服务后停止活动指示器,在 viewdid 加载方法中。编写代码以在 viewdidload 方法中调用 'get_data_from_url(json_data_url)' 方法后停止活动指示器并试试这个。跨度>
  • 为什么不用UIRefreshControl老老实实的实现pull-to-refresh呢?
  • @system21 它就像在 Twitter 中一样工作——当你拉下你的提要时,它开始刷新。下面是一个如何实现的例子:stackoverflow.com/questions/10291537/…

标签: ios swift uitableview


【解决方案1】:

您需要保留对myActivityIndicator 的引用并将其停止在do_table_refresh() 中,如下所示。

func do_table_refresh()
{
    dispatch_async(dispatch_get_main_queue(), {
        self.tableview.reloadData()

         myActivityIndicator.stopAnimating()
         return
        })
    }

编辑:在查看问题中的代码后快速思考了一下。

如果您想使用 addProgressIndicator(isProgressShowing) 隐藏 myActivitIndicator,则必须确保将 isProgressShowing 设置为 FALSE,然后在我上面给出的代码中,将 myActivityIndicator.stopAnimating() 替换为 addProgressIndicator(isProgressShowing) .

您还需要更新 addProgressIndicator 函数并将 myActivityIndicator.stopAnimating() 添加到 else 条件。

【讨论】:

  • 我会更改 self.table... 和 myActivity..... 行的顺序,但这是您应该停止指标的正确方法。
  • @turushan 如果重新加载需要很长时间,可能是糟糕的编程,或者可能只是加载了很多东西,那么基本上指示器会在重新加载完成之前隐藏。为了解决这个问题,我们最好在重新加载表格后停止指标。不过,对于更小/更快的 tableview 重新加载,延迟可以忽略不计。
  • 实际上在你的代码中 stopAnimating() 行并没有等到 reloadData() 结束,因为它不在完成部分,所以在运行时间读取 reloadData() 后 0.00001 秒跳转到下一行,并再次停止动画,而不依赖于 reloadData 是否完成。
  • 我同意。调用reloadData 只调用tableView:numberOfRowsInSection:tableView:heightForRowAtIndexPath: 然后调用返回... tableView:cellForRowAtIndexPath: 仅在实际重绘表时调用。所以我认为我的方式和你的方式,用户基本上无法区分:)两者都是正确的。
  • @turushan 我应该用什么替换 myActivityIndi​​cator 自己不工作
【解决方案2】:

如果我理解你的问题,那么我认为下面就是你想要的。

-(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if([indexPath row] == ((NSIndexPath*)[[tableView indexPathsForVisibleRows] lastObject]).row){
    //end of loading
    //for example [activityIndicator stopAnimating];
}
}

对于 swift 它是这样的

func cellForRowAtIndexPath(_ indexPath: NSIndexPath) -> UITableViewCell?{
if(indexPath.row = tableView.indexPathsForVisibleRows().lastObject().row{
    //end of loading
    //for example [activityIndicator stopAnimating];
}
return yourCell;

}

我对 swift 了解不多,但我想你会知道怎么做。

【讨论】:

    【解决方案3】:

    do_table_refresh()之后添加此代码:addProgressIndicator(!isProgressShowing);

    【讨论】:

    • 这只是保持活动指示器旋转
    • 试着把它放在task.resume()之前get_data_from_url()
    • 这一次当我点击刷新它仍然没有停止
    • 尝试@Shumais Ul Haq 解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多