最近得空做了一個(gè)小的新聞?lì)怉PP或油,基本上都是照著News Digest的模子刻出來(lái)的族操,之所以這個(gè)為參考锐峭,是因?yàn)橛X(jué)得News Digest這個(gè)APP做得真的很酷炫停忿!
猛戳這里獲取整個(gè)項(xiàng)目源代碼
項(xiàng)目前端主要由swift編寫(xiě)驾讲,本地?cái)?shù)據(jù)用CoreData,后端由Node.js編寫(xiě)席赂,后臺(tái)數(shù)據(jù)庫(kù)用MongoDB吮铭。
News Digest(雅虎新聞)模仿秀第二彈
News Digest(雅虎新聞)模仿秀第三彈
News Digest(雅虎新聞)模仿秀第四彈
先上幾張效果圖讓大家看一下:
今天先講首頁(yè)部分的實(shí)現(xiàn)吧
-
UITableView
整個(gè)首頁(yè)其實(shí)就是一個(gè)UITableView,有三種類(lèi)型的Cell
MainTopTableViewCell是頂部這個(gè)Cell
MainTableViewCell是中間的Cell
MainBottomTableViewCell是底部那個(gè)Cell(顯示已閱那個(gè))
剩下兩個(gè)cell.xib是MainBottomTableViewCell里面的颅停,因?yàn)槔锩嬗幸粋€(gè)UICollectionView. -
MainTopTableViewCell
時(shí)間是固定在Cell上面谓晌,最外層那個(gè)Button是固定在ViewController上面的,其實(shí)就是底層一張圖片癞揉,圖片上面再放一個(gè)圖片(也就是那個(gè)梯形)
現(xiàn)在說(shuō)說(shuō)下拉放大圖片并且文字不隨著圖片下拉的效果
//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í)候毁靶,也就是在最頂部下拉的時(shí)候,計(jì)算下拉數(shù)值逊移,然后重新賦值給頂部時(shí)間预吆,也就是把控件的origin.y 改成下拉了多少,就能保持頂部時(shí)間不動(dòng)胳泉。圖片放大的話拐叉,也只是修改圖片origin.y岩遗,因?yàn)閳D片的模式設(shè)成了AspectFill,所以當(dāng)origin.y改變的時(shí)候凤瘦,圖片也會(huì)相應(yīng)放大
- MainBottomTableViewCell
這里其實(shí)就是一個(gè)UICollectionView宿礁,通過(guò)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ù),比如說(shuō)UICollectionViewCell距離圓心的半徑蔬芥,Cell數(shù)量等等
詳情請(qǐng)參考這里UICollectionViewLayout之CircleLayout
與上面這個(gè)例子有點(diǎn)不同的是梆靖,在這里我們定義了
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
}
這個(gè)就是顯示在BottomCell中間的已閱字樣,之前我是選擇用DecorationView的笔诵,類(lèi)的名字都已經(jīng)叫DecorationCollectionReusableView了返吻,但是發(fā)現(xiàn)裝飾視圖重用的時(shí)候不會(huì)刷新,于是就改用了SupplementaryView
每次重用BottomCell乎婿,都會(huì)調(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
}
上一張效果圖: