用Swift实现的高仿今日头条App源代码免费下载 开源项目

[转载]
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
查看查看862 回复回复11 收藏收藏1 分享淘帖 转播转播 分享分享 微信
查看: 862|回复: 11
收起左侧

[转载] 用Swift实现的高仿今日头条App源代码免费下载 开源项目

[复制链接]
swifter 发表于 2016-8-22 18:44:57 | 显示全部楼层 |阅读模式
快来登录
获取优质的苹果资讯内容
收藏热门的iOS等技术干货
拷贝下载Swift Demo源代码
订阅梳理好了的知识点专辑


0、说明

首先声明,今日头条是我经常用的 app 之一,模仿今日头条也是因为感兴趣,代码仅用于学习交流。

项目中有的地方代码写的不是很简洁,毕竟自己能力有限,对 Swift 使用不是很熟练,还请各位朋友不喜勿喷。下面有项目的完整源码,喜欢的朋友可以下载下来,如果您感觉我写的代码对您有所帮助,还请在 github 给个 star,非常感谢您的支持!~

下载地址:

游客,如果您要查看本帖隐藏内容请回复


用Swift实现的高仿今日头条App源代码免费下载 开源项目 1

用Swift实现的高仿今日头条App源代码免费下载 开源项目 - 敏捷大拇指 - 用Swift实现的高仿今日头条App源代码免费下载 开源项目 1





1、环境设置

  • 项目环境
    • Xcode 7.3.1(低于这个版本会报错)
    • Swift 2.2
    • iOS 8.0 +
  • 使用cocoaPods管理第三方库,如果电脑没有安装 cocoapods,请先安装 cocoapods。安装方式可参考:最新版 CocoaPods 的安装流程
  • 项目中使用到的第三方库
    • SnapKit: 布局
    • Kingfisher: 缓存图片
    • SVProgressHUD:提示框
    • FDFullscreenPopGesture:侧滑
    • Alamofire :网络请求
    • SwiftyJSON:解析 json
    • MJRefresh: 上拉刷新和下拉刷新






2、实现的功能

1. 获取今日头条的接口

2. 完成首页的布局和数据的显示

3. 实现首页顶部导航栏滚动

4. 新闻详情界面简单实现

5. 点击屏蔽按钮,弹出屏蔽视图(坐标有一些问题)

6. 完成视频界面顶部导航栏滚动

7. 完成视频界面布局和数据获取

8. 用户界面简单实现

9. 完成关注界面布局和数据的获取

10. 完成关注界面,添加关注功能

11. 完成搜索功能

12. 完成个人界面的布局

13. 完成设置界面的布局

14. 完成离线下载界面布局

15. 活动界面简单实现

16. 登录界面的简单实现

17. 启动界面的简单实现




3、数据请求

今日头条的接口文件请看:

游客,如果您要查看本帖隐藏内容请回复


需要提前安装 postman,然后把该文件导入到 postman 进行查看,可以打开谷歌浏览器,找到扩展程序,添加新的扩展,搜索 postman或者直接去这个链接下载:

游客,如果您要查看本帖隐藏内容请回复


下载完成后,直接拖入到谷歌浏览器的扩展程序界面即可。




4、首页

游客,如果您要查看本帖隐藏内容请回复


用Swift实现的高仿今日头条App源代码免费下载 开源项目 2

用Swift实现的高仿今日头条App源代码免费下载 开源项目 - 敏捷大拇指 - 用Swift实现的高仿今日头条App源代码免费下载 开源项目 2




4.1、首页的状态栏

首先,首页的状态栏的颜色是白色,所以调用了下面的方法:

[Swift] 纯文本查看 复制代码
override func preferredStatusBarStyle()->UIStatusBarStyle 
{    
  return.LightContent
}


但是,经过测试,上面的代码不起作用,对于 YMMineViewController.swift 上面的代码是起作用的。

唯一的区别是就是在 YMMineViewController.swift 中隐藏了导航条。所以经过查阅资料,得到下面的结论:

