UItableView结合网络请求,多线程,数据解析,MVC实战
学了这么久的swift都没有做过什么东西,今天就以自己的一个小小的联系,讲一下,怎么使用swift在实战中应用MVC,并且结合后面的高级知识:网络请求,JSON数据解析一起应用到一个项目中来。
好了,废话不多说,我们直接开始吧。
首先看看最终的效果:
是不是很简单,就是个UItableView显示一些简单的数据,如果你真的觉得太简单了,那么请绕道,寻找更深入东西,但或者没有你想的那么简单,这不仅仅是一个tableView,为什么呢?下面我就给大家详细介绍一下。
一:首先,既然说到MVC,我们肯定要先从模型开始,新建一个模型类。
因为我们只是现实一张图片和一行文件,所以模型中非常简单,两行代码:
1 import UIKit 2 3 class DataModel: NSObject 4 { 5 // 文字 6 var title : String = "" 7 8 // 图片 9 var photh : String = "" 10 11 12 }
二:然后创建一个自定义Cell,并且和我们前面一样实现相应的方法,并且在里面实现相应的代码:
1:创建两个控件对应的属性:
1 // 文字 2 var titleLable : UILabel? 3 // 图片 4 var photoImageView : UIImageView?
2:实现init方法,并且在里面调用loadView方法来实现控件的初始化:
1 override init(style: UITableViewCellStyle, reuseIdentifier: String!) 2 { 3 super.init(style: style, reuseIdentifier: reuseIdentifier) 4 5 6 loadView() 7 8 } 9 func loadView() 10 { 11 titleLable = UILabel(frame: CGRectMake(100, 0, 200, 80)) 12 titleLable!.textAlignment = NSTextAlignment.Left 13 titleLable!.numberOfLines = 0 14 self.addSubview(titleLable!) 15 16 photoImageView = UIImageView(frame: CGRectMake(0, 0, 80, 80)) 17 self.addSubview(photoImageView!) 18 19 20 }
3:然后通过模型来加载数据,这里涉及到了网络请求的知识,请多留意蓝色部分代码:
1 func loadData(item:DataModel) 2 { 3 titleLable?.text = item.title 4 5 // 图片转换 6 var thumbQueue = NSOperationQueue() 7 8 var urlString = (item.photh as String) 9 var url = NSURL(string: urlString)! 10 let request = NSURLRequest(URL: url) 11 12 13 /** 14 <#(NSURLResponse!, NSData!, NSError!) -> Void##(NSURLResponse!, NSData!, NSError!) -> Void#> 15 自己命名 16 */ 17 18 //NSURLConnection.sendAsynchronousRequest(request, queue: thumbQueue, completionHandler: ) 19 // <#(NSURLResponse!, NSData!, NSError!) -> Void##(NSURLResponse!, NSData!, NSError!) -> Void#> 20 21 22 23 // NSURLConnection.sendAsynchronousRequest(request, queue: thumbQueue) { (response, data, error) -> Void in 24 // let image = UIImage.init(data :data) 25 // dispatch_async(dispatch_get_main_queue(), { () -> Void in 26 // self.photoImageView!.image = image 27 // }) 28 // 29 // } 30 31 32 NSURLConnection.sendAsynchronousRequest(request, queue: thumbQueue, completionHandler: { response, data, error in 33 if (error != nil) { 34 println(error) 35 36 } else { 37 let image = UIImage.init(data :data) 38 dispatch_async(dispatch_get_main_queue(), { () -> Void in 39 self.photoImageView!.image = image 40 }) 41 42 } 43 }) 44 45 photoImageView?.layer.masksToBounds = true 46 photoImageView?.layer.cornerRadius = 40 47 photoImageView?.image = UIImage(named: item.photh) 48 49 }
3:下面是系统自动实现的方法;
1 required init(coder aDecoder: NSCoder) { 2 fatalError("init(coder:) has not been implemented") 3 } 4 5 6 override func setSelected(selected: Bool, animated: Bool) { 7 super.setSelected(selected, animated: animated) 8 9 // Configure the view for the selected state 10 } 11 12 override func awakeFromNib() { 13 super.awakeFromNib() 14 // Initialization code 15 }
三:然后就是控制器里面了
1:定义相应的属性
- 1:定义一个UItableView
- 2:定义一个可变数组
- 3:定义一个队列(这里涉及到了多线程)
- 4:定义一个网络请求的api链接
- 5:定义一个刷新控件
1 var tableView : UITableView! 2 var dataArray : NSMutableArray = [] 3 var thumbQueue = NSOperationQueue() 4 let hackerNewsApiUrl = "http://qingbin.sinaapp.com/api/lists?ntype=%E5%9B%BE%E7%89%87&pageNo=1&pagePer=10&list.htm" 5 let refreshControl = UIRefreshControl()
2:ViewDidLoad中调用相应的方法
1 override func viewDidLoad() { 2 super.viewDidLoad() 3 // Do any additional setup after loading the view, typically from a nib. 4 5 self.title = "自定义Cell-下拉刷新" 6 7 // 创建TableView 8 createTableView() 9 // 下载数据 10 loadData() 11 12 }
3:创建TableView方法的实现
1 func createTableView() 2 { 3 4 // TableView 5 self.tableView = UITableView(frame: CGRectMake(0, 0, view.frame.size.width, view.frame.size.height)) 6 self.tableView.dataSource = self 7 self.tableView.delegate = self 8 view.addSubview(self.tableView) 9 10 refreshControl.attributedTitle = NSAttributedString(string: "下拉刷新") 11 refreshControl.addTarget(self, action: "loadDataSource", forControlEvents: UIControlEvents.ValueChanged) 12 self.tableView.addSubview(refreshControl) 13 14 15 }
4:加载数据
- 1:通过URL发送请求
- 2:实现一步请求的发送
- 3:使用GCD多多线程实现界面的现实(在主线程中)
- 4:解析加载的json数据(这里可以使用框架SwiftyJSON)
- 5:使用刷新控件实现更好的用户交互效果
1 // MARK: - 加载数据 2 func loadDataSource() 3 { 4 var loadURL = NSURL(string: hackerNewsApiUrl)! 5 var request = NSURLRequest(URL: loadURL) 6 // 线程 7 var loadDataSourceQueue = NSOperationQueue() 8 9 NSURLConnection.sendAsynchronousRequest(request, queue: loadDataSourceQueue, completionHandler: { response, data, error in 10 if (error != nil) 11 { 12 println(error) 13 dispatch_async(dispatch_get_main_queue(), { 14 // self.refreshControl?.endRefreshing() 15 }) 16 } 17 else 18 { 19 let json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary 20 let newsDataSource = json["item"] as! NSArray 21 22 dispatch_async(dispatch_get_main_queue(), 23 24 { 25 self.dataArray = NSMutableArray() 26 // 遍历数组 27 for dict in newsDataSource 28 { 29 var item = DataModel() 30 item.title = dict["title"] as! String 31 item.photh = dict["thumb"] as! String 32 self.dataArray.addObject(item) 33 println(dict["title"]) 34 println(dict) 35 } 36 37 // 刷新时间 38 var sendDate = NSDate() 39 var dateformatter = NSDateFormatter() 40 dateformatter.setLocalizedDateFormatFromTemplate("yyyy年MM月dd日 hh:mm:ss") 41 var loactionTime = String() 42 loactionTime = dateformatter.stringFromDate(sendDate) 43 var title = NSAttributedString(string: "上次刷新时间\(loactionTime)") 44 self.refreshControl.attributedTitle = title 45 // 刷新结束 46 self.refreshControl.endRefreshing() 47 48 // 刷新Cell 49 self.tableView.reloadData() 50 51 }) 52 } 53 }) 54 55 56 } 57 func loadData() 58 { 59 }
5:实现UITableView数据源和代理方法,设置对应的属性来显示数据到界面上:
1 // MARK:- UITableViewDataSource 2 func numberOfSectionsInTableView(tableView: UITableView) -> Int 3 { 4 return 1 5 } 6 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 7 { 8 println(dataArray.count) 9 10 return self.dataArray.count 11 } 12 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 13 { 14 println(dataArray) 15 16 self.tableView.registerClass(ImageCell.self, forCellReuseIdentifier: "cell") 17 var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ImageCell 18 cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator 19 //cell = ImageCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "cell") 20 21 var item = DataModel() 22 item = self.dataArray[indexPath.row] as! DataModel 23 if self.dataArray.count != 0 24 { 25 cell.loadData(item) 26 27 } 28 return cell 29 } 30 func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat 31 { 32 return 80 33 } 34 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 35 { 36 println("row = %d",indexPath.row) 37 var detailVC = DetailViewController() 38 self.navigationController?.pushViewController(detailVC, animated: true) 39 }
当我们点击对应的行,就会跳到对应行的详细界面:
加载这一行中对应的数据
1 var detailID = NSInteger() 2 var detailURL = "http://qingbin.sinaapp.com/api/html/108035.html" 3 var webView = UIWebView() 4 5 override func viewDidLoad() { 6 super.viewDidLoad() 7 8 // Do any additional setup after loading the view. 9 view.backgroundColor = UIColor.whiteColor() 10 self.title = "Detail" 11 12 self.webView.frame = CGRectMake(0, 0, view.frame.size.width, view.frame.size.height) 13 self.webView.scalesPageToFit = true 14 self.webView.delegate = self 15 view.addSubview(self.webView) 16 17 loadData() 18 } 19 20 override func didReceiveMemoryWarning() { 21 super.didReceiveMemoryWarning() 22 // Dispose of any resources that can be recreated. 23 } 24 func loadData() 25 { 26 var url = NSURL(string: self.detailURL) 27 var urlRequest = NSURLRequest(URL: url!) 28 webView.loadRequest(urlRequest) 29 } 30 // MARK: - UIWebViewDelegate 31 // 加载失败 32 func webView(webView: UIWebView, didFailLoadWithError error: NSError) 33 { 34 println(error) 35 } 36 // 加载完成 37 func webViewDidFinishLoad(webView: UIWebView) 38 { 39 println("完成加载\(webView)") 40 } 41 // 开始加载 42 func webViewDidStartLoad(webView: UIWebView) 43 { 44 println("开始加载\(webView)") 45 } 46 func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool 47 { 48 return true 49 }
点击之后显示的节目如下:
时间: 2024-12-22 20:11:10