最近得空做了一個小的新聞類APP,基本上都是照著News Digest的模子刻出來的,之所以這個為參考,是因為覺得News Digest這個APP做得真的很酷炫!
猛戳這里獲取整個項目源代碼
項目前端主要由swift編寫,本地數(shù)據(jù)用CoreData,后端由Node.js編寫,后臺數(shù)據(jù)庫用MongoDB。
News Digest(雅虎新聞)模仿秀第二彈
News Digest(雅虎新聞)模仿秀第三彈
News Digest(雅虎新聞)模仿秀第四彈
先上幾張效果圖讓大家看一下:




今天先講首頁部分的實現(xiàn)吧
-
UITableView
整個首頁其實就是一個UITableView,有三種類型的Cell
三個Cell
MainTopTableViewCell是頂部這個Cell
MainTableViewCell是中間的Cell
MainBottomTableViewCell是底部那個Cell(顯示已閱那個)
剩下兩個cell.xib是MainBottomTableViewCell里面的,因為里面有一個UICollectionView. -
MainTopTableViewCell
首頁
時間是固定在Cell上面,最外層那個Button是固定在ViewController上面的,其實就是底層一張圖片,圖片上面再放一個圖片(也就是那個梯形)
現(xiàn)在說說下拉放大圖片并且文字不隨著圖片下拉的效果
//MARK: - UIScrollViewDelegate
func scrollViewDidScroll(scrollView: UIScrollView) {
let offset_y = scrollView.contentOffset.y;
// contentOffset.y < 0
guard let cell = self.mainTV.cellForRowAtIndexPath(NSIndexPath.init(forRow: 0, inSection: 0)) as? MainTopTableViewCell else {
// MainTopTableViewCell 已經(jīng)不在visiableCells數(shù)組
let distance = self.topCellHeight - self.markFirstCellHeight
if offset_y > distance {
if self.lastOffset > offset_y {
self.menuButton.hidden = false
}
else{
self.menuButton.hidden = true
}
}
else {
self.menuButton.hidden = false
}
self.lastOffset = offset_y
return
}
if offset_y < 0 {
// BackgroundImage
var imageRect = cell.backgroundImage.frame
imageRect.origin.y = offset_y
imageRect.size.height = self.topCellHeight - offset_y
cell.backgroundImage.frame = imageRect
// Date And Time
var dateRect = cell.currentDate.frame
var timeRect = cell.currentTime.frame
dateRect.origin.y = offset_y + 12
timeRect.origin.y = offset_y + 49
cell.currentDate.frame = dateRect
cell.currentTime.frame = timeRect
}
else {
// 恢復(fù)到原始狀態(tài)
cell.backgroundImage.frame = CGRectMake(0, 0, WIDTH, self.topCellHeight)
cell.currentDate.frame = CGRectMake(12, 12, 110, 29)
cell.currentTime.frame = CGRectMake(12, 49, 110, 21)
// Mark Height
self.markFirstCellHeight = cell.heightConstraint.constant
}
// 是否隱藏菜單按鈕
let distance = self.topCellHeight - self.markFirstCellHeight
if offset_y > distance {
if self.lastOffset > offset_y {
self.menuButton.hidden = false
}
else{
self.menuButton.hidden = true
}
}
else {
self.menuButton.hidden = false
}
self.lastOffset = offset_y
}
這里guard條件先判斷MainTopCell在不在當(dāng)前屏幕內(nèi),不在的話,直接判斷需要不需要隱藏右上角按鈕即可
如果在的話,offset_y<0的時候,也就是在最頂部下拉的時候,計算下拉數(shù)值,然后重新賦值給頂部時間,也就是把控件的origin.y 改成下拉了多少,就能保持頂部時間不動。圖片放大的話,也只是修改圖片origin.y,因為圖片的模式設(shè)成了AspectFill,所以當(dāng)origin.y改變的時候,圖片也會相應(yīng)放大
- MainBottomTableViewCell
這里其實就是一個UICollectionView,通過CircleLayout重新排列UICollectionView的出現(xiàn)位置就好
override func prepareLayout() {
super.prepareLayout()
// Assign
self.size = self.collectionView!.frame.size
self.cellCount = CGFloat(self.collectionView!.numberOfItemsInSection(0))
self.center = CGPointMake(self.size.width/2.0, self.size.height/2.0)
self.radius = min(self.size.width/2.0, self.size.height)/2.0
}
首先prepareLayout初始化一些參數(shù),比如說UICollectionViewCell距離圓心的半徑,Cell數(shù)量等等
詳情請參考這里UICollectionViewLayout之CircleLayout
與上面這個例子有點不同的是,在這里我們定義了
override func layoutAttributesForSupplementaryViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
let attributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: elementKind, withIndexPath: indexPath)
attributes.size = CGSizeMake(108, 80)
attributes.center = self.center
return attributes
}
這個就是顯示在BottomCell中間的已閱字樣,之前我是選擇用DecorationView的,類的名字都已經(jīng)叫DecorationCollectionReusableView了,但是發(fā)現(xiàn)裝飾視圖重用的時候不會刷新,于是就改用了SupplementaryView
每次重用BottomCell,都會調(diào)用下面方法,刷新已閱數(shù)量
func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
let view = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "Supplementary", forIndexPath: indexPath) as! DecorationCollectionReusableView
self.number = 0
for model in self.newsArray {
if model.isRead?.intValue == 1 {
self.number += 1
}
}
view.readLabel.text = "\(self.number)/\(self.newsArray.count)"
return view
}
上一張效果圖:


