swift之异步加载图片的tableview

来源:互联网 发布:不懂英文能学编程吗 编辑:程序博客网 时间:2024/05/18 20:34

tableview中使用异步线程加载图片,并且实现下拉刷新和上拉翻页功能。

效果如下:



首先,创建工程:



stroyboard中增加tableview

如下:



增加RootTableViewController

代码如下:

////  RootTableViewController.swift//  swiftSimpleNews////  Created by Chi Zhang on 14/6/30.//  Copyright (c) 2014年 Chi. All rights reserved.//import UIKitclass RootTableViewController: UITableViewController, LoadMoreTableFooterViewDelegate {        var dataSource = NSMutableArray()        var thumbQueue = NSOperationQueue()        var pageNo = 1        let PAGESIZE = 10        var loadMoreFooterView: LoadMoreTableFooterView?    var loadingMore: Bool = false    var loadingMoreShowing: Bool = false    //    init(coder aDecoder: NSCoder!) {//        super.init(coder: aDecoder)//        println("init coder")//    }////    init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) {//        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)//        println("init name")//    }        override func viewDidLoad() {        super.viewDidLoad()                // Uncomment the following line to preserve selection between presentations        // self.clearsSelectionOnViewWillAppear = false                // Uncomment the following line to display an Edit button in the navigation bar for this view controller.        // self.navigationItem.rightBarButtonItem = self.editButtonItem                        self.tableView!.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")        let refreshControl = UIRefreshControl()        refreshControl.attributedTitle = NSAttributedString(string: "下拉刷新")        refreshControl.addTarget(self, action: "loadDataSource", forControlEvents: UIControlEvents.ValueChanged)        self.refreshControl = refreshControl        if self.loadMoreFooterView == nil {            println("contentSize \(self.tableView.contentSize.height) framewidth = \(self.tableView.frame.size.width) frameheight= \(self.tableView.frame.size.height)")            self.loadMoreFooterView = LoadMoreTableFooterView(frame: CGRectMake(0, self.tableView.contentSize.height, self.tableView.frame.width, self.tableView.frame.height))            self.loadMoreFooterView!.delegate = self            self.tableView.addSubview(self.loadMoreFooterView!)        }        loadDataSource(true)    }        // LoadMoreTableFooterViewDelegate    func loadMoreTableFooterDidTriggerRefresh(view: LoadMoreTableFooterView) {//        loadMoreTableViewDataSource()        self.pageNo++        loadingMore = true        loadDataSource(false)        println("loadMoreTableFooterDidTriggerRefresh")    }        func loadMoreTableFooterDataSourceIsLoading(view: LoadMoreTableFooterView) -> Bool {        return loadingMore    }    override// UIScrollViewDelegate    func scrollViewDidScroll(scrollView: UIScrollView!)    {        if (loadingMoreShowing) {            loadMoreFooterView!.loadMoreScrollViewDidScroll(scrollView)        }    }        override func scrollViewDidEndDragging(scrollView: UIScrollView!, willDecelerate decelerate: Bool) {                if (loadingMoreShowing) {            loadMoreFooterView!.loadMoreScrollViewDidEndDragging(scrollView)        }    }        override func didReceiveMemoryWarning() {        super.didReceiveMemoryWarning()        // Dispose of any resources that can be recreated.    }        // #pragma mark - Table view data source        override func numberOfSectionsInTableView(tableView: UITableView?) -> Int {        // #warning Potentially incomplete method implementation.        // Return the number of sections.                return 1    }        override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {        // #warning Incomplete method implementation.        // Return the number of rows in the section.                        return dataSource.count            }        func refreshSource() {        pageNo = 1        self.dataSource.removeAllObjects()        loadDataSource(true)    }        func loadDataSource(isRefresh : Bool) {        println("loadDataSource \(isRefresh)")        self.refreshControl.beginRefreshing()        var loadURL = NSURL.URLWithString("http://qingbin.sinaapp.com/api/lists?ntype=%E5%9B%BE%E7%89%87&pageNo=\(pageNo)&pagePer=10&list.htm")        var request = NSURLRequest(URL: loadURL)        var loadDataSourceQueue = NSOperationQueue();                NSURLConnection.sendAsynchronousRequest(request, queue: loadDataSourceQueue, completionHandler: { response, data, error in            if (error != nil) {                println(error)                dispatch_async(dispatch_get_main_queue(), {                    self.refreshControl.endRefreshing()                    })            } else {                let json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary                let newsDataSource = json["item"] as NSArray                //                var currentNewsDataSource = NSMutableArray()                for currentNews : AnyObject in newsDataSource {                    let newsItem = XHNewsItem()                    newsItem.newsTitle = currentNews["title"] as NSString                    newsItem.newsThumb = currentNews["thumb"] as NSString                    newsItem.newsID = currentNews["id"] as NSString                    self.dataSource.addObject(newsItem)                    println( newsItem.newsTitle)                }                if (self.dataSource.count != self.PAGESIZE) {                    self.loadingMoreShowing = false                } else {                    self.loadingMoreShowing = true                }                if (!self.loadingMoreShowing) {                    self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)                }                dispatch_async(dispatch_get_main_queue(), { //                   self.dataSource = currentNewsDataSource                    self.tableView.reloadData()                                        if isRefresh {                        self.refreshControl.endRefreshing()                    } else {                        self.doneLoadingMoreTableViewData()                    }                    })            }            })    }        func doneLoadingMoreTableViewData() {        loadingMore = false        loadMoreFooterView!.loadMoreScrollViewDataSourceDidFinishedLoading(tableView)    }            override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {                        var cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell//        if !cell {//            cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "cell")//        }        if(indexPath.row < dataSource.count) {            var newsItem = dataSource[indexPath.row] as XHNewsItem            cell.textLabel.text = newsItem.newsTitle            cell.imageView.image = UIImage(named :"iconpng")            cell.imageView.contentMode = UIViewContentMode.ScaleAspectFit                                    let request = NSURLRequest(URL :NSURL.URLWithString(newsItem.newsThumb))            NSURLConnection.sendAsynchronousRequest(request, queue: thumbQueue, completionHandler: { response, data, error in                if (error != nil) {                    println(error)                                } else {                    let image = UIImage.init(data :data)                    dispatch_async(dispatch_get_main_queue(), {                        cell.imageView.image = image                    })                }            })                }        return cell    }        override func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {        return 80    }        // #pragma mark - Segues    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {        println("aa")    }        //选择一行    override func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!){        var row=indexPath.row as Int        var data=self.dataSource[row] as XHNewsItem        //入栈                var webView=WebViewController()        webView.detailID=data.newsID        //取导航控制器,添加subView        self.navigationController.pushViewController(webView,animated:true)    }        }

