iOS开发学习之-常见的app基础框架 -项目总结

一、标签式

1,标签式框架最常见,包括像淘宝、京东等主流的app都是采用此框架。框架采用UITabBarController作为根控制器,在里面添加UINavigationController,实现多个视图,如图:

完成之后,进行UITabBarItem的设置,包括标题和选择/未选择时候的图片:


之后在AppDelegate.h里面设置一下;

MyTabBarViewController * myTabBar = [[MyTabBarViewController alloc]init];

self.window.rootViewController = myTabBar;

效果:


二、滚动式框架

1,最有代表的就是腾讯,网易新闻类的app,思路就是点击button,通过tag值来改变UIScrollView的setContentOffset ,并把多个子视图控制器添加为UIScrollView的ChildViewController;核心代码为:



效果:


三、抽屉式



四、项目总结


```

1、改变状态栏的样式

方法一:[self.navigationController.navigationBar setBarStyle:UIBarStyleBlack];//这个方法必须写在rootViewController里面。而且要保证需要改状态栏颜色的viewController是继承与rootViewController的

方法二:[UIApplication sharedApplication].statusBarStyle  = UIStatusBarStyleLightContent;  //这种方法写在AppDelegate里面,但要配合修改plist文件,在Info.plist里面添加View controller-based status bar appearance,并将其属性修改为NO

2、创建数据model时,防止未定义的key引起程序崩溃,可在model的.m文件添加下面的方法,过滤掉未定义的key值,防止程序崩溃,而且可以修改和系统关键字重复的字段名称

```

-(void)setValue:(id)value forUndefinedKey:(NSString *)key

{

if ([key isEqualToString:@"description"]) {

self.detail = value;

}

}

```

3.UITableView的header和tableHeaderView是两个不同的概念,tableHeaderView有且只有一个,而tableView的每个section都可能有自己的header


4.轮播类的使用


```

//创建并设置frame

_cycleView = [[Carousel alloc]initWithFrame:CGRectMake(0,0, KSCREENW,(KSCREENH - 49) / 4)];

//设置是否需要pageControl

_cycleView.needPageControl = YES;

//设置是否需要无限轮播

_cycleView.infiniteLoop = YES;

//设置pageControl的位置

_cycleView.pageControlPositionType = PAGE_CONTROL_POSITION_TYPE_RIGHT;

//设置网络图片数组

_cycleView.imageUrlArray = self.cycleImageArray;

//设置本地图片数组

_cyclePlaying.imageArray = @[@"shili10",@"shili2",@"shili1",@"shili19"];

[_headerBgView addSubview:_cycleView];

5.处理图片,使用图片原尺寸

UIImage * unselectedImage = [UIImage imageNamed:unselectedImageArray[i]];

unselectedImage = [unselectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

6.appearance用来单独设置某个类的属性

[[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor orangeColor]} forState:UIControlStateSelected];

7.导航相关属性

//设置导航条颜色

self.navigationController.navigationBar.barTintColor = [UIColor orangeColor];

//设置导航不透明,不透明指的是让控件的起始纵坐标已经除去导航的64高度

self.navigationController.navigationBar.translucent = NO;


```

8.如果一行文字有多种样式(不同的大小或者不同的字体颜色),可用下面的函数处理

NSMutableAttributedString * string = [[NSMutableAttributedString alloc]initWithString:[NSString stringWithFormat:@"%d%@",indexPath.row + 1,model.dishes_step_desc]];

[string addAttributes:@{NSForegroundColorAttributeName:[UIColor orangeColor]} range:NSMakeRange(0, 2)];

_desLabel.attributedText = string;

```

```

9.设置cell的点击效果为无

cell.selectionStyle = UITableViewCellSelectionStyleNone

10.设置cell的分割线为无

方法一:_tableView.separatorStyle = UITableViewCellSeparatorStyleNone

方法二:_tableView.separatorColor = [UIColor clearColor]

11.去掉tableView多余的线条

_tableView.tableFooterView = [[UIView alloc]init]

12.push页面的时候隐藏tabBar

//页面跳转的时候隐藏tabBar

detailVC.hidesBottomBarWhenPushed = YES;

13.网络活动指示器的使用

//活动指示器

_hud = [[MBProgressHUD alloc]initWithView:self.view];

//设置加载的文字提示

_hud.labelText = @"正在加载...";

//设置菊花的颜色

_hud.activityIndicatorColor = [UIColor whiteColor];

//设置颜色

_hud.color = [UIColor colorWithWhite:1 alpha:0.2];

[self.view addSubview:_hud];

//显示活动指示器

[_hud show:YES];

//数据请求成功之后停止活动指示器

[_hud hide:YES];

14.设置label的边框

//设置边框宽度

indexLabel.layer.borderWidth = 2;

//设置边框颜色

indexLabel.layer.borderColor = [UIColor redColor].CGColor;

15.使用AFNetworking请求数据时的contentType设置

//ContentType默认支持json,如果要支持其他格式,需要手动设置

manager.responseSerializer.acceptableContentTypes  = [NSSet setWithObjects:@"text/html", nil];

16.设置cell的简单动画

//给cell添加动画

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

{

//设置Cell的动画效果为3D效果

//设置x和y的初始值为0.1;

cell.layer.transform = CATransform3DMakeScale(0.1, 0.1, 1);

//x和y的最终值为1

[UIView animateWithDuration:1 animations:^{

cell.layer.transform = CATransform3DMakeScale(1, 1, 1);

}];

}

```