1.不管是调用了系统的 UINavigationController 还是使用自己继承自 UINavigationController,如果 navigationBar 没有被隐藏的话,那么导航控制器的 rootController 以及它 push 的控制器的 preferredStatusBarStyle() 方法都不会被调用。

2.如果在当前控制器手动设置了 navagationBar 的 barStyle 为 .Black 或者 .Default 或者使用下面的代码手动设置:

[Swift] 纯文本查看 复制代码
// 方式1
navigationController?.setNavigationBarHidden(true,animated:false)
// 方式2
navigationController?.navigationBarHidden = true


那么 preferredStatusBarStyle() 就会被正常调用了。

还有一点关于隐藏导航栏的注意点请看:

游客,如果您要查看本帖隐藏内容请回复




4.2、关于导航栏的 titleView

在首页首页顶部标题的时候,直接设置 titleView 的宽度为屏幕的宽,但是两边总是会留出 10 的间距,这个时候需要重写父类的 setFrame 方法,在 OC 里面可以使用下面的方法:

[Objective-C] 纯文本查看 复制代码
- (void)setFrame:(CGRect)frame{      
    CGRect newFrame = CGRectMake(0,0,SCREENW,44);    
    [super setFrame:frame];  
}


但是在 Swift 中不能这样写,要使用下面的方式:

[Swift] 纯文本查看 复制代码
/// 重写 
frameoverride var frame: CGRect 
{    
    didSet {        
        let newFrame = CGRectMake(0, 0, SCREENW, 44)        
        super.frame = newFrame    
    }
}


这样设置,运行程序,发现 titleView 在屏幕两边不在留有间距。



4.3、子控制器

YMHomeTopicController.swift 作为 YMHomeViewController.swift 的子控制器,显示新闻数据。

游客,如果您要查看本帖隐藏内容请回复


该类注册了四种 cell,分别表示中间三张图片,右边一张图片,中间一张大图,中间一张视频大图,没有图片的情况。

以下是四种情况:

用Swift实现的高仿今日头条App源代码免费下载 开源项目 3

用Swift实现的高仿今日头条App源代码免费下载 开源项目 - 敏捷大拇指 - 用Swift实现的高仿今日头条App源代码免费下载 开源项目 3


用Swift实现的高仿今日头条App源代码免费下载 开源项目 4

用Swift实现的高仿今日头条App源代码免费下载 开源项目 - 敏捷大拇指 - 用Swift实现的高仿今日头条App源代码免费下载 开源项目 4


用Swift实现的高仿今日头条App源代码免费下载 开源项目 5

用Swift实现的高仿今日头条App源代码免费下载 开源项目 - 敏捷大拇指 - 用Swift实现的高仿今日头条App源代码免费下载 开源项目 5


用Swift实现的高仿今日头条App源代码免费下载 开源项目 6

用Swift实现的高仿今日头条App源代码免费下载 开源项目 - 敏捷大拇指 - 用Swift实现的高仿今日头条App源代码免费下载 开源项目 6


用Swift实现的高仿今日头条App源代码免费下载 开源项目 7

用Swift实现的高仿今日头条App源代码免费下载 开源项目 - 敏捷大拇指 - 用Swift实现的高仿今日头条App源代码免费下载 开源项目 7




[Swift] 纯文本查看 复制代码
tableView(tableView:UITableView,cellForRowAtIndexPath indexPath:NSIndexPath)->UITableViewCell


中,根据不同情况对要显示的 cell 进行判断,显示对应的 cell。

具体判断情况请看 Model 里的 YMNewsTopic.swift 类。

游客,如果您要查看本帖隐藏内容请回复


详情有下面四种方式,为了实现简单,这里使用 `webView` 来实现。

游客,如果您要查看本帖隐藏内容请回复


iOS 8 以后推出的专门负责转场动画的控制器。