在storyboard中将rootviewcontroller与添加的tableview关联。



XHNewsItem.swfit代码:

////  XHNewsItem.swift//  swiftSimpleNews////  Created by Chi Zhang on 14/6/30.//  Copyright (c) 2014年 Chi. All rights reserved.//import Foundationclass XHNewsItem {    var newsTitle = NSString()    var newsThumb = NSString()    var newsID = NSString()}

WebViewController.siwft代码:

////  WebViewController.swift//  swiftSimpleNews////  Created by Chi Zhang on 14/6/30.//  Copyright (c) 2014年 Chi. All rights reserved.//import UIKitclass WebViewController: UIViewController {        var detailID = NSString()    var detailURL = "http://qingbin.sinaapp.com/api/html/"    var webView : UIWebView?        func loadDataSource() {        var urlString = detailURL + "\(detailID).html"        var url = NSURL.URLWithString(urlString)        var urlRequest = NSURLRequest(URL :NSURL.URLWithString(urlString))        webView!.loadRequest(urlRequest)    }        override func viewDidLoad() {        super.viewDidLoad()                webView=UIWebView()        webView!.frame=self.view.frame        webView!.backgroundColor=UIColor.grayColor()        self.view.addSubview(webView!)                loadDataSource()                        // Do any additional setup after loading the view.    }        override func didReceiveMemoryWarning() {        super.didReceiveMemoryWarning()        // Dispose of any resources that can be recreated.    }            /*    // #pragma mark - Navigation        // In a storyboard-based application, you will often want to do a little preparation before navigation    override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {    // Get the new view controller using [segue destinationViewController].    // Pass the selected object to the new view controller.    }    */    }

