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
- swift之异步加载图片的tableview
- tableview 图片异步加载
- iOS tableView的图片缓存异步加载
- ios-UI常见问题之TableView异步加载图片错乱显示
- iOS---tableview加载图片的时候的优化之lazy(懒加载)模式and异步加载模式
- iOS---tableview加载图片的时候的优化之lazy(懒加载)模式and异步加载模式
- IOS(swift)-scrollView(tableView) ·图片加载逻辑的优化
- IOS从网络上异步加载一系列的图片并显示在tableview上的例子
- Swift 网络请求, 图片加载, tableView, collectionView, webView(八)
- 图片的异步加载
- 异步的图片加载
- 图片的异步加载
- 图片的异步加载
- 图片的异步加载
- 图片的异步加载
- TableView异步加载
- 摘译:MHLazyTableImages异步加载图片到TableView(LazyTableImages升级版)
- iOS开发笔记--异步加载图片在TableView中的应用
- 20140820 【第七届湖南省省赛】 RMQ with Shifts
- 循环小数
- Eclipse安装JD-Eclipse反编译插件
- Android学习——ActivityManager与Proxy模式的运用
- CFNetwork的错误代码参考
- swift之异步加载图片的tableview
- Jobdu 题目1448:Legal or Not
- java零碎知识点
- AFNetworking 与 UIKit+AFNetworking 详解
- Maven学习——修改Maven的本地仓库路径
- windows下安装PHP与nginx和fastcgi
- jQuery EasyUI ComboGrid 集成分页、按键示例
- jsp向action提交list对象
- php去除多维数组里的相关元素__array_filter不太好使_自己的解决办法