前言
公司忙著開放發(fā)功能劲绪,一直都都沒時間來更新,廢話不多卡者。今天主要完成的功能
1蒿囤、微博列表的展示
2、下拉刷新和上拉加載更多
3崇决、點擊查看大圖和長按圖片保存的本地相冊材诽。
首先來來張效果圖
1、普通微博界面的UI
我把其分為三部分恒傻,如下圖
1.1脸侥、布局分析
個人信息和微博內(nèi)容為一部分(偷懶沒有自定義view)
圖片展示用CollectView來展示
底部三個按鈕則是用xib拖得的View
布局的話用AutoLayout的第三方SnapKit來進行布局的。
這里就不貼代碼了碌冶。
1.2不等高Cell問題的解決
由于不同的微博內(nèi)容,導致cell的高度不同涝缝,因此需要定義一個方法來獲取cell的高度扑庞。
// MARK:計算cell的高度
func getCellHeight(status:YJStatus) -> CGFloat {
self.status = status
layoutIfNeeded()
return CGRectGetMaxY(bottomToolBar.frame);
}
該方法在cell的返回高度的地方調(diào)用譬重,
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let status = statusArry[indexPath.row]
let height = calCell.getCellHeight(status)
print("計算高度")
return height
}
注意:這里的calCell我是懶加載一個專門用來計算cell高度的cell,懶加載的目的是不要重復創(chuàng)建cell罐氨。因為使用下面方法獲取cell計算的高度是有問題的臀规。所以暫時這樣計算高度。
let cell = tableView.dequeueReusableCellWithIdentifier(reuseID)
2栅隐、數(shù)據(jù)的處理
微博官網(wǎng)文檔的數(shù)據(jù)結(jié)構(gòu)如下(截圖不完整
)
從上圖中我們中我們可以看出返回的包含微博對象的數(shù)組塔嬉,微博對象中又包含了User對象。因此我們需要新建兩個對象租悄,將返回的數(shù)據(jù)包裝到兩個對象中谨究,方法使用。
微博對象
class YJStatus: NSObject
用戶對象
class YJUser: NSObject
重寫init方法將字典轉(zhuǎn)為對象
init(dict: [String:AnyObject]) {
super.init()
setValuesForKeysWithDictionary(dict)
}
這里重寫setValueForKey是為叫user轉(zhuǎn)為對象
override func setValue(value: AnyObject?, forKey key: String) {
if key == "user" {
user = YJUser(dict: value as![String:AnyObject])
return
}
super.setValue(value, forKey: key)
}
因為我創(chuàng)建的對象YJStatus沒包含數(shù)據(jù)中所有的key值泣棋,所有需要重寫下面的方法胶哲,防止程序崩潰,注意不需要實現(xiàn)
//重寫該方法是為不崩潰
override func setValue(value: AnyObject?, forUndefinedKey key: String) {
}
有了數(shù)據(jù)后潭辈,剩下就是把數(shù)據(jù)賦值給cell鸯屿,然后更新UI。以前OC中我一般會重寫model的set方法把敢,在該方法中去更新UI寄摆,swift中我的寫法如下,在didSet中賦值修赞,更新UI婶恼,其他和OC中一樣。
//微博模型
var status:YJStatus?{
didSet {
//在這里賦值
sourceLabel.text = status?.source
contentLabel.text = status?.text
crateTimeLabel.text = status?.created_at
userIconImageView.sd_setImageWithURL(status?.user!.iconURL)
nickNameLabel.text = status?.user?.name
//給縮略圖片賦值
pictureView.imageURLS = status!.thumbURLs
// 賦值給大圖
pictureView.largeURLs = status!.largeURLs
//圖片賦值完后計算圖片大小榔组,更新約束
let size = pictureView.calPictureSize()
print(size)
self.pictureHeighCons?.constraint.updateOffset(size.height)
self.pictureWidthCons?.constraint.updateOffset(size.width)
}
}
這里另外講下微博時間的處理熙尉,因為返回的時間并不是我們想要的格式,我們需要對其處理搓扯,在給時間賦值的didSet方法中進行處理检痰,處理如下
//微博的創(chuàng)建時間
var created_at: String? {
didSet {
//在這里處理時間
//先把時間處理為NSDate
let formatter = NSDateFormatter()
//設置時間的格式
formatter.dateFormat = "EEE MMM d HH:mm:ss Z yyyy"
// 設置時間的區(qū)域
formatter.locale = NSLocale(localeIdentifier: "en")
// 轉(zhuǎn)化為NSDate
let cratedDate = formatter.dateFromString(created_at!)
if let realDate = cratedDate {
//在這里與當前時間比較
//獲取當前日歷
let currentCalendar = NSCalendar.currentCalendar()
if currentCalendar.isDateInToday(realDate) {
//如果在今天之內(nèi)
//計算當前時間和系統(tǒng)時間之差
let interval = Int(NSDate().timeIntervalSinceDate(realDate))
if interval<60 {
created_at = "剛剛"
}
if interval<60*60 {
created_at = "\(interval/60)分鐘前"
}
created_at = "\(interval/60/60)小時前"
}
// 2.判斷是否是昨天
var formatterStr = "HH:mm"
if currentCalendar.isDateInYesterday(realDate) {
formatterStr = "昨天:" + formatterStr
}
else {
//處理一年以內(nèi)
formatterStr = "MM-dd " + formatterStr
//獲取年份
let comps = currentCalendar.components(NSCalendarUnit.Year, fromDate: realDate, toDate: NSDate(), options: NSCalendarOptions(rawValue: 0))
if comps.year >= 1 {
formatterStr = "yyyy-" + formatterStr
}
}
//設置格式化
formatter.dateFormat = formatterStr
created_at = formatter.stringFromDate(realDate)
}
}
}
3、點擊查看大圖的實現(xiàn)
分析:點擊圖片的present一個控制器用來展示大圖锨推,和起對象處于哪一張铅歼,所以點擊的時候需要把大圖的數(shù)組和圖片對應的索引傳遞給首頁的控制。由于View的層級超過了三層换可,我們就不用閉包了椎椰,采用通知的形式。在collectionVIew的點擊事件中發(fā)送通知沾鳄,實現(xiàn)如下:
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
print("我是圖片我被點擊拉")
//在這里發(fā)送通知,info中包含大圖數(shù)組慨飘,和被點擊圖片所在的索引
let info:[String:AnyObject] = [YJLargeURLSkey:largeURLs!,YJIndexKey:indexPath]
NSNotificationCenter.defaultCenter().postNotificationName(YJShowPhotoBrowerNotification, object: nil, userInfo: info)
}
在主控制器注冊通知
// 注冊顯示圖片瀏覽器的通知
NSNotificationCenter.defaultCenter().addObserverForName(YJShowPhotoBrowerNotification, object: nil, queue: nil) { (notice) in
if let info = notice.userInfo {
//通知處理
let photoBrowserVC = YJPhotoBrowseViewController()
photoBrowserVC.sourceImageURLs = info[YJLargeURLSkey] as?[NSURL]
photoBrowserVC.clickIndex = (info[YJIndexKey] as! NSIndexPath).row
self.presentViewController(photoBrowserVC, animated: true, completion: nil)
}
}
注意記得移除通知
//MARK: 移除通知
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
YJPhotoBrowseViewController的實現(xiàn),也是collectinVIew來實現(xiàn)。
定義兩個變量瓤的,一個是圖片數(shù)組休弃,還有就是記錄被點擊圖片的索引
// 圖片數(shù)組
var sourceImageURLs:[NSURL]?{
didSet {
collectView.contentSize = CGSizeMake(CGFloat(sourceImageURLs!.count)*UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height)
}
}
// 點擊圖片的所在索引
var clickIndex:Int? {
didSet {
topLabel.text = "\(clickIndex! + 1)/\(sourceImageURLs!.count)"
let offSetX = (CGFloat(clickIndex!)*UIScreen.mainScreen().bounds.size.width)
print(offSetX)
collectView.contentOffset = CGPointMake(offSetX, 0)
}
}
在圖片的didSet中設置collectionVIew的contensize,在索引didSet中設置contenOffset。
大圖的展示和圖片比較大的顯示進度的圖片處理
var photoURL:NSURL?{
didSet {
// 重置起狀態(tài)
reset()
// 下載圖片
SDWebImageManager.sharedManager().downloadWithURL(photoURL, options: SDWebImageOptions.HighPriority, progress:{ (totalSize, receiveSize) in
SVProgressHUD.showProgress(Float(receiveSize)/Float(totalSize))
if totalSize == receiveSize {
SVProgressHUD.dismiss()
}
}) { (originImage, _, _, _) in
if originImage == nil {
return
}
let originWidth = originImage.size.width
let originHeight = originImage.size.height
let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
let realImageHeight = (originWidth/originHeight)*screenWidth
if realImageHeight<screenHeight {
self.photeImageView.frame = CGRectMake(0, (screenHeight - realImageHeight)*0.5, screenWidth , realImageHeight)
}else {
self.photeImageView.frame = CGRectMake(0, 0, screenWidth, originHeight)
self.backScrollView.contentSize = CGSizeMake(screenWidth, realImageHeight)
}
self.photeImageView.image = originImage
}
}
}
點擊圖片dimiss和長按保存的實現(xiàn)圈膏,給圖片添加分別添加一個tap手勢和長按手勢塔猾,然后通過閉包傳遞事件給YJPhotoBrowseViewController
首先定義兩個閉包
//圖片單擊一閉包
var imageClick:(()->())?
//圖片長按閉包,傳遞需要保存的圖片參數(shù)
var imageLongPress:((saveImage:UIImage)->())?
給圖片添加tap和長按手勢
//圖片添加一個點擊事件
let tap = UITapGestureRecognizer.init(target: self, action: "tapClick")
photeImageView.userInteractionEnabled = true
photeImageView.addGestureRecognizer(tap)
//給圖片添加一個長按手勢
let longPressGesture = UILongPressGestureRecognizer.init(target: self, action: "longPressAction:")
photeImageView.addGestureRecognizer(longPressGesture)
事件方法
//MARK:點擊事件
func tapClick() {
imageClick?()
}
//MARK:長按點擊事件
func longPressAction(longPressGeture:UILongPressGestureRecognizer){
let clickImageView = longPressGeture.view as! UIImageView
if longPressGeture.state == .Ended {
//長按收拾結(jié)束哦
print("長按保存圖片可以嗎")
imageLongPress?(saveImage:clickImageView.image!)
}
}
在控制返回cell進行事件處理
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectView.dequeueReusableCellWithReuseIdentifier(YJPhotoBrowseViewReuseID, forIndexPath: indexPath) as! YJPhotoBrowserCell
cell.backgroundColor = UIColor.yj_randomColor()
cell.photoURL = sourceImageURLs![indexPath.row]
// 圖片的點擊事件
cell.imageClick = {
//dismiss
self.dismissViewControllerAnimated(true, completion: nil)
}
// 長按保存圖片的點擊事件
cell.imageLongPress = {
(saveImage:UIImage)->() in
self.saveImage = saveImage
//保存圖片到相冊
let alertView = UIAlertView()
alertView.message = "保存圖片到相冊?"
alertView.addButtonWithTitle("取消")
alertView.addButtonWithTitle("保存")
alertView.delegate = self
alertView.show()
}
return cell
}
保存圖片的方法如下
UIImageWriteToSavedPhotosAlbum(saveImage!, self, "image:didFinishSavingWithError:contextInfo:", nil)
保存的結(jié)果OC中會在該方法中回調(diào)稽坤, - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;
坑爹的事沒有swift方法函數(shù)丈甸,我們只能直接將OC方法改成swift中的寫法,處理如下尿褪。
func image(image:(UIImage),didFinishSavingWithError error:(NSError?) ,contextInfo:(AnyObject)){
if error != nil {
SVProgressHUD.showErrorWithStatus("保存失敗", maskType: SVProgressHUDMaskType.Black)
}
else {
SVProgressHUD.showSuccessWithStatus("保存成功", maskType: SVProgressHUDMaskType.Black)
}
}
還有圖片的縮放睦擂,我是利用了UIScorllView的縮放來實現(xiàn)。