LoadMoreFooterView:

////  LoadMoreTableFooterView.swift//  LoadMoreTableFooterView-for-swift////  Created by zhang on 14-6-18.//  Copyright (c) 2014 zhang. All rights reserved.//import Foundationimport UIKitlet TEXT_COLOR: UIColor = UIColor(red: 87.0 / 255.0, green: 108.0 / 255.0, blue: 137.0 / 255.0, alpha: 1.0)enum LoadMoreState{    case LoadMorePulling    case LoadMoreNormal    case LoadMoreLoading}protocol LoadMoreTableFooterViewDelegate {    func loadMoreTableFooterDidTriggerRefresh(view: LoadMoreTableFooterView)    func loadMoreTableFooterDataSourceIsLoading(view: LoadMoreTableFooterView) -> Bool}class LoadMoreTableFooterView: UIView {    var delegate: LoadMoreTableFooterViewDelegate?    var state: LoadMoreState                        = LoadMoreState.LoadMoreNormal    var statusLabel: UILabel                        = UILabel()    var activityView: UIActivityIndicatorView       = UIActivityIndicatorView()        required init(coder aDecoder: NSCoder) {        super.init(coder: aDecoder)    }        override init(frame: CGRect) {        super.init(frame: frame)                self.autoresizingMask = UIViewAutoresizing.FlexibleWidth        self.backgroundColor = UIColor.clearColor()                var label: UILabel = UILabel(frame: CGRectMake(0, 10, self.frame.size.width, 20))        label.autoresizingMask = UIViewAutoresizing.FlexibleWidth        label.font = UIFont.boldSystemFontOfSize(13)        label.textColor = TEXT_COLOR        label.shadowColor = UIColor(white: 0.9, alpha: 1)        label.shadowOffset = CGSizeMake(0, 1)        label.backgroundColor = UIColor.clearColor()        label.textAlignment = NSTextAlignment.Center        self.addSubview(label)        statusLabel = label                var view: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)        view.frame = CGRectMake(55, 20, 20, 20)        self.addSubview(view)        activityView = view                self.hidden = true                setState(LoadMoreState.LoadMoreNormal)    }        func setState(aState: LoadMoreState) {        switch aState {        case LoadMoreState.LoadMorePulling:            statusLabel.text = NSLocalizedString("松开加载更多...", comment: "")            statusLabel.frame = CGRectMake(0, 20, self.frame.size.width, 20)        case LoadMoreState.LoadMoreNormal:            statusLabel.text = NSLocalizedString("上拉加载更多...", comment: "")            statusLabel.frame = CGRectMake(0, 10, self.frame.size.width, 20)            activityView.stopAnimating()        case LoadMoreState.LoadMoreLoading:            statusLabel.text = NSLocalizedString("加载中...", comment: "")            statusLabel.frame = CGRectMake(0, 20, self.frame.size.width, 20)            activityView.startAnimating()        default:            statusLabel.text = ""        }        state = aState    }    func loadMoreScrollViewDidScroll(loadScrollView: UIScrollView) {        if state == LoadMoreState.LoadMoreLoading {            loadScrollView.contentInset = UIEdgeInsetsMake(loadScrollView.contentInset.top, 0, 60, 0)        } else if loadScrollView.dragging {            var loading: Bool = false            if delegate != nil {                loading = delegate!.loadMoreTableFooterDataSourceIsLoading(self)            }                        if (state == LoadMoreState.LoadMoreNormal && loadScrollView.contentOffset.y < (loadScrollView.contentSize.height - (loadScrollView.frame.size.height - 60)) && loadScrollView.contentOffset.y > (loadScrollView.contentSize.height - loadScrollView.frame.size.height) && !loading) {                self.frame = CGRectMake(0, loadScrollView.contentSize.height, self.frame.size.width, self.frame.size.height)                self.hidden = false            } else if (state == LoadMoreState.LoadMoreNormal && loadScrollView.contentOffset.y > (loadScrollView.contentSize.height - (loadScrollView.frame.size.height - 60)) && !loading) {                setState(LoadMoreState.LoadMorePulling)            } else if (state == LoadMoreState.LoadMorePulling && loadScrollView.contentOffset.y < (loadScrollView.contentSize.height - (loadScrollView.frame.size.height - 60)) && loadScrollView.contentOffset.y > (loadScrollView.contentSize.height - loadScrollView.frame.size.height) && !loading) {                setState(LoadMoreState.LoadMoreNormal)            }                        if loadScrollView.contentInset.bottom != 40 {                loadScrollView.contentInset = UIEdgeInsetsMake(loadScrollView.contentInset.top, 0, 40, 0)            }                        var offset: CGFloat = loadScrollView.contentOffset.y - (loadScrollView.contentSize.height - loadScrollView.frame.size.height) - loadScrollView.contentInset.bottom            if offset <= 20 && offset >= 0 {                statusLabel.frame = CGRectMake(0, 10 + offset / 2, self.frame.size.width, 20)            }        }    }        func loadMoreScrollViewDidEndDragging(loadScrollView: UIScrollView) {        var loading = false        if delegate != nil {            loading = delegate!.loadMoreTableFooterDataSourceIsLoading(self)        }        if (loadScrollView.contentOffset.y > (loadScrollView.contentSize.height - (loadScrollView.frame.size.height - 60)) && !loading) {            if delegate != nil {                delegate!.loadMoreTableFooterDidTriggerRefresh(self)            }                        setState(LoadMoreState.LoadMoreLoading)            UIView.beginAnimations(nil, context: nil)            UIView.setAnimationDuration(0.2)            loadScrollView.contentInset = UIEdgeInsetsMake(loadScrollView.contentInset.top, 0, 60, 0)            UIView.commitAnimations()        }    }        func loadMoreScrollViewDataSourceDidFinishedLoading(scrollView: UIScrollView) {        setState(LoadMoreState.LoadMoreNormal)        self.hidden = true    }}

