typedef enum : NSUInteger { XTThemeItemTypeAll = 1, XTThemeItemTypeVideo = 41, XTThemeItemTypeVoice = 31, XTThemeItemTypePicture = 10, XTThemeItemTypeText = 29 } XTThemeItemType;注意:定義枚舉的快捷鍵是:enum 2.4.2 如果是text類型的就不需要計算了 2.4.3 如果圖片實際高度太高,我們就在模型裡面定義一個屬性來記錄是否是大圖 2.4.4 給大圖設置一個固定高度,不需要把大圖全部展示出來了
// middleView:一樣計算方式 // 不是段子的時候,才需要計算中間View的Frame if (item.type != XMGThemeItemTypeText) { CGFloat middleW = textW; CGFloat middleH = middleW / item.width * item.height; if (middleH > XTScreenH) { // 大圖 middleH = 300; item.is_bigPicture = YES; } CGFloat middleX = margin; CGFloat middleY = _cellH; _middleViewFrame = CGRectMake(middleX, middleY, middleW, middleH); _cellH = CGRectGetMaxY(_middleViewFrame) + margin; }2.5 運行發現,如果是大圖,圖片就被壓縮了,很難看,怎麼解決? ImageView默認是圖片填充的,就是把圖片拉伸或壓縮成整個ImageView的大小 設置ImageView的內容模式,不讓它壓縮 UIViewContentModeTop 2.6 設置內容模式,發現雖然圖片不被壓縮,但是圖片不能填充ImageView(兩邊是空的) 怎麼解決? UIViewContentModeTop默認是圖片上面顯示到ImageView的頂部,但是不會進行拉伸或壓縮 我們需要先對圖片進行拉伸或壓縮處理,然後再設置UIViewContentModeTop 就可以了 2.7 怎麼對圖片進行拉伸或壓縮處理? 可以用繪圖,生成一張新的拉伸或壓縮好的圖片 2.8 怎麼繪圖? 2.8.1 開啟圖形上下文 2.8.2 繪制圖片 2.8.3 獲取新的圖片 2.8.4 關閉圖形上下文 2.9 對圖片處理進行性能優化 2.9.1 每次設置圖片,都要進行繪圖,有可能重復繪圖,性能不好,怎麼優化? 把處理好的圖片緩存到磁盤(沙盒)裡面,下次再設置這張圖片時,直接從磁盤取 2.9.2 怎麼對圖片緩存處理? 自己寫方法太麻煩, SDImageCache.h內部有方法緩存圖片,直接調用它的方法來進行緩存
[[SDImageCache sharedImageCache] storeImage:image forKey:item.image0]; 注意:要到入頭文件: #import <SDImageCache.h>2.9.3 怎麼從磁盤中去圖片? 同樣也是調用SDImageCache.h方法來取
UIImage *image = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:item.image0];
注意:key值就是圖片的url
2.10 剛開始加載圖片時,進度條怎麼設置? 2.10.1 需要設置一個功能模塊的時候,我們要先去找有沒有做該功能模塊的框架,有就直接拿來用 2.10.2 沒有的話,就找一個功能差不多的模塊來修改一下 2.10.3 怎麼去查找一個框架?- (void)awakeFromNib { _progressView.progressLabel.textColor = [UIColor whiteColor]; _progressView.progressTintColor = [UIColor whiteColor]; _progressView.roundedCorners = 10; _progressView.progressLabel.text = [NSString stringWithFormat:@"%.1f%%",0.0 * 100]; _progressView.progress = 0; } - (void)setItem:(XMGThemeItem *)item { _item = item; // 設置圖片 UIImage *image = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:item.image0]; if (image) { 如果有圖片直接設置,並把進度設為100% _imageView.image = image; _progressView.progressLabel.text = [NSString stringWithFormat:@"%.1f%%",1.0 * 100]; _progressView.progress = 1; } else { 如果沒有圖片,就先把進度設置為0 ,再去下載圖片 _progressView.progressLabel.text = [NSString stringWithFormat:@"%.1f%%",0.0 * 100]; _progressView.progress = 0; // 下載網絡圖片 [_imageView sd_setImageWithURL:[NSURL URLWithString:item.image0] placeholderImage:nil options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize) { 進度就為已下載的文件大小 / 總文件大小 CGFloat progress = 1.0 * receivedSize / expectedSize; 運行發現,進度有時候為-0,打印發現總文件大小該開始為-0 當為-0 的時候就返回 注意:該block會頻換調用,所以 returen一次沒關系 if (expectedSize < 0) return ; _progressView.progressLabel.text = [NSString stringWithFormat:@"%.1f%%",progress * 100]; _progressView.progress = progress; } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { if (!item.is_bigPicture) return ; // 生成一個新拉伸好圖片 CGFloat w = XMGScreenW - 20; CGFloat h = w / item.width * item.height; // 開啟圖形上下文 UIGraphicsBeginImageContextWithOptions(CGSizeMake(w, h), NO, 0); // 繪圖 [image drawInRect:CGRectMake(0, 0, w, h)]; // 獲取上下文圖片 image = UIGraphicsGetImageFromCurrentImageContext(); // 保存圖片到沙盒 [[SDImageCache sharedImageCache] storeImage:image forKey:item.image0]; // 關閉上下文 UIGraphicsEndImageContext(); _imageView.image = image; }]; } 根據服務器數據,決定gif圖片是否顯示 _gifView.hidden = !item.is_gif; 根據自己判斷保存的屬性,來決定顯示大圖按鈕是否顯示 _seeBigButton.hidden = !item.is_bigPicture; if (item.is_bigPicture) { _imageView.contentMode = UIViewContentModeTop; _imageView.clipsToBounds = YES; } else { _imageView.contentMode = UIViewContentModeScaleToFill; _imageView.clipsToBounds = NO; } }3.videoView樣式 和 voiceView樣式 3.1 由於這兩個模塊基本相同,處理方法也差不多 注意:把搭建好的xib的view拷貝到另一個xib裡面的時候,會把對應的連線也拷過去,一定要先刪除這些連線,再繼續使用 3.2 根據類型,只需要設置中間按鈕的圖片就可以了 3.3 xib搭建界面,並把界面添加到cell裡面 3.4 請求數據 3.5在視圖模型中計算cell子控件的frame和高度 3.6 展示數據 3.6.1 在videoView或voiceView的模型裡設置數據的時候,要對數據進行處理 3.6.2 為什麼要處理? 服務器返回的時間數據是以秒為單位的,需求以 00:00 來顯示 3.6.3 怎麼處理?
NSInteger minute = item.voicetime / 60; NSInteger second = item.voicetime % 60; self.timeLabel.text = [NSString stringWithFormat:@"%02ld:%02ld",minute,second];4 在cell模型屬性的set方法裡面統一設置middleView各個模塊的frame的是否隱藏
// middleView if (vm.item.type == XMGThemeItemTypePicture) { // 圖片 _pictureView.hidden = NO; _videoView.hidden = YES; _voiceView.hidden = YES; _pictureView.item = vm.item; _pictureView.frame = vm.middleViewFrame; } else if (vm.item.type == XMGThemeItemTypeVideo) { // 視頻 _pictureView.hidden = YES; _videoView.hidden = NO; _voiceView.hidden = YES; _videoView.item = vm.item; _videoView.frame = vm.middleViewFrame; } else if (vm.item.type == XMGThemeItemTypeVoice) { // 音頻 _pictureView.hidden = YES; _videoView.hidden = YES; _voiceView.hidden = NO; _voiceView.item = vm.item; _voiceView.frame = vm.middleViewFrame; } else { _voiceView.hidden = YES; _pictureView.hidden = YES; _videoView.hidden = YES; }