在 Xcode 7 以上的版本中,`UIPresentationController` 有一个 bug,见下图:

用Swift实现的高仿今日头条App源代码免费下载 开源项目 8

用Swift实现的高仿今日头条App源代码免费下载 开源项目 - 敏捷大拇指 - 用Swift实现的高仿今日头条App源代码免费下载 开源项目 8


presentingViewController 会报一个野指针的错误,这是 Xcode 的 bug。

UIPresentationController 中有两个方法可以布局子视图,分别是:

[Swift] 纯文本查看 复制代码
// 即将布局转场子视图时调用 
public func containerViewWillLayoutSubviews()
// 布局完成转场子视图时调用
public func containerViewDidLayoutSubviews()


可以在两个方法里设置  UIPresentationController 的容器视图 containerView 和 被展现的视图 presentedView()。

用Swift实现的高仿今日头条App源代码免费下载 开源项目 9

用Swift实现的高仿今日头条App源代码免费下载 开源项目 - 敏捷大拇指 - 用Swift实现的高仿今日头条App源代码免费下载 开源项目 9



游客,如果您要查看本帖隐藏内容请回复


这个类主要作为四种类型 cell 的父类,主要定义了 标题、头像、昵称、评论、关闭按钮。

显示图片交给其子类各自实现。

当时考虑过使用一个类来实现四种类型的 cell,但是经过测试,由于 cell 的重用机制,始终不能达到想要的结果,所以才分别创建了四种不同的 cell,使用一个类的方式是 YMTopicTableViewCell.swift 这个类,大家可以参考一下。

由于首页的情况比较多,cell 的显示比较复杂,而且今日头条的接口也不是很规范,所以这几个类实现起来比较麻烦,而且代码写的不是很简洁,用了很多 if 判断,可能看起来不是很美观。

判断的情况与 YMNewsTopic.swift 类相同,具体请看 YMNewsTopic.swift。

我觉得使用不同 cell 的情况还比较简单理解。

如果各位朋友有什么更好的实现方法,欢迎给我留言或『Pull Request』,非常感谢您的留言和建议。


游客,如果您要查看本帖隐藏内容请回复


用Swift实现的高仿今日头条App源代码免费下载 开源项目 10

用Swift实现的高仿今日头条App源代码免费下载 开源项目 - 敏捷大拇指 - 用Swift实现的高仿今日头条App源代码免费下载 开源项目 10


这个类和和视频顶部标题的类有些类似,对于数据和按钮点击的回调使用闭包的方式。而在视频的标题 YMVideoTitleView.swift 里使用代理来代替闭包,实现的功能是相同的,但是实现的方式不同,可以对比看一下。

对控件的布局方式还是使用的 SnapKit 来进行布局。

这个类里需要首先从服务器获取标题数据,服务器返回一个数组,根据这个数组循环创建标题的 label,然后设置好 label 的位置以及 scrollView 的 contentSize。

标题 label 的点击通过添加手势来实现监听点击操作,titleLabelOnClick 为标题点击的方法,当点击的时候,根据索引进行相应的偏移,调用 adjustTitleOffSetToCurrentIndex 来改变 label 的位置。

在 adjustTitleOffSetToCurrentIndex(currentIndex: Int, oldIndex: Int) 方法里,需要获取之前点击 label 的索引以及刚刚点击 label 的索引,改变形变,计算当前的偏移量。

重写 frame,来设置导航栏不再有两边的间距。请看具体代码 206 行。


游客,如果您要查看本帖隐藏内容请回复


这个类是我觉得最麻烦的一个类了,有很多种情况,所以判断也比较多。

今日头条返回的数据中,有这四个字段,image_list ,middle_image,large_image_list,video_detail_info,在 cell 里面分别对应 YMHomeSmallCell.swift,YMHomeMiddleCell.swift,YMHomeLargeCell.swift。

image_list 这是一个 数组,表示中间有三种图的情况;

用Swift实现的高仿今日头条App源代码免费下载 开源项目 11

