--------------------------------------------------------------------------
前言:
作为一名学生, 作为一名iOS开发学习者, 我个人浏览信息包括博客, 更多的选择移动终端。然而, csdn并没有现成的客户端(不过有个web版的)。
之前曾经看到一款开源的导出工具, 但是它是基于Windows平台的。导出的也仅仅是PDF格式。而且, 对于文章的导出, 需要精确URL。无法做到边浏览别导出。
另外, 我想实现的是, 可以在没有网络的情况下, 浏览自己收藏的文章。并且, 对于自己收藏的文章, 可以分类管理。
最关键的是, 对于自己的文章, 可以做一个备份。我曾经遇到过这样一件事, csdn账号密码泄漏, 使得他人登录我账号发表垃圾博文, 导致我的博客被封一天。那时候, 我的博客记录了170篇自己的学习点滴, 没有备份, 可以想像那时候我有多慌。可见, 备份自己文章的重要性。
基于以上种种原因, 这款基于iOS平台的博客导出工具应运而生。
注:
本文章正在参与2014年csdn博客大赛。如果您觉得, 对您有所帮助, 希望能投上宝贵的一票。在最下方投票
投票链接:http://vote.blog.csdn.net/Article/Details?articleid=31768677
具体功能:
- 支持在线浏览csdn博客
- 可导类型包括: 单篇文章, 专栏, 指定作者全部文章
- 导出方式包括: (1)导出单前浏览博文/专家/专栏 (2)导出指定URL博文/专家/专栏
- 导出文章分类管理
- 导出文章查询功能
- 导出文章自动排版, 图片自适应, 可放缩
运行效果:
看到这里, 如果你只是想体验一下这个应用, 想看看源码, 那可以从我的Github中下载。另外, 第一版已经上传到App Store上去了。 正在等待审核。
https://github.com/colin1994/csdnBlog.git
如果你想了解下整体开发过程, 欢迎继续往下看。推荐下载了源码, 对照着看。
你将学到:
- 自定义启动动画
- 网络环境判断(是否是Wi-Fi状态)
- IOS与JavaScript的交互
- 自定义HUD加载效果(非传统菊花)
- UITableView列表基本操作
- 列表关键字模糊查询
- 图片基本操作
(一) 自定义启动动画
@property (strong, nonatomic) UIImageView *splashView;
打开AppDelegate.m文件, 加入具体实现过程。
1.添加启动动画
//添加启动动画
[self.window makeKeyAndVisible];
splashView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, Screen_height)];
if ([[UIScreen mainScreen] bounds].size.height == 568)
{
[splashView setImage:[UIImage imageNamed:@"bgBlog-568"]];
}
else
{
[splashView setImage:[UIImage imageNamed:@"bgBlog"]];
}
[self.window addSubview:splashView];
[self.window bringSubviewToFront:splashView];
[self performSelector:@selector(scale) withObject:nil afterDelay:0.0f];
[self performSelector:@selector(showWord) withObject:nil afterDelay:2.5f];
2.动画具体实现
-(void)scale
{
UIImageView *logo_ = [[UIImageView alloc]initWithFrame:CGRectMake(119, 88, 82, 82)];
logo_.image = [UIImage imageNamed:@"csdnLogo"];
[splashView addSubview:logo_];
[self setAnimation:logo_];
}
-(void)setAnimation:(UIImageView *)nowView
{
[UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionCurveLinear
animations:^
{
// 执行的动画code
[nowView setFrame:CGRectMake(nowView.frame.origin.x- nowView.frame.size.width*0.1, nowView.frame.origin.y-nowView.frame.size.height*0.1, nowView.frame.size.width*1.2, nowView.frame.size.height*1.2)];
}
completion:^(BOOL finished)
{
// 完成后执行code
[nowView removeFromSuperview];
}
];
}
-(void)showWord
{
UIImageView *word_ = [[UIImageView alloc]initWithFrame:CGRectMake(75, Screen_height-100, 170, 29)];
word_.image = [UIImage imageNamed:@"word_"];
[splashView addSubview:word_];
word_.alpha = 0.0;
[UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionCurveLinear
animations:^
{
word_.alpha = 1.0;
}
completion:^(BOOL finished)
{
// 完成后执行code
[NSThread sleepForTimeInterval:1.0f];
[splashView removeFromSuperview];
}
];
}
(二)网络环境判断(是否是Wi-Fi状态)
1.导入Reachability.h / .m文件
2.添加头文件
#import "Reachability.h" //Wi-Fi
3.判断网络环境
if ([Reachability reachabilityForInternetConnection].currentReachabilityStatus == ReachableViaWiFi)
{
//添加你想做的事情
}
(三)IOS与JavaScript的交互
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSString *currentURL = [webView stringByEvaluatingJavaScriptFromString:@"document.location.href"];
}
2、获取页面title。
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSString *currentURL = [webView stringByEvaluatingJavaScriptFromString:@"document.location.href"];
NSString *title = [webview stringByEvaluatingJavaScriptFromString:@"document.title"];
}
3、修改界面元素的值。
NSString *js_result = [webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByName('q')[0].value='Colin';"];
4、表单提交:
NSString *js_result2 = [webView stringByEvaluatingJavaScriptFromString:@"document.forms[0].submit(); "];
当然, 还有更多的功能, 需要你自己去学习。
//获取详细内容
NSString *lJs = @"document.getElementById(\"article_content\").innerHTML";
NSString *lHtml1 = [webView stringByEvaluatingJavaScriptFromString:lJs];
同理, 文章标题可以这样获得:
//获取标题
NSString *lJs2 = @"document.getElementById(\"article_details\").getElementsByClassName(\"article_title\")[0].getElementsByTagName(\"a\")[0].innerText";
NSString *lHtml2 = [webView stringByEvaluatingJavaScriptFromString:lJs2];
//修改图片大小
if ([lHtml1 rangeOfString:@"<img"].location != NSNotFound)
{
NSScanner *myScanner = [NSScanner scannerWithString:lHtml1];
NSString *myText = nil;
while ([myScanner isAtEnd] == NO)
{
[myScanner scanUpToString:@"<img" intoString:nil];
[myScanner scanUpToString:@"s" intoString:&myText];
lHtml1 = [lHtml1 stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"%@s",myText] withString:@"<img style=\"width:300px;height:this.offsetHeight;\" s"];
}
}
(四)自定义HUD加载效果(非传统菊花)
1.导入文件夹SVProgressHUD
2.添加头文件
#import "SVProgressHUD.h" //HUD 加载显示
3.显示HUD
//显示HUD
[SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeGradient];
4.移除HUD
//移除HUD
[SVProgressHUD dismiss];
(五)UITableView列表基本操作
//删除
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}
/*改变删除按钮的title*/
-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
return @"删除";
}
/*删除用到的函数*/
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
//获取完整路径 以及字典和数组的初始化
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString * namePath = [documentsDirectory stringByAppendingPathComponent:@"csdnInfo.plist"];
[blogArr removeObjectAtIndex:indexPath.row];
[blogArr writeToFile:namePath atomically:YES];
[nameList removeObjectAtIndex:indexPath.row];
[myTableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; //删除对应数据的cell
}
}
(六)列表关键字模糊查询
1.导入查询字列表文件夹
2.添加头文件
//查询子列表
#import "DDList.h"
#import "PassValueDelegate.h"
3.初始化查询列表
//查询列表初始化
nameList = [[NSMutableArray alloc]init];
for (int i =0; i<[blogArr count]; i++)
{
[nameList addObject:[[blogArr objectAtIndex:i]objectForKey:@"name"]];
}
//初始化查询的字符串
_searchStr = @"";
//初始化提醒视图
_ddList = [[DDList alloc] initWithStyle:UITableViewStylePlain];
_ddList._delegate = self;
[self.view addSubview:_ddList.view];
[_ddList.view setFrame:CGRectMake(30, 108, 200, 0)];
_ddList._totalList = nameList;
4.响应查询
//隐藏提醒视图
- (void)setDDListHidden:(BOOL)hidden
{
NSInteger height = hidden ? 0 : 180;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.2];
[_ddList.view setFrame:CGRectMake(30, 108, 200, height)];
[UIView commitAnimations];
}
//单例,传回选中提醒框中的结果
#pragma mark -
#pragma mark 传回数据
- (void)passValue:(NSString *)value
{
//如果有选中,则修改当前搜索内容为返回结果,调用结束函数searchBarSearchButtonClicked
if (value)
{
_searchBar.text = value;
[self searchBarSearchButtonClicked:_searchBar];
}
else {
}
}
//搜索框中的字符改变时候调用
#pragma mark -
#pragma mark SearchBar Delegate Methods
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
//如果搜索框有内容,更新提示列表
if ([searchText length] != 0) {
_ddList._searchText = searchText;
[_ddList updateData];
[self setDDListHidden:NO];
}
else
{
[self setDDListHidden:YES]; //否则隐藏
}
}
//文本框弹出,开始搜索
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
searchBar.showsCancelButton = YES;
for(id cc in [searchBar subviews])
{
if([cc isKindOfClass:[UIButton class]])
{
UIButton *btn = (UIButton *)cc;
[btn setTitle:@"取消" forState:UIControlStateNormal];
}
}
return YES;
}
//开始搜索响应。
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
searchBar.text = @"";
}
//结束文本框输入
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
searchBar.showsCancelButton = NO;
searchBar.text = @"";
}
//当选中了提示列表中的某个,搜索结束,选中结果,并且高亮
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[self setDDListHidden:YES]; //隐藏提示视图
_searchStr = [searchBar text]; //获得查询结果
[searchBar resignFirstResponder]; //收回键盘
for (int i = 0; i<[blogArr count]; i++) //从列表中查找结果,选中
{
if ([[[blogArr objectAtIndex:i]objectForKey:@"name"] isEqualToString:_searchStr])
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
[myTableView reloadData];
[myTableView scrollToRowAtIndexPath:indexPath //滚动视图
atScrollPosition:UITableViewScrollPositionMiddle
animated:YES];
[myTableView selectRowAtIndexPath:indexPath //选中高亮
animated:YES
scrollPosition:UITableViewScrollPositionMiddle];
}
}
}
//取消搜索响应
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
[self setDDListHidden:YES];
[searchBar resignFirstResponder];
}
(七)图片基本操作
1.添加手势。
// Add gesture,double tap zoom imageView.
UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(handleDoubleTap:)];
[doubleTapGesture setNumberOfTapsRequired:2];
[imageView addGestureRecognizer:doubleTapGesture];
我们的放缩都是通过手势识别来实现的。 比如, 你双指拖拉, 就是放缩。 双指点击是自动放缩, 单指点击是退出图片浏览。
2.响应手势操作
#pragma mark - Zoom methods
- (void)handleDoubleTap:(UIGestureRecognizer *)gesture
{
float newScale = self.zoomScale * 1.5;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gesture locationInView:gesture.view]];
[self zoomToRect:zoomRect animated:YES];
}
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center
{
CGRect zoomRect;
zoomRect.size.height = self.frame.size.height / scale;
zoomRect.size.width = self.frame.size.width / scale;
zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0);
zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0);
return zoomRect;
}
本文章正在参与2014年csdn博客大赛。如果您觉得, 对您有所帮助, 希望能投上宝贵的一票。
投票链接:http://vote.blog.csdn.net/Article/Details?articleid=31768677