17.滚动式项目框架的实现

_scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, SCREENW, SCREENH)];

//设置分页

_scrollView.pagingEnabled = YES;

//设置隐藏横向滑条

_scrollView.showsHorizontalScrollIndicator = NO;

[self.view addSubview:_scrollView];

//设置contentSize

_scrollView.contentSize = CGSizeMake(2 * SCREENW, 0);

//设置代理

_scrollView.delegate = self;

//实例化

ArticalViewController * articalVC = [[ArticalViewController alloc]init];

articalVC.view.backgroundColor = [UIColor redColor];

RecoderViewController * recoderVC = [[RecoderViewController alloc]init];

recoderVC.view.backgroundColor = [UIColor yellowColor];

NSArray * array = @[articalVC,recoderVC];

int i = 0;

for (UIViewController * vc in array) {

vc.view.frame = CGRectMake(i * SCREENW, 0, SCREENW, SCREENH);

[self addChildViewController:vc];

[_scrollView addSubview:vc.view];

i ++;

}

18.UIWebView的使用

_webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 0, SCREENW, SCREENH)];

//设置自动适配屏幕比例

_webView.scalesPageToFit = YES;

//加载内容,loadHTMLString用于加载带有标签式的字符串,loadRequest用于加载网址

[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:ARTICALDETAILURL,self.articalModel.dataID]]]];

[self.view addSubview:_webView];

19.系统提示框的使用

//iOS8之前的写法

UIAlertView * alertView = [[UIAlertView alloc]initWithTitle:@"提示" message:@"已经收藏过了" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];

[alertView show];

//iOS8之后的写法

UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"已经收藏过了" preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction * action = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];

[alert addAction:action];

[self presentViewController:alert animated:YES completion:nil];

20、http中的post数据请求

AFHTTPRequestOperationManager * manager = [AFHTTPRequestOperationManager manager];

NSDictionary * dic = @{@"methodName": @"HomeSerial", @"page": [NSString stringWithFormat:@"%d",_page], @"serial_id": [NSString stringWithFormat:@"%d",_dataID], @"size": @"20"};