用Swift实现的高仿今日头条App源代码免费下载 开源项目 - 敏捷大拇指 - 用Swift实现的高仿今日头条App源代码免费下载 开源项目 11


middle_image 这是一个字典,表示图片在右侧的情况;

用Swift实现的高仿今日头条App源代码免费下载 开源项目 12

用Swift实现的高仿今日头条App源代码免费下载 开源项目 - 敏捷大拇指 - 用Swift实现的高仿今日头条App源代码免费下载 开源项目 12


large_image_list 这是一个数组,表示中间是一张大图:

用Swift实现的高仿今日头条App源代码免费下载 开源项目 13

用Swift实现的高仿今日头条App源代码免费下载 开源项目 - 敏捷大拇指 - 用Swift实现的高仿今日头条App源代码免费下载 开源项目 13


video_detail_info 这是一个字典,表示是视频,中间也用一张大图表示,这种情况和大图的情况基本相同,但是视频中间多了播放按钮。

用Swift实现的高仿今日头条App源代码免费下载 开源项目 14

用Swift实现的高仿今日头条App源代码免费下载 开源项目 - 敏捷大拇指 - 用Swift实现的高仿今日头条App源代码免费下载 开源项目 14


还有最后一种情况就是没有图片的情况,比如置顶的专题,但是置顶的专题和上面在举报按钮的地方也有所区别,置顶的新闻没有举报按钮,其他情况有举报按钮,需要根据 一个字段 `label` 来进行判断。

用Swift实现的高仿今日头条App源代码免费下载 开源项目 15

用Swift实现的高仿今日头条App源代码免费下载 开源项目 - 敏捷大拇指 - 用Swift实现的高仿今日头条App源代码免费下载 开源项目 15


上面五种情况出现的依赖关系,也需要进行判断,

下面说一下,具体的判断过程:

image_listmiddle_imagelarge_image_listvideo_detail_info
nilnilnilnil
nil不为 nil不为 nilnil
nil不为 nilnilnil
不为 nil不为 nil不为 nil不为 inil
不为 nil不为 nil不为 nilnil
不为 nil不为 nilnil不为 nil
不为 nil不为 nilnilnil


还有一些其他情况,比如有个数据里没有 image_list 这个字段,这种情况我没做判断,一般程序崩溃都是因为这个原因。但是实际上,我是先判断 image_list 是否有值,如果有值,则显示三张图片,如果为 nil,再判断 middle_image 的情况。

如果各位朋友有什么更好的实现方法,欢迎给我留言或『Pull Request』,非常感谢您的留言和建议。


游客,如果您要查看本帖隐藏内容请回复


自定义转场动画需要集成两个代理协议,分别是 UIViewControllerTransitioningDelegate 和 UIViewControllerAnimatedTransitioning。

如果需要自定义转场动画,那么所有的操作需要自己完成,系统不再处理。


UIViewControllerTransitioningDelegate

UIViewControllerTransitioningDelegate 共有五个代理方法,这里我用到了三个代理方法,分别是:

[Swift] 纯文本查看 复制代码
// MARK:- UIViewControllerTransitioningDelegate    
/** 告诉系统由哪个控制器来实现代理
- parameter presented:被展现的视图    
- parameter presenting:展现的视图     
- returns: YMPopPresentationController 
iOS 8 以后推出的专门负责转场动画的控制器  */    
func presentationControllerForPresentedViewController(presented:UIViewController,presentingViewController presenting:UIViewController,sourceViewController source UIViewController) -> UIPresentationController?    /**     告诉系统谁来负责 modal 的展现动画     - parameter presented:  被展现的视图     - parameter presenting: 展现的视图     - returns: 由谁管理     */    func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning?    /**     告诉系统谁来负责 modal 的消失动画     - parameter dismissed: 消失的控制器     - returns: 由谁管理     */    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?



UIViewControllerAnimatedTransitioning

用到了两个代理方法:

[Swift]