ios中的tableView类似于android中的listview,要实现tableview主要包括delegate与datasource两部分
为了实现dataSource协议,我们需要做什么?
1.table分为几个section?func numberOfSectionsInTableView(sender: UITableView) -> Int
2.在指定的section中有几行?func tableView(sender: UITableView, numberOfRowsInSection: Int) -> Int
3.给TableView一个UITableViewCell或它的子类
UITableViewDelegate
1.可通过UITableViewDelegate获取被选中行的信息func tableView(sender: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { }
2.可获取detail disclosure被选中的信息func tableView(sender: UITableView, accessoryButtonTappedForRowWithIndexPath: NSIndexPath) { }
如果Model发生变化,如何更新UITableView
可使用func reloadData()方法更新全部数据,也可使用func reloadRowsAtIndexPaths(indexPaths: [NSIndexPath], withRowAnimation: UITableViewRowAnimation)来更新某一行到某一行之间的数据
如果Cell的行高发生了变化,如何使其自动适应
可将行高设置为UITableViewAutomaticDimension.同时设定estimatedRowHeight获取尺寸的大小.也可让delegate计算每一行的高度func tableView(UITableView,{estimated}heightForRowAtIndexPath: NSIndexPath) -> CGFloat
SmashtagDEMO
需要调用twitter api,需要在模拟器中登陆账号,此外原来的twitter工具类是swift1版本的,swift2版本见:TwitterAPI
TweetTableViewController
import UIKit class TweetTableViewController: UITableViewController, UITextFieldDelegate { var tweets = [[Tweet]]() // MARK: – ViewControllerLifecycle var searchText: String? = “#stanford” { didSet { lastSuccesfulRequest = nil //每次搜索值改变了以后,将上次的搜索设为nil.因为本次搜索的内同与上次搜索的内容不同,本次的搜索内容与上次的搜索内容无关,在此搜索时需要重新载入请求 searchTextField.text = searchText tweets.removeAll() //当searchText被重新输入新值时,清空推文,并重载tableView,并刷新 tableView.reloadData() refresh() } } override func viewDidLoad() { super.viewDidLoad() //自动设置tableView的高度 tableView.estimatedRowHeight = tableView.rowHeight tableView.rowHeight = UITableViewAutomaticDimension refresh() } //实现下拉刷新 var lastSuccesfulRequest: TwitterRequest? var nextRequestToAttempt: TwitterRequest? { if lastSuccesfulRequest == nil {//如果上次请求未实现,则在进行一次请求 if searchText != nil { return TwitterRequest(search: searchText! , count: 100) } else { return nil } }else { //如果上次请求已经实现,则载入新的信息 return lastSuccesfulRequest!.requestForNewer } } func refresh() { //调用UIRefreshControl,进行刷新 if refreshControl != nil { refreshControl?.beginRefreshing() } refresh(refreshControl!) } @IBAction func refresh(sender: UIRefreshControl) { if searchText != nil { if let request = nextRequestToAttempt {//向Twitter提交请求 request.fetchTweets { (newTweets) -> Void in //fetchTweets是异步API,多线程API,故下面的UI操作要返回主线程 dispatch_async(dispatch_get_main_queue()) { () -> Void in if newTweets.count > 0 {//如果搜索到了新的推文 self.lastSuccesfulRequest = request self.tweets.insert(newTweets, atIndex: 0)//将新的推文插入到第一个section中 self.tableView.reloadData()//重载tableView sender.endRefreshing()//下拉刷新结束 } } } } } else { sender.endRefreshing() } } //设置搜索栏 @IBOutlet weak var searchTextField: UITextField! { didSet { searchTextField.delegate = self searchTextField.text = searchText } } //点击键盘上的return后进行搜索,并且隐藏键盘 func textFieldShouldReturn(textField: UITextField) -> Bool { if textField == searchTextField { textField.resignFirstResponder() searchText = textField.text } return true } // MARK: – UITableViewDataSource override func numberOfSectionsInTableView(tableView: UITableView) -> Int { return tweets.count } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return tweets[section].count } // 设置Cell的原型 private struct Storyboaed { static let CellReuseIndetifier = “Tweet” } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier(Storyboaed.CellReuseIndetifier, forIndexPath: indexPath) as! TweetTableViewCell // Configure the cell… cell.tweet = tweets[indexPath.section][indexPath.row] return cell } }
TweetTableViewCell
import UIKit class TweetTableViewCell: UITableViewCell { var tweet: Tweet? { didSet { updateUI() } } @IBOutlet weak var tweetProfileImageView: UIImageView! @IBOutlet weak var tweetScreenNameLabel: UILabel! @IBOutlet weak var tweetTextLabel: UILabel! func updateUI() { tweetTextLabel?.attributedText = nil tweetScreenNameLabel?.text = nil tweetProfileImageView?.image = nil if let tweet = self.tweet { tweetTextLabel?.text = tweet.text if tweetTextLabel?.text != nil { for _ in tweet.media { tweetTextLabel.text! += ” 📷” } } tweetScreenNameLabel?.text = “\(tweet.user)” if let profileImageURL = tweet.user.profileImageURL { if let imageData = NSData(contentsOfURL: profileImageURL) { tweetProfileImageView?.image = UIImage(data: imageData) } } } } }
问题
Transport security has blocked a cleartext HTTP
解决方法参见:stackoverflow
源码:smashtag