[manager POST:FOODURL parameters:dic success:^(AFHTTPRequestOperation *operation, id responseObject) {

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {

}];

21.iOS9之前和iOS9之后的视频播放

-(void)beforeiOS9Nomal:(NSString *)videoUrl

{

//初始化视频播放器

MPMoviePlayerViewController * playVC = [[MPMoviePlayerViewController alloc]initWithContentURL:[NSURL URLWithString:videoUrl]];

//设置播放资源

playVC.moviePlayer.movieSourceType = MPMovieSourceTypeFile;

//设置全屏播放

playVC.moviePlayer.controlStyle = MPMovieControlStyleFullscreen;

//播放之前进行预播放

[playVC.moviePlayer prepareToPlay];

//开始播放

[playVC.moviePlayer play];

//推出播放控制器

[self presentViewController:playVC animated:YES completion:nil];

}

//iOS9之后的视频播放。iOS9之后,MPMoviePlayerViewController被废弃掉,由AVKit框架下的AVPlayerViewController代替,同时需要结合AVFoudation框架下的AVPlayer来使用

-(void)afteriOS9Normal:(NSString *)videoUrl

{

//实例化

AVPlayerViewController * playVC = [[AVPlayerViewController alloc]init];

//设置播放资源

AVPlayer * player = [AVPlayer playerWithURL:[NSURL URLWithString:videoUrl]];

//转换播放器

playVC.player = player;

//推出播放视图控制器

[self presentViewController:playVC animated:YES completion:nil];

}

//实现强制横屏,需要重写系统的两个方法

-(BOOL)shouldAutorotate

{

return YES;

}


-(UIInterfaceOrientationMask)supportedInterfaceOrientations

{

return UIInterfaceOrientationMaskLandscape;

}

22.实现tableView的图头放大效果

//头部视图,实现一个头图放大的效果

_headerImageView = [FactoryUI createImageViewWithFrame:CGRectMake(0, -ImageOriginHeight, SCREENW, ImageOriginHeight) imageName:@"welcome1"];

[_tableView addSubview:_headerImageView];

//设置tableView的内容从ImageOriginHeight处开始显示.四个参数分别表示上左下右

_tableView.contentInset = UIEdgeInsetsMake(ImageOriginHeight, 0, 0, 0);

-(void)scrollViewDidScroll:(UIScrollView *)scrollView

{

//实现思路:根据scrollView的滑动偏移量来改变顶部图片的大小

if (scrollView == _tableView) {

//获取scrollView的偏移量

//纵向偏移量

float yOffset = scrollView.contentOffset.y;

//横向偏移量,它的变化随着纵向偏移量的变化而变化

float xOffset = (yOffset + ImageOriginHeight) / 2;

//改变图片的大小

if (yOffset < -ImageOriginHeight) {

CGRect rect = _headerImageView.frame;

//纵坐标

rect.origin.y = yOffset;

//高度

rect.size.height = -yOffset;

//横坐标

rect.origin.x = xOffset;

//宽度

rect.size.width = SCREEN_W + fabs(xOffset) * 2;

_headerImageView.frame = rect;

}

}

}

23.夜间模式实现

_darkView = [FactoryUI createViewWithFrame:[UIScreen mainScreen].bounds];

//夜间模式

if (swi.on) {

//添加半透明view到window上

UIApplication * app = [UIApplication sharedApplication];

AppDelegate * delegate = app.delegate;

//设置view的背景色

_darkView.backgroundColor = [UIColor blackColor];

_darkView.alpha = 0.3;

//关闭view的用户交互(响应者链),UIImageView的用户默认关闭,UIView的用户交互默认打开

_darkView.userInteractionEnabled = NO;

[delegate.window addSubview:_darkView];

}

else

{

[_darkView removeFromSuperview];

}

24.tableVIew实现数据删除

//删除数据

//设置是否允许编辑

-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath

{

return YES;

}

//设置编辑cell的类型

-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath

{

return UITableViewCellEditingStyleDelete;

}

//具体实现删除

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

{

//删除cell具体实现思路:1.删除数据库中的数据 2.删除当前页面数据源的数据(对应的数组中的数据)3.删除与数据相对应的cell

//第一步

DBManager * manager = [DBManager defaultManager];

ArticalModel * model = self.dataArray[indexPath.row];

[manager deleteNameFromTable:model.dataID];

//第二步

[self.dataArray removeObjectAtIndex:indexPath.row];

//第三步

[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

}

25.引导页实现

-(void)addGuidePage

{

if (![[[NSUserDefaults standardUserDefaults]objectForKey:@"isRuned"] boolValue]) {

NSArray * imageArray = @[@"welcome2",@"welcome3",@"welcome4"];

self.guidePageView = [[GuidePageView alloc]initWithFrame:self.window.bounds imageArray:imageArray];

[self.myTabBar.view addSubview:self.guidePageView];

//第一次运行完成之后进行记录

[[NSUserDefaults standardUserDefaults]setObject:@YES forKey:@"isRuned"];

}

//点击最后的按钮跳转

[self.guidePageView.goInButton addTarget:self action:@selector(goInButtonClick) forControlEvents:UIControlEventTouchUpInside];

}

-(void)goInButtonClick

{

[self.guidePageView removeFromSuperview];

}

26、UICollectionView的header和footer的实现

//设置header的大小

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section

{

return CGSizeMake(SCREEN_W, 30);

}

//设置footer的大小

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section

{

return CGSizeMake(SCREEN_W, 30);

}

//设置header和footer对应的view

-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath

{

//参数一:表示是header还是footer,根据需要做一说明

MusicCollectionReusableView * view = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"View" forIndexPath:indexPath];

//header

if (kind == UICollectionElementKindSectionHeader) {

view.titleLabel.text = @"段头";

} else if (kind == UICollectionElementKindSectionFooter)

{

view.titleLabel.text = @"段尾";

}

return view;

}

27.AVAUdioPlayer实现音乐播放

//系统的音乐播放使用AVFoundation框架下的AVAudioPlayer来实现,但是AVAudioPlayer只能播放本地音乐文件,并且只能播放单一的音乐文件,如果想要播放网络音乐文件的话,实现思路实质上是先将音乐文件缓存到本地,然后进行播放

//存在的问题:缓存音乐文件到本地的过程是一个耗时的过程。所以我们通过手动开辟多线程来处理,将缓存音乐文件的操作放在子线程中,防止主线程阻塞,导致界面假死

//创建线程组,使用GCD

dispatch_group_t group = dispatch_group_create();

//创建线程队列

dispatch_queue_t queue = dispatch_queue_create(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//启用异步方法

dispatch_group_async(group, queue, ^{

[self createAVAudioPlayer];

});

-(void)createAVAudioPlayer

{

//初始化

//NSURL创建,initWithContentsOfURL表示的是本地文件的url

//_audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL URLWithString:self.urlString] error:nil];

//NSData创建,播放网络资源

_audioPlayer = [[AVAudioPlayer alloc]initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:self.urlString]] error:nil];

//设置代理

_audioPlayer.delegate = self;

//设置播放音量

_audioPlayer.volume = 0.5;//0~1之间

//设置当前的播放进度

_audioPlayer.currentTime = 0;

//设置循环次数

_audioPlayer.numberOfLoops = -1;//负数表示无限循环播放,0表示只播放一次,正数是几就播放几次

//只读属性

// _player.isPlaying //是否正在播放

//_player.numberOfChannels //声道数

//_player.duration //持续时间

//预播放,将播放资源添加到播放器中,播放器自己分配播放队列

[_audioPlayer prepareToPlay];

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容