AppDelegate.swift源码:


////  AppDelegate.swift//  swiftSimpleNews////  Created by Chi Zhang on 14/6/30.//  Copyright (c) 2014年 Chi. All rights reserved.//import UIKit@UIApplicationMainclass AppDelegate: UIResponder, UIApplicationDelegate {                                var window: UIWindow?    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)        // Override point for customization after application launch.        self.window!.backgroundColor = UIColor.whiteColor()        self.window!.makeKeyAndVisible()        var root = RootTableViewController()        var navCtrl=UINavigationController(rootViewController:root)        self.window!.rootViewController=navCtrl                return true    }    func applicationWillResignActive(application: UIApplication) {        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.    }    func applicationDidEnterBackground(application: UIApplication) {        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.    }    func applicationWillEnterForeground(application: UIApplication) {        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.    }    func applicationDidBecomeActive(application: UIApplication) {        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.    }    func applicationWillTerminate(application: UIApplication) {        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.    }}




源码:swiftSimpleNews

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 58企业认证失败怎么办 炸鸡店没生意怎么办 你好漂亮重名了怎么办 医保卡被冒用怎么办 理财钱被骗走怎么办 个体户怎么办三方协议 社保户籍错了怎么办 身份证号码变更后驾驶证怎么办 公司倒闭欠工资怎么办 海南买房要社保怎么办? 工商核名不过怎么办 税局要求查账怎么办 完税凭证丢了怎么办 开票开错了怎么办 上海居住证搬家了怎么办 上海无户口 医保怎么办 淘宝账号注销不了怎么办 淘宝账号被覆盖怎么办 淘宝号注册不了怎么办 appleid密码忘了怎么办 蘑菇街用白富美后忘记账号怎么办 不知道宽带账号怎么办 上网用户名忘了怎么办 别人借淘宝号怎么办 不知道ipad密码怎么办 捡的ipad密码怎么办 12306注册名已存在怎么办 忘记网银用户名怎么办 登录用户名忘了怎么办 网银登录错误怎么办 路由器账号忘了怎么办 忘记宽带账号密码怎么办 12123被注册过怎么办 w10不能创建账户怎么办 忘记xp登录密码怎么办 华硕密码忘记了怎么办 电脑账户已停用怎么办 鼠标灯亮不动怎么办 电脑用户名被停用怎么办 电脑截图不清晰怎么办 win10电脑磁盘空间不足怎么办