第一阶段控件/第二阶段数据存储/第三阶段通讯
A控件:
0、UIview :
可以挡住 button的事件 挡不住touchBegan的事件;
MAX(<#A#>, <#B#>) //比较A和B 取较大的;
CGRectGetMaxX(<#CGRect rect#>)//获取X轴最大值;
aView.layer.cornerRadius = 40; //圆角 是UiView的属性;
aView.clipsToBounds = YES; //剪下来 到边界 是UiView的属性;
[_view1 setClipsToBounds:YES];//裁剪边到边界
aButton.layer.borderWidth =1;//设置边框
aButton.layer.borderColor =[UIColor redColor].CGColor;
>>通过tag值找控件的时候,先判断自身tag是否符合,然后遍历身上子控件的tag找到第一个匹配的。
//判断_aImageView是不是cell.contentView的子视图
[_aImageView isDescendantOfView:cell.contentView]
1、调用主屏幕尺寸并做 全屏退键盘按钮:0
_window.frame = [[UIScreen mainScreen] bounds]];//调用主屏幕尺寸;
//全屏背景按钮;
UIControl *page1BackControl = [[UIControl alloc]initWithFrame:[[UIScreen mainScreen] bounds]];//设置contrl对象
[page1BackControl addTarget:self action:@selector(allBackGroundButtonClick) forControlEvents:(UIControlEventTouchUpInside)];//给对象一个事件
[_window addSubview:page1BackControl];
>>>®®®[self.view bringSubviewToFront:aView]; //把子视图aView设置到最前面;
[self.view sendSubviewToBack:earth1] ;
2、UIImageView 加背景图片:
UIImageView上挂载按钮 按钮无法操作,因为相框(UIImageView)的用户交互信息默认是关闭的需要手动打开;
imgView.userInteractionEnabled=YES;
UIImageView *imageView = [[UIImageView alloc] init];
aView.layer.cornerRadius = 40; //圆角 是UiView的属性;
aView.clipsToBounds = YES; ////剪下来 到边界 是UiView的属性;
imageView.frame = CGRectMake(0, 0, 320 , 320); //创建相框;
imageView.image = [UIImage imageNamed:@"llll"]; //引用图片;
[_window addSubview:imageView];
3、UILabel Label显示书签;
UILabel *_label = [[UILabel alloc] init];
_label.frame = CGRectMake(100, 40, 130, 30); //输入框位置;
[_window addSubview:_label];//在window视口上添加子视口;
label.shadowColor=[UIColor yellowColor];//阴影颜色
label.shadowOffset=CGSizeMake(5, 10);//设置阴影偏移量(正值往右偏,正值往下偏移)
label.textAlignment = NSTextAlignmentCenter;//文字对齐方式
label.font = [UIFont systemFontOfSize:25];
label.numberOfAlignment=0 0为自动换行;
4、UITextField 文本框输入栏;
UITextField *_textField = [[UITextField alloc] initWithFrame:CGRectMake(50, 80, 220, 35)];
_textField.placeholder = @"hello girl!告诉我你的工资。";//占位符;
_textField.borderStyle = UITextBorderStyleRoundedRect;
_textField.returnKeyType=UIReturnKeyGo;//设置键盘的回车键;
_textField.keyboardType = UIKeyboardTypeNumberPad;//输入框类型;
_textField.secureTextEntry = YES;//安全符输入
[_textField becomeFirstResponder];//成为第一响应者。
[_window addSubview:_textField];
//文本框结束编辑的两个方式:searchBar文板框—>>文本框取消第一响应/结束编辑 或视图取消第一响应/结束编辑。
[self.view endEditing:YES];
[searchBar endEditing:YES];
[searchBar resignFirstResponder];
[self.view resignFirstResponder];
可以添加一个事件 事件类型选择 编辑完成是退出键盘即点击回车退出键盘UIControlEventEditingDidEndOnExit;
//在低版本的时候,如果直接点击注册按钮,没有点击具体的输入框,得到输入框中的内容为nil,如果点击输入框,但是没有输入任何内容,这个时候点击注册按钮获得的内容为@"".这是系统懒加载的结果。
5、UIButton Button 按钮:
>>>通过tag 找回子视图上的 view或button
UIView *aView = [self.view viewWithTag:2]
按钮上的标题相当于 在按钮上叠加了一层label;
设置标题名字用 调用方法 [_dayOrNight setTitle:@"晚上" forState:UIControlStateNormal];
UIButton *button = [[UIButton alloc] init];
button.frame = CGRectMake(100, 120, 150, 40);
[button setTitle:@"点我" forState:UIControlStateNormal];//按钮上的标题;
button.titleLabel.font = [UIFont systemFontOfSize:25];//修改字号;
//设置按钮选中状态的背景图片; btn.selected=YES;为选中, 默认是NO
[button setBackgroundImage:[UIImage imageNamed:@"w_xq1.png"] forState:UIControlStateSelected];
[button addTarget:self action:@selector(buttonClick) forControlEvents:( UIControlEventTouchUpInside )];//添加按钮事件:1、用谁来调用;2、调用什么方法固定格式 @selector();3、触发启用时间的方式;
[_window addSubview:button];
6、UIPickerView (: UIView) pickerVIew 滚轴:必须做代理才能显示。
UIPickerView *pickView = [[UIPickerView alloc]initWithFrame:CGRectMake(0, 100, 320, 150)];
picker 高度只有三种尺寸 162/180/216;
picker 必须做代理才能显示。.h中声明 <UIPickerViewDataSource,UIPickerViewDelegate>
.m中实现必选方法 并且设置委托:pickView.delegate=self; pickView.dataSource=self;
[pickerView selectRow:0 inComponent:1 animated:YES];//必须放在 判断组件的条件里面
[pickerView reloadComponent:1];[pickerView reloadAllComponents];
7、UIDatePicker (: UIControl)日历picker:
//UIDatePicker是处理时间的一个控件,继承于UIControl ,UIPickView继承于UIView,两者没有直接联系
UIDatePicker *pick=[[UIDatePicker alloc]initWithFrame:CGRectMake(0, 0, 320, 240)];
[self.view addSubview:pick];
pick.datePickerMode=UIDatePickerModeDateAndTime;//时间表类型
pick.minimumDate=[NSDate dateWithTimeInterval:5*60*60 sinceDate:[NSDate date]];//设置日期最小值
//[NSDate date]获取当前日期
-(void)goGoGo:(UIDatePicker *)aDatePick{//日期转化成字符串
NSDate *nowDate = [aDatePick date]; //获取一个日期
>>获取当前日期方法一
NSDate *nowDate = [NSDate date];//获取当前日期时间
NSDateFormatter *fromat = [[NSDateFormatter alloc]init];
[fromat setDateFormat:@"yyyy年MM月dd日 eeee hh:mm:ss a"];//设置日期格式
NSString *str = [fromat stringFromDate:nowDate];//获取字符串 从日期;
NSLog(@"%@",str);
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{//字符串转化成日期给表格
UIDatePicker *datePicker =(UIDatePicker *)[self.view viewWithTag:2];
NSString *str = @"2015年05月28日 09:29:36";
NSDateFormatter *format = [[NSDateFormatter alloc]init];
[format setDateFormat:@"yyyy年MM月dd日 hh:mm:ss"];
NSDate *aDate = [format dateFromString:str];
datePicker.date = aDate;//把设置好格式的日期给 当前表格
}
>>获取当前日期方法二
- (NSString *)time{
NSDate *now=[NSDate date];
NSCalendar *cal=[NSCalendar currentCalendar];
NSCalendarUnit time=NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond;
NSDateComponents *t=[cal components:time fromDate:now];
int year=[t year];
int mouth=[t month];
int day=[t day];
int hour=[t hour];
int minute=[t minute];
int second=[t second];
NSString *label2=[NSString stringWithFormat:@"%2d-%2d-%2d-%2d-%2d-%2d",year,mouth,day,hour,minute,second];
return label2;
}
8、 UIAlertView UIActionSheet警告提示窗:
>>>//弹出框 Alert 警告,
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"警告" message:@"用户名不能为空" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[alertView show];//show 展现 ,显示alertview
return; }
aAlert.alertViewStyle=UIAlertViewStyleLoginAndPasswordInput;//输入框(密码 用户名等 明文和暗文)的输入。
UITextField *aField=[alertView textFieldAtIndex:0];//获取输入框的内容。
>>>//ActionSheet警告, 重下面弹出框
UIActionSheet *action=[[UIActionSheet alloc]initWithTitle:@"提示" delegate:self cancelButtonTitle:@"红" destructiveButtonTitle:@"绿" otherButtonTitles:@"蓝", nil];
[action showInView:self.view];
9、UIScrollView (:UIView)滑动相框控件:
UIScrollView *scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(10, 30, 300, 400)];
scrollView.contentSize = CGSizeMake(300*14, 400);//设置一个活动范围视图就可以动了;
scrollView.pagingEnabled = YES;//控制逐页浏览;
scrollView.showsHorizontalScrollIndicator = NO;//水平进度显示轴
scrollView.showsVerticalScrollIndicator = NO;//竖直进度显示轴
scrollView.contentOffset = CGPointMake(0, 0);//内容偏移值
_smallScroll.alwaysBounceVertical = YES;//反弹效果
//在导航器中 scrollView的视图自适应 :
控制器中的scollerView 先放置, 然后放置其他视图,会产生 scollerView身上子视图向下偏移20个像素;
解决办法: 1、 后放置scollerView 或者2、关闭他的自适应 // self.automaticallyAdjustsScrollViewInsets=NO;
//控件 触发事件:
scrollView 是系统的设置, 要使用其设置方法需要做代理, 1、 .h中 <UIScrollViewDelegate> 2、 .m中_itleScroll.delegate =self;(_itleScroll为 scroll对象) 3、 .m中 实现代理方法就可以了;
//只要scroll 偏移了就会调用
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
//手拨动时会调用
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
10、UIPageControl(:UIControl )//页面控制 点点轴
UIPageControl *pageCtr = [[UIPageControl alloc]initWithFrame:CGRectMake(10, 450, 300, 20)];
pageCtr.numberOfPages = 14;//页数
pageCtr.currentPage =0;//当前页数
pageCtr.pageIndicatorTintColor=[UIColor lightGrayColor];//点颜色
pageCtr.currentPageIndicatorTintColor = [UIColor blackColor];//当前点颜色
11、 UINavigationController(:UIViewController)导航器
//导航器相当于一个桶,里面叠着放了很多控制器,但视图只能看到最上面的一个, 所以出栈就是视图控制器的移除;压栈是创建一个视图控制器对象;
UINavigationController *aNav = [[UINavigationController alloc]initWithRootViewController:OneCtr];//OneCtr为View控制器
self.window.rootViewController = aNav;
UIBarButtonItem(:UIBarItem) 与UIbutton无关
>>>设置导航bar栏<<<
self.title = @"safdasd";
self.navigationItem.title = @"GGGGGG";
navigationController 和 navigationItem都是UIViewcontrol的属性, 只有UIViewcontrol对象在控制器中时 此属性才有意义
self.navigationController.navigationBarHidden=YES;(此处是导航控制器的属性,控制所有bar)//隐藏Bar栏
//设置导航栏的左右按钮标题及事件 (此处是视图控制器的属性,控制当前视图ctr的bar);
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"GoBarTwo" style:UIBarButtonItemStylePlain target:self action:@selector(barGoToPageTwo)];
[self.navigationController pushViewController:twoCtr animated:YES];
>>>压栈和出栈<<<
//当前控制器在导航器中,那么控制器的navigationController这个属性才有东西,代表他所在的导航器,如果当前控制器没有在导航器里,这个属性就是nil;
[self.navigationController pushViewController:twoBarCtr animated:YES];//压栈一个控制器
[self.navigationController popViewControllerAnimated:YES];//出栈一个控制器
//通过导航控制器找到 控制器中的所有视图控制器的数组,通过数组找到里的视图控制器对象,进而控制此对象的属性;
NSArray *NavigaArray = self.navigationController.viewControllers;
ZWOneViewController *OneCtr = NavigaArray[0];
OneCtr.TFOne.text = self.TFTwo.text;//控制器间传参。
>>>模态<<< 控制器之间的跳转
ZWThreeViewController *threeCtr = [[ZWThreeViewController alloc]init];
[self presentViewController:threeCtr animated:YES completion:nil];//模态呈现控制器对象
[self dismissViewControllerAnimated:YES completion:nil];//模态移除呈现的对象
three.modalTransitionStyle=UIModalTransitionStyleFlipHorizontal;//设置翻转动画,是枚举类型(翻转一半在此处)
foodDetail.modalPresentationStyle=UIModalPresentationFormSheet;//设置模态呈现一个视图, 在此视图的上面,半屏或全屏(Ipad有效)。
????= self.presentingViewController//模态通过呈现找对象,???可以为导航器
UINavigationController *naviga = self.presentingViewController;//模态通过呈现找对象(找到的可以使导航器数组或者控制器对象);
ZWTwoViewController *twoCtr = naviga.viewControllers[1];//通过导航器数组找 控制器对象;
//UIViewController 对象来打点调用 presenting 得到呈现我的对象;
//presented 得到我呈现的对象;
12、UIWebView(:UIView)网络
URL—>>统一资源定位符
UIWebView *_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 44+30, 320, 480-44-30)];
NSURL *webUrl = [NSURL URLWithString:@"http://www.baidu.com"];
NSURLRequest *webUrlRequst = [NSURLRequest requestWithURL:webUrl];
[_webView loadRequest:webUrlRequst];
[_webView setScalesPageToFit:YES];
[self.view addSubview:_webView];
[_webView.request.URL absoluteString]//获取当前_webView的 地址。
[_webView.request.URL relativeString]//获取当前_webView的 地址。
13、UIActivityIndicatorView(:UIView) 网络加载时的小 风火轮圈圈:
_activityIndicat = [[UIActivity00View alloc] initWithFrame:CGRectMake(100, 150, 100, 100)];
_activityIndicat.activityIndicatorViewStyle=UIActivityIndicatorViewStyleGray;
_activityIndicat.hidesWhenStopped = YES;
[self.view addSubview:_activityIndicat];
14、UILongPressGestureRecognizer:(UIGestureRecognizer(:NSObject))长按事件控件
//设置长按控件
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPress:)];
longPress.delegate=self;
longPress.minimumPressDuration=1;
[aView addGestureRecognizer:longPress];//需要触发长按时间的添加此对象
-(void)longPress:(UILongPressGestureRecognizer *)aLongPress{//长按事件
if (aLongPress.state ==UIGestureRecognizerStateBegan) {
}
}
15、UITableView(:UIScrollView:UIView) 表表表表表表表表表表表表表表表表表表表表 //添加视图直接可显示 , 要设置此表 必须做代理
>>创建表的方法>>UITableView 表表表表表表表表表表表表表表表表表表表表表表表表表
1>>代码 在控制器中创建一个UITableView对象
2>>Xib 上拖拽一个UITableView
3>>直接创建一个 UITableViewController 并且附带Xib的控制器
>>创建表细胞的方法>>UITableViewCell
1>>代码直接在UITableView控制器中创建
2>>新建一个类继承 UITableViewCell 可以给这个类扩充属性,比如 上面放的图片,按钮什么的;
3>>新建一个类继承 UITableViewCell 附带Xib 用Xib拖拽需要扩充的 控件,并且>**设置重用标示符>**cell的尺寸一定要和 表对象里面设置的行高一致。
找到这个cell的方法 cell= [[NSBundle mainBundle] loadNibNamed:@"ZYMyTwoTableViewCell" owner:nil options:nil][0];
UITableView *aTableView= [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
[self.view addSubview:aTableView];
aTableView.delegate=self;
aTableView.dataSource=self;
//表头
UIView *aView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 60)];
aTableView.tableHeaderView=aView;
UITableViewCell *cell=[tableView cellForRowAtIndexPath:indexPath];//获得选择的行的cell
cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;//最右边访问下级标示符
>>>>cell的 重复使用
A>>使用注册单元格
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];
//从Xib拖拽的cell注册单元格
[self.tableView registerNib: [UINib nibWithNibName:@"ZWTableViewCell" bundle:nil] forCellReuseIdentifier:@"cell"];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
不需要再alloc创建 cell对象, 系统会在没有可重复利用的cell对象的时候自己创建;
}
B>>//手动设置代码
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{//行里面的 内容
static NSString *str = @"strxxx";//设置一个重用标示
UITableViewCell *aCell = [tableView dequeueReusableCellWithIdentifier:str];//在有重用标示的对象中选出一个
if (aCell==nil) {//如果没有找到有重用标示的对象 那么创建一个对象
aCell=[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:str] autorelease];
}
if (indexPath.section==0&&indexPath.row==0) {//只在第一行设置图片
cell.imageView.image=[UIImage imageNamed:@"foot.png"];
}else{
cell.imageView.image=nil;
}
aCell.textLabel.text=@“dsfgds”;
return aCell;
}
//重新刷新表,就会重新执行表的委托方法
[_tab reloadData];
//重新刷新特定的区
[_tab reloadSections:[NSIndexSet indexSetWithIndex:btn.tag] withRowAnimation:UITableViewRowAnimationMiddle];
//重新刷新特定的多个区
NSMutableIndexSet *indexSet=[[NSMutableIndexSet alloc] init];
[indexSet addIndex:0];
[indexSet addIndex:1];
[_menuTable reloadSections:indexSet withRowAnimation:UITableViewRowAnimationLeft];
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
//使用此方法是tableView的样式 不要用group, 否者会出BUG(第0区的区头不显示)
}
//返回滑动删除按钮的标题
- (NSString* )tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath;
>>>>>//屏幕右边的索引条 , 数组里面对象的索引和表里面的section索引对应。
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
ASCII码值转字符串
unichar cc = i;
NSString* info = [NSString stringWithFormat:@"%c",cc];
NSArray *aArr=@[@"1",@"2",@"3"];
return aArr;
}
>>>>单元格的删除
[tableView delete:indexPath];//没动画
//有动画—---参数是数组,数组中只能存放indexPath的对象
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationMiddle];
//当把这个方法粘过来的时候,这个表就会启用左滑删除这个功能,当点击删除按钮的时候,就会调用这个方法,这个方法是处理添加和删除(删除//添加都会调用此方法)。
//当点击编辑操作会调用此方法 比如: 滑动删除的删除/添加/多选/删除等。
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{……………………}
//设置表的编辑样式返回0表示不编辑,1表示删除,2表示添加,3表示多选,需要打开表的编辑模式 。
//此处返回1并且编辑样式 关闭。 滑动删除可用。否者滑动删除失效。
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
// 110=1*10^2+1*10^1+0*10^0
// 110=1*2^2+1*2^1+0*2^0
// | 或运算 1|0=1 0|0=0 1|1=1
// & 余运算 1&0=0 0&0=0 1&1=1
return 1;
}
16、UISearchBar(:UIView)搜索控制器.H遵守协议<UISearchBarDelegate>///和UISearchDisplayController一起用
_searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
_searchBar.delegate=self;
_searchBar.showsCancelButton=NO;//此处不影响UISearchDisplayController时的cancel的打开。
_searchBar.showsScopeBar=YES;//搜索条件打开
_searchBar.scopeButtonTitles=@[@"name",@"phone"];//搜索条名称
_searchBar.selectedScopeButtonIndex=1;//搜索条默认位置
_searchBar.showsSearchResultsButton=YES;
_aTableView.tableHeaderView =_searchBar;//加到table的表头上
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{//搜索框 值改变的时候
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{//点击键盘上搜索按钮时。
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{// 开始编辑的时候
修改cancel标题>>>>>
//此时 searchBar上的cancel按钮还没有加载所以无法修改标题,必须用延时函数。
[self performSelector:@selector(changeButtonTitle) withObject:nil afterDelay:0];
NSLog(@"1111");
}
-(void)changeButtonTitle{
UIView *suView=[_searchBar.subviews firstObject];
for (UIView *vi in suView.subviews) {
if ([vi isKindOfClass:[UIButton class]]) {
UIButton *btn=(UIButton *)vi;
NSLog(@"+++++++||%p",btn);
[btn setTitle:@"滚犊子" forState:UIControlStateNormal];
}
}
}
17、UISearchDisplayController(:NSObject) 搜索显示控制器 <需要三个代理> ///和UISearchBar一起用
//初始化默认的searchBar和默认的控制器
_disCtr=[[UISearchDisplayController alloc] initWithSearchBar:_searchBar contentsController:self];
_disCtr.delegate=self;//设置自身代理
_disCtr.searchResultsDataSource=self;//设置显示使用的tableView的代理
_disCtr.searchResultsDelegate=self;//设置显示使用的tableView的代理
//改变搜索框值得时候重新加载表
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString{
}
//改变搜索条件的时候重新加载表
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption{
//需要按照新的条件重新收集数据所以重新调用此方法
[self searchDisplayController:controller shouldReloadTableForSearchString:_searchBar.text];
return YES;
}
18、UIRefreshControl(:UIControl)下拉刷新:
1>>>>#pragma mark 下拉刷新方法 在UITableViewController控制器中
UIRefreshControl *refresh=[[UIRefreshControl alloc] init];//创建一个刷新控制器。
//设置刷新标题:
refresh.attributedTitle=[[[NSAttributedString alloc] initWithString:@"下拉刷新"] autorelease];
//下拉刷新调用方法:
[refresh addTarget:self action:@selector(biganRefresh) forControlEvents:UIControlEventValueChanged];
self.refreshControl=refresh;//把刷新控制器赋给tableViewCtr控制器的刷新控制器属性
[refresh release];
-(void)biganRefresh{//延迟函数模拟上传下载数据需要的时间
[self performSelector:@selector(laterXX) withObject:nil afterDelay:1];
}
-(void)laterXX{//数据传输完成调用方法停止刷新。
[self.refreshControl endRefreshing];
}
2>>>#pragma mark 下拉刷新方法 在UIViewController控制器中
做好一个UITableViewController 头文件导入UIViewController中创建对象。
并将 表控制器对象的View加到self.View身上。
ZYRefreshTableViewController *refesh=[[ZYRefreshTableViewController alloc]init];
[self.view addSubview:refesh.view];
19、UIImagePickerController(:UINavigationController)图片选择器
- (IBAction)buttonClick:(id)sender
{
//在创建选择器对象的时候,不用指定跟视图控制器
UIImagePickerController* picker = [[UIImagePickerController alloc] init];
picker.delegate = self;//设置代理 做代理可以控制模态取消的时候
picker.allowsEditing = YES;//编辑一张图片(裁剪一张图片,并选择)
//判断图片的来源
//如果摄像头能够利用
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{//打开摄像机
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
}else if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum])
{//相册能够被使用
picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
}else{//最后打开图库
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
[self presentViewController:picker animated:YES completion:nil];//模态弹出
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSLog(@"------>%@",info);
if (picker.allowsEditing)
{//如果编辑状态打开选择编辑完成的图片
_imageView.image = [info objectForKey:UIImagePickerControllerEditedImage];
}else{//如果编辑状态没打开可只写次方法获取图片。
_imageView.image = [info objectForKey:UIImagePickerControllerOriginalImage];
}
//模态消失
[picker dismissViewControllerAnimated:YES completion:nil];
}
A2xib>>>:
//返回一个数组 数组里面是Xib上的所有控件。
1、创建一个xib ,xib的file’sOwner 自定义类必须为 需要连线的类 否者无法连线;
2、获取xib里面 的View Bundle压缩包的意思 [NSBundle mainBundle]资源目录。
>>找到XIB的两个方法
I>//通过压缩包找到 压缩包里面的内容(XIB文件)
NSArray *xibArray = [[NSBundle mainBundle] loadNibNamed:@"NewItem" owner:self options:nil];//>>1、NewItem:创建的Xib的名称>>2、self需要设置xib的拥有者为 必须为需要连线的对象,否者连线后运行会崩溃>3、nil
II>//直接找XIB文件。
UINib *nib =[UINib nibWithNibName:@"NewItem" bundle:nil]; //nil 默认是mainBundle。
NSArray *xibArray = [nib instantiateWithOwner:self options:nil];
UIView *aView = (UIView *)xibArray.firstObject;
3、然后修改aView 的frame 图片等参数。并添加到self.view视图。
B动画方法:
1、播放动画图片的两种方法:
a>>_MainFJ.image = [UIImage imageNamed:[NSString stringWithFormat:@"plane%d.png",(j%2+1)]];//根据变量j 来确定图片的名字来动;
b>>bombView.animationImages = aArray;//aArray是一个数组里面放的Uiimge图片对象;
2、位移动画
1>>>、定时器 每次调用增加 位移的方法
可用来做圆周运动,曲线,各种规律的非规则动画
2>>>、放射变换
-(void)animationGoGoGo{
[UIView beginAnimations:nil context:nil];//UIView 静态方法,开始一个动画;
[UIView setAnimationDuration:1]; //animation 动画 duration 间隔时间;
//旋转到180度=pi/2(3.14/2);Rotation
CGAffineTransform c = CGAffineTransformMakeRotation(-3.1415926/2);
//相对原来旋转180度=pi/2(3.14/2);Rotate
CGAffineTransform a =CGAffineTransformRotate(_mainABaseImageView.transform, 3.1415926 / 2);
_mainABaseImageView.transform = a; //修改矩阵,仿射变换
[UIView commitAnimations]; //commit 提交
}
3>>>、循环云
for (int i=0; i<5; i++) {
UIImageView *aView = [[UIImageView alloc]initWithFrame:CGRectMake(-80, (arc4random()%10)*40, 60, 40)];
aView.image = [UIImage imageNamed:@"w_cloud.png"];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:arc4random()%10/10.0+1];//持续时间
[UIView setAnimationRepeatCount:MAXFLOAT]; //重复次数
[UIView setAnimationRepeatAutoreverses:YES];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
aView.center = CGPointMake(400, aView.center.y);
[UIView commitAnimations];
[self.window addSubview:aView];
}
3、翻页动画:
可对任何页面做动画,但最好是remove一个add一个或者//两个视图之间exchange;
[UIView beginAnimations:nil context:nil]; //翻页动作在动画之前 之后都可以。
[UIView setAnimationDuration:1];
//Transition 转换,变换 Curl 卷
//1.动画的样式
//2.要在哪个视图上做动画,一般是动画动作视图的父视图
//3.是否缓存
①和② 二选一;
① [[self.window viewWithTag:2] removeFromSuperview];//翻页动画完成的同时移除本页
②[_window exchangeSubviewAtIndex:0 withSubviewAtIndex:1];//两个页面之间的相互切换 0表示加在视图上的第一个页面,1表示加在视图上的第二个页面,以此类推;
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:_window cache:NO];//setAnimationTransition为0时 变换方式为渐变效果,此处有100多种方法 可以试一下。。
[UIView commitAnimations];//commit 提交
4、context上下文传参: 此处设置把 imgVIew对象传过去 用context传过去,下面用aaView接收 然后设置动画结束后要调用的方法;
>>>®®®[self.view bringSubviewToFront:aView]; //把子视图aView设置到最前面;
[UIView beginAnimations:nil context:imgView];
[UIView setAnimationDuration:1];
[UIView setAnimationDelegate:self];//设置代理(委托)
//设置动画结束以后调用的方法,我们只需要把context设置为imgView,系统就会调用此方法给传参数
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];//先写完下面方法 这里会自动提示;
[UIView commitAnimations];
-(void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{
UIView *aaVIew = (UIView *)context;
[aaVIew removeFromSuperview];
}
5、blok
[UIView animateWithDuration:.5 animations:^{…………………… }]
[UIView transitionWithView:self.view duration:.5 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{……………} completion:^(BOOL finished) {………………}];
6、layer层动画
//创建动画
CATransition* transition = [CATransition animation];
transition.duration = 0.5;
//动画类型(怎么进来的)
>>transition.startProgress = 0.5; //默认是0
>>transition.endProgress = 1;//默认是1
>>transition.type = @"cube”;//使用此方法就不需要下面两个了。
//@"cube" @"moveIn" @"reveal" @"fade"(default) @"pageCurl" @"pageUnCurl" @"suckEffect" @"rippleEffect" @"oglFlip"
transition.type = kCATransitionMoveIn;
//动画子类型(从哪个方位进来的)
transition.subtype = kCATransitionFromRight;
>>transition.fillMode = kCAFillModeRemoved;/默认不开启也行
kCAFillModeRemoved 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态
kCAFillModeBackwards 这个和kCAFillModeForwards是相对的,就是在动画开始前,你只要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始.你可以这样设定测试代码,将一个动画加入一个layer的时候延迟5秒执行.然后就会发现在动画没有开始的时候,只要动画被加入了layer,layer便处于动画初始状态
kCAFillModeBoth 理解了上面两个,这个就很好理解了,这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态.
>>transition.removedOnCompletion = NO;
[imageView.layer addAnimation:transition forKey:@"animation"];
imageView.image = [UIImage imageNamed:[self.array objectAtIndex:_currentIndex]];
c定时器和分线程:
1、定时器:每隔多长时间进行一次操作:
1>NSTimer *tim=[NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(boFang) userInfo:nil repeats:YES];
//1>每隔0.05秒 2>调用当前类对象的3>boFang方法4>不传参数,5>一直重复;
关闭定时器/废弃定时器: 定时器不能暂停 只能废弃,(用一个按钮 开启关闭一个定时器的方法是废弃—重建):
2>NSTimer *tim=[NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(bofang:) userInfo:imageView repeats:YES];
//1>每隔0.05秒 2>调用当前类对象的3>boFang方法并且把self传过去(也就是这里的tim)4>传参数(这里的参数可以是任意对象类型,我们传的是imageView对象 因为我们后面需要使用这个对象),5>一直重复;
传来的对象的调用方法:
-(void)bofang:(NSTimer *)tim{
[tim userInfo] 返回类型为传来的参数类型}
关闭定时器/废弃定时器: 定时器不能暂停 只能废弃,(用一个按钮 开启关闭一个定时器的方法是废弃—重建):
-(void)btnPress{
if(_tim){//判断定时器的指针是否存在(定时器的对象是否存在)
[_tim invalidate]; //定时器失效;
_tim=nil;//必须在定时器失效以后将定时器的指针至为空
}else{//或者开启定时器;
_tim=[NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(boFang) userInfo:nil repeats:YES];
}
//防止滑动竖着的scroollView是影响定时器的效果;
[[NSRunLoop currentRunLoop]addTimer:_aTimer forMode:NSRunLoopCommonModes];
}
2、分线程
//开启一个线程调用当前对象的update2方法,不传参数,当Updatess 方法执行完成后分线程就结束了
[NSThread detachNewThreadSelector:@selector(Updatess) toTarget:self withObject:nil];
-(void)Updatess{//分线程方法只调用一次
static int a=3;
while (YES) {
count++;
_aImageView.tag +=a;
if (_aImageView.tag<=0||_aImageView.tag>=320-44) {
a=-a;
}
//因为分线程中不能直接改变UI,所以要从分线程中调到主线程去修改UI
//回到主线程去执行其updateUi这个方法,yes表示先阻碍当前的分线程,等到主线程的refreshUI这个方法执行完成后,回到分线程
//NO表示不等到主线程完成后才回来
[self performSelectorOnMainThread:@selector(updateUi) withObject:nil waitUntilDone:YES];
[NSThread sleepForTimeInterval:.02];
}
}
-(void)updateUi{//修改Ui的主线程
_aImageView.image=[UIImage imageNamed:[NSString stringWithFormat:@"img%02d.png”,(_count/8)%2]];
_aImageView.frame=CGRectMake(_aImageView.tag, 0, 44, 44);
}
D代理-通知|传参:
1、Protocol协议代理委托的 创建步骤
1>>>系统
//系统 协议 代理的使用方法,1>>、点delegate进去 查找到尖括号<>的协议 ,.h中声明, 2>>、点击协议进去,查找需要使用的方法并复制出来在.m中实现 3>>、代理中设置委托代理的对象 一般是self (把self代理给系统的属性)。
2>>>自定义
例 协议:ZWProto.h; 委托方:ZWAppDelegate.m; 代理方:MyView.m
3> a>>、委托方 .m中导入代理方的头文件, b>>、并且把自身 赋予给代理方的属性如:myView.delegate = self; c>>、委托方.m中实现协议中的方法(方法中做需要做的事,比如:改变委托方的背景颜色);
1>创建一个协议的.h文件 里面声明要用的方法, 有@required(必须执行的)和@optional(选择执行的)两种
2><<代理声明属性不能用retain 只能用assign///并且声明的对象属性只能是id类型>>
a>>在做协议的两个文件的.h中 导入 协议头文件,
b >>委托(有需求的一方).h中声明id类型的属性,并且类型和属性间声明代理 如:@property (nonatomic,assign)id <ZWProto>delg;
c >>代理 .h中直接声明<ZWProto>////
4> 委托 通过自己的属性(代理属性)在自己的方法中 调用委托方的方法来执行委托方的方法例如:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.delegate doSomthing];}//self.delegate是代理方的属性 doSomthing是委托方的方法。
2、NSNotificationCenter 通知(观察者模式)
1>>>自定义通知
I>//在通知中心给自己注册一个观察者模式,并制定一旦受到通知调用设定的方法。
//Observer注册人 :@selector(jieShou:)接受消息后调用的方法(冒号为 传参NSNotification) name注册ID(识别暗号) object允许呼叫我的对象nil为任何人都可以(此处一般用来传参)*
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jieShou:) name:@"ID" object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self];//移除某个对象的多个观察者模式
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"ID" object:nil];//移除特定的一个观察者模式。
-(void)jieShou:(NSNotification *)notti{
UITextField *str= [notti object];
UITextField *str2=[notti userInfo];
}
II>//在另外一个控制器中给注册过的控制器发送通知。
- (IBAction)goBackMoTai:(UIBarButtonItem *)sender {
//object(任意对象) 和 userInfo(字典) 都可以传参。 如果注册对象设置了object,此处object必须和注册的一致才能通知成功。
[[NSNotificationCenter defaultCenter] postNotificationName:@"ID" object:nil userInfo:@"ggggjjj"];
}
2>>>系统通知
//系统观察者模式 name(从系统中选一个)是 系统通知Observer调用selector方法的时间 object为空时系统才能调用。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dododo) name:UIApplicationDidEnterBackgroundNotification object:nil];
E数组和字典
1>>>>>数组:
_miMaArray isEqualToArray:_bigButtonArray;//两个数组是否相等
if (![_bigButtonArray containsObject:@"-1"]) {……} 如果 数组不包含@“-1”对象,返回一个BooL类型;
1>//不可变数组
不可变数组转可变数组
NSMutableArray* mutArr=[[NSMutableArray alloc] initWithArray:arr];
NSArray *arr2=[NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"5", nil];
NSArray *arr4=@[@"1",@"2",@"3",@"4",@"5"];//等同于arr2不等同于arr
//可变数组
NSMutableArray *arr3=[[NSMutableArray alloc]init];
for(int i=0;i<100;i++){
[arr3 addObject:[NSString stringWithFormat:@"你好%d",i+1]];
}
for(int i=0;i<100;i++){
//只针对可变数组,因为不可变数组初始化后不能再对其赋值了
arr3[i]=[NSString stringWithFormat:@"你好%d",i+1];
}
2>数组的排序
排序时要保证数组内对象的类型一致,如果是自定义排序,系统会根据内部对象的类型,去调用此类对象的 定义的方法进行排序。
>>数组系统方法的排序
1>>//sortedArrayUsingSelector是NSArray的方法,通过这个方法会返回一个新的数组,这个数组是经过老的数组排过序的
2>>//排序只能对于10进制的数字进行排序,简单地1234和abcd
NSArray *arr=[[NSArray alloc] initWithObjects:@“e”,@“b”,@“d”,@“c”,@“a”, nil];
NSArray *arr0=[arr sortedArrayUsingSelector:@selector(compare:)];//compare: 为系统方法调用即可不需要实现。
返回的结果为:arr0=[[NSArray alloc] initWithObjects:@"a",@"b",@"c",@"d",@"e", nil];
数字>>>排序结果 为 1 11 111 2 21 22 222 3 31.
字符串用此方法排序是正常的。
>>数组的自定义排序 (此方法可以排序任何类型)。
第一步>>>>>>扩充类
@implementation NSString (myString)//扩充类别(和需要重新排序的对象类一样)
-(NSComparisonResult)myCompare:(NSString *)str{
if ([self intValue]>[str intValue]) {//根据数组中对象的一个属性或特征对数组重新排序
return NSOrderedDescending;//降序
}
else if([self intValue]<[str intValue]){
return NSOrderedAscending;//升序
}
else{
return NSOrderedSame;//相同
}
}
第二部>>>>>>数组排序方法 调用扩充类中声明的方法
NSArray *aArray2=[aArray sortedArrayUsingSelector:@selector(myCompare:)];
//@selector(myggg) //@selector为全局方法(整个.m中所有类的方法/或者导入头文件的类的方法都可调用)必须保证谁的方法谁调用。
@end
3>//数组的遍历
//普通遍历
for(int i=0;i<[arr count];i++){
NSLog(@"%@",[arr objectAtIndex:i]);
}
//遍历偶数
for(int i=0;i<[arr count];i+=2){
NSLog(@"%@",[arr objectAtIndex:i]);
}
//从中间(5)开始遍历
for(int i=0;i<[arr count];i++){
NSLog(@“%@“,([arr objectAtIndex:(i+5)%[arr count]]);
}
//泛型遍历
//数组中放置的是什么数据类型 *变量名 in 数组
//for循环的次数为数组的长度,这种遍历模式for循环的次数不可控
for (NSString *str in arr) {
NSLog(@"%@",str);
}
3>C语言数组
@interface ZWQQViewController (){
bool _OrOpen[3];//声明一个布尔类型的数组,这个数组有三个内容。
}
_OrOpen[1]=!_OrOpen[1];//改变索引为1的位置的内容。
2>>>>字典
字典的创建
NSDictionary *dic=[[NSDictionary alloc]initWithObjectsAndKeys:@"qw",@"a",@"er",@"t",@"g",@"c",@"h",@"d",@"5",@"e",nil];
NSDictionary *dic2=[NSDictionary dictionaryWithObjectsAndKeys:@"1",@"a",@"2",@"b",@"3",@"c",nil];
NSDictionary *dic3=@{@"a": @"1",@"b":@"2",@"c":@"3"};
//只要字典里内容确定,不再改动,每次调用allKeys这个方法,返回的顺序是乱序,但是顺序不会变
[arr sortedArrayUsingSelector:@selector(compare:)]//重新顺序排列keys数组
//往可变字典中 添加/替换内容。
[dic4 setObject:@"1" forKey:@"a"];
3>>>>从自己创建的plist中获取数组或者字典
[NSBundle mainBundle]//获取程序文件
NSString *path =[[NSBundle mainBundle] pathForResource:@"shop.plist" ofType:nil];
>//从列表获取数组(列表必须是数组类型)
NSArray *aArray = [NSArray arrayWithContentsOfFile:path];//file必须是全路径
>//从列表获取字典(列表必须是字典组类型)
NSDictionary *Dic =[NSDictionary dictionaryWithContentsOfFile:path];
F— MVC
模型>>
//模型的封装可以用 静态方法(+号方法中 alloc并且返回一个对象)传入对象。////或者用实例方法(-号方法)初始化方法With传入需要设置的参数。
MVC常用步骤A>>
1、创建模型 设置好模型初始化内容(plist转模型对象时使用)。
2、ctr中根据遍历plist数组获得的字典 创建模型对象并加入新数组(类调用 “+”方法创建)。
3、创建一个继承于UITaleViewCellcell对象 并设置view的样式 /创建一个属性为模型对象,根据此属性设置cell的样式。
4、使用时传递 模型到cell中 cell.modo=_modoArray[indexPath.row] 重新set modo设置数据和位置信息。
MVC常用步骤B>>
1>新建一个UItableViewCell的子类————WeboCell
2>在创建cell的时候(initWithStyle :reuseIdentifier:方法中)添加cell内部需要使用的子控件
(注意:只管创建添加子控件,先不要去管子控件的位置和尺寸)
3>新建一个模型类—————Weibo,增加对应的数据属性。
4>给WeiboCell增加一个Weibo模型属性,在拿到Weibo模型数据的同时设置子控件的属性
5>重新setWeibo:方法,在这里面取出Weibo模型数据的数据显示到子控件上。
G内存管理
内存法则 >>>>>谁创建 谁管理。
OC内存管理遵循“谁创建,谁释放。谁引用,谁管理”的机制,当创建或引用一个对象的时候,需要向它发送alloc copy retain 消息,当释放该对象时需要发送release消息,当该对象引用计数为0时,系统将释放该对象,这是OC的手动内存管理机制;iOS5.0之后OC又提供了自动管理机制,ARC(automatic reference counting),管理机制跟手动管理机制一样,只是不再需要调用 retain release autorelease;它是编译时特性,当你启用ARC时,在适当的位置插入release和autorelease;它引用了strong和weak 关键字,strong修饰的指针变量指向对象时,当指针指向新值,或者指针不再存在时,相关联的对象就会自动释放,而weak修饰的指针变量指向对象,当对象的拥有者指向新值或者不存在时weak修饰的指针则自动置为nil,这是ARC管理机制;
arc和非arc混编:
【解决方案】
Xcode 项目中我们可以使用 ARC 和非 ARC 的混合模式。
如果你的项目使用的非 ARC 模式,则为 ARC 模式的代码文件加入 -fobjc-arc 标签。
如果你的项目使用的是 ARC 模式,则为非 ARC 模式的代码文件加入 -fno-objc-arc 标签。
添加标签的方法:
- 打开:你的target -> Build Phases -> Compile Sources.
- 双击对应的 *.m 文件
- 在弹出窗口中输入上面提到的标签 -fobjc-arc / -fno-objc-arc
- 点击 done 保存
I>.MRC(人工引用计数),手动管理内存
static 声明的对象即使有alloc,也不需要手动释放。
[vi retainCount]//内存的引用计数
1、全局类型的变量初始化的时候 _变量名=[[alloc]init],最后在delloc里面释放,如果一些变量必须要用静态方法创建,那么可以_变量名=[[类 静态方法]retain],在delloc释放
2、局部类型的变量初始化的时候如果是alloc创建的,那么在使用完成后release,如果是类调用静态方法创建的,不管他
3、使用委托时,如果出现了循环引用,不能用retian必须用assign
全局变量
//只要是我们自己alloc new retain copy这些内存的时候,他的引用计数会增加,增加的这部分值 只有我们自己release的时候才会减少,系统不会管到这部分引用计数
//release是异步过程,release的执行结束时间不可控,比较安全的写法是在内存释放完成后把指针置为nil
//空指针可以做任何事情,并且可以无限release
//内存管理谁创建谁释放
//放入数组、放入字典、放入导航器、uialertView show的时候系统都会让其引用计数增加,当从数组中移除、导航其中移除、uialertView点击按钮消失时候系统会让其引用计数减少
//当一个视图放在另一个视图上的时候,系统会让其引用计数增加
[self.window addSubview:vi2];//此处vi2所指向的内存的引用计数会增加1。
UIView *vi=[[UIView alloc]init];
野指针: 指向一个已删除的对象或未申请访问受限内存区域的指针。与空指针不同,野指针无法通过简单地判断是否为 NULL 避免,而只能通过养成良好的编程习惯来尽力减少。对野指针进行操作很容易造成程序错误。
野指针:指针指向一块内存地址,如果此内存地址被release掉但是 指针没有nil,此时指针为野指针。
野指针有内存地址编号,没有真实内存,用此对象操作 运行会崩溃。
//当一个视图从父视图中移除的时候,系统会让其引用计数减少
[vi2 removeFromSuperview];//此处vi2所指向的内存的引用计数会减少1。
//获取一个指针所指向的内存的引用计数
NSLog(@"%d",[vi retainCount]);
//当一块内存是通过一个类调用静态方法创建的时候,它的引用计数也为1,只不过这块是自动释放的
UIButton *btn=[UIButton buttonWithType:UIButtonTypeSystem];
局部变量
//局部变量是对象类型如果是你alloc new copy retain 必须要在使用完成后release
//局部变量是对象类型如果是类调用静态方法创建时候,不能写release
//全局类型的变量因为我们要在多个方法中进行访问,所以这个对象不能够是自动释放的,需要手动释放(例如在dealloc中 release)
>>copy的深拷贝和浅拷贝
//因为arr描述为copy,当_arr指向一个可变的内存的时候,就是深拷贝,深拷贝相当于开辟新的内存地址,内容和老的相同,_arr指向新的内存,并让其引用计数+1,当_arr指向一个不可变的内存的时候,就是浅拷贝,浅拷贝相当于retain,_arr指向这块内存地址,并让其引用计数+1
>>dealloc
//当一个类的对象over的时候 ,就会调用其delloc方法,在这个方法里面要去释放属性
-(void)dealloc{
//先释放属性,在调用父类的dealloc
[_myVi release];
[_myBtn release];
[super dealloc];
}
Z其他:
删除缓存 资源库-> Developer->Xcode->derivedDate(删除此文件夹即可)
1、判断一个指针是否是UIbutton类 [btn isKindOfClass:[UIButton class]]
2、 NSString:
常量字符串 内存地址相同,拼接字符串,和变量字符串内存地址不相同。
- (NSString *)uppercaseString;//全部大写。
- (NSString *)lowercaseString;//全部小写。
- (NSString *)capitalizedString;//首字母大写。
[string hasSuffix:@"是个"];以什么结尾
[string hasPrefix:@"是个"];以什么开头
//[str uppercaseString] 字符串转大写
I>判断B字符串在A字符串中的位置
返回一个NSRange(长度和索引位置) 长度为0 /或者.location不存在 A不包含B。
NSRange aRange = [[str uppercaseString] rangeOfString:[searchBar.text uppercaseString]];
if (aRange.length>0) {……}
if ([str123 rangeOfString:ttt].location!=NSNotFound) {……}
II>//字符串 字符串拼接
[NSHomeDirectory() stringByAppendingString:@"/Documents/arr.plist"]
NSString *str=[NSString stringWithFormat:@"ios|good|really"];
III> //字符串 分割。 根据一个特殊的分割标"|"示符进行分割
//字符分割返回一个数组,是分割完成的多有字符串。
NSArray *strArr=[str componentsSeparatedByString:@"|"];
NSArray *aa2 =[aa componentsSeparatedByString:NSLocalizedString(@",", nil)];//以“,”将字符串拆分成数组
IV>//字符串是否相同
if ([registName isEqualToString:@“”])
//判断两个字符串是否相等,不能使用==,使用等号是判断两个对象是否是一个对象,也就是是否是一个内存地址。
//判断字符串的内容是否相同应该使用nsstring的isEqualToString:方法
V>width———获取显示的字符串宽度
NSDictionary *dic=[NSDictionary dictionaryWithObjectsAndKeys:aButton.titleLabel.font,NSFontAttributeName, nil];
CGSize aSize = [[aButton titleForState:UIControlStateNormal] sizeWithAttributes:dic];//获取字符串size需要字典。
_buttonIndentifier.bounds=CGRectMake(0, 0, aSize.width,2 );
VI>删除字符串中的某个字符
NSRange range = [aString rangeOfString:@" "];
while (range.location != NSNotFound)
{
[aString deleteCharactersInRange:range];
range = [aString rangeOfString:@" "];
}
VII>替换字符串中的某些字符
string = [string stringByReplacingOccurrencesOfString:@" " withString:@""];
VIII>只获取一个字符串中的数字
-(NSString *)setString:(NSString *)str{
NSString *str123 = @"0123456789";
NSMutableString *multStr=[NSMutableString string];
for (int i=0; i<str.length; i++) {
NSString *strChar=[NSString stringWithFormat:@"%c",[str characterAtIndex:i]];
if ([str123 rangeOfString:strChar].location !=NSNotFound) {
[multStr appendString:strChar];
}
}
return multStr;
IX> ASCII键盘码值转字符串
unichar cc=i;//cc为无符短整型 i 为int数字(可以查询AscII知道字符对应的值)。
//可通过以下两种方式的一种转换成字符串来使用
NSString* info = [NSString stringWithCharacters:&cc length:1];
NSString* info = [NSString stringWithFormat:@"%c",cc];
X>除一个字符串两端的空格和换行
NSString* string = @" fajdfkdkasf ";
string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
3. 初始化标准格式 //为什么super —>self 因为 我们不知道父类坐了什么事情, 所以 初始化一下父类的事情 然后再做自己的事情;
- (instancetype)init
{ //创建对象 并且初始化的时候会调用此方法。
self = [super init];
if (self) {
<#statements#>
}
return self;
}
4、键盘 下去或调出来————第一响应者;
键盘高度216.
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event //此方法不需要任何调用,点击背景屏幕即生效
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{//让父视图取消编辑。所有键盘下去;
[self.window endEditing:YES] }
[_textField resignFirstResponder]; //放弃第一响应者。_textField为调用这个方法的对象。
[self.view endEditing:YES];//放弃第一响应者。
[_textField becomeFirstResponder];//成为第一响应者。_textField为调用这个方法的对象。要成为第一响应者的人;
5、数字类字符串和 数字之间的转换:
[NSString stringWithFormat:@“%.2d”,5] ->(5.00);
[NSString stringWithFormat:@“%02d”,5] ->(05);
//字符串转float;
String *content = _textField.text; //(_textField.text)为字符串类数字的 变量;
float salary = [content floatValue]; //salary --工资;
//数字转字符串;
NSString *str = [[NSString alloc] initWithFormat:@"%.2f",tax]; //tax数字的变量;
6、多个按钮绑定同一个方法:
//多个按钮可以绑定同一个方法
//按钮在绑定方法的时候,可以把自己的对象作为参数传递给绑定的方法
//多个按钮绑定同一个方法的时候,可以加以区分。区分的方式有两种:1,把button按钮设置一个tag值,区分各自的tag值。2,区分各自的内存地址
//note:一个按钮只能绑定一个方法
//用一个带参数的方法,调用方法的时候 冒号后面为空时 参数为调用者自己;
-(void)dongyidong:(UIButton *)aButton;//(按钮调用 dongyidong:)
{ if (aButton.tag ==1) {
NSLog(@"button————————1动了!");
return; }
if (aButton.tag ==2) {
NSLog(@"button————————2动了!");
return; }
}
7、循环
1>For循环:
里面不能用全局变量;
rerun//跳出当前方法 break//跳出当前循环 continue//跳出循环的当次执行;
//i++是一个自加,每次把自身加1相当于i= i+ 1;
//i++和++i是有区别的:b=i++ 先把 i 的值赋给b i 再加1; b=++i 先加1 再把结果赋给b;
//i++ 是一个表达式
for (int j =0; j<3; j++) {
for (int i =0 ; i<3; i++) {
UIButton *buttonJSQ1 = [UIButton buttonWithType:UIButtonTypeCustom];//创建按钮
buttonJSQ1.frame = CGRectMake(20+i*80, 100+j*60, 60, 40);
NSString *str = [NSString stringWithFormat:@"%d",i+j*3+1] ;//把数字转成字符串 给下面设置标题的方法中用
[buttonJSQ1 setTitle:str forState:UIControlStateNormal];
buttonJSQ1.tag = [str intValue]; //[str intValue] 字符转成int数字;
buttonJSQ1.backgroundColor = [UIColor lightGrayColor];
[_window addSubview:buttonJSQ1];
}
}
2>while循环
while( ){ } 小括号内 为真时 无限循环执行大括号内容, 小括号为假时跳出;
8、static 和 红定义的使用
I >>static 声明的变量 只初始化一次 static int =0;
方法和方法之间声明的变量尽量加上satatic 作用本类中;不加的话作用整个软件,再其他类中用 extern重新声明一下就可以用;
II >>红定义 :可以定义一个常量(数字或者 字符串) #define XXrowHeight 30
可以定义一串代码(自能定义一行)
可以传参 #define K_rowHeight(info) info不能和系统关键字重复。
如果声明在.h头文件前 ,或者声明在Supproting FIles ->XXX-Prefix.pch 中 则为整个程序的全局变量。
9、比较两个rect 是否重叠;
while (CGRectIntersectsRect(aButton.frame, theOtherButton.frame))重叠 返回YES . 不重叠返回No;
10、字符串/数组/颜色是否相等:
== 数字或者内存地址
isEqual 两个对象是否相同
isEqualToString 字符串内容是否相同
isEqualToArray 数组内容是否相同
//颜色是否相同
if (CGColorEqualToColor(lastButton.backgroundColor.CGColor, [UIColor blackColor].CGColor)) {
blckCount+=1;}
//两个数组是否相等
_miMaArray isEqualToArray:_bigButtonArray;
11、随机函数/取余运算;
arc4random()%256 //无限大的随机值 对256取余,使随机范围在0—255之间;
取a—b得随机值—> arc4random()%(b-a+1)+a;
12、frame、bounds、center的区别:
//frame是相对于其父视图而言的
//bounds是相对于自身而言的,bounds的xy是设置自己坐标系的左上角坐标,会影响其子视图
//一般使用bounds不设置x和y只设置宽和高
//center是相对于其父视图而言的,是CGpoint类型
13、点击背景屏幕触发事件;这三个方法不需要调用, 可直接使用
一个类一个touchbegan 每个类中只能接受自己的类的touchbegan 可以通过 新建类的方法来用tachbegan拦截 事件,然后使用代理来控制其他类的方法,例如第一个项目的 新闻页面,点击页面最大化视图;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.window endEditing:YES] } //点击 背景屏幕是启用;
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
}//在屏幕上滑动是启用;
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
}//点击 离开背景屏幕是启用;
14、找到主Window的三种方法:
1>>因为委托对象的window是应用程序的主窗口,所以我们通过应用程序的对象调用keyWindow也可以找到手机屏幕上显示的widow
ZYRegViewController *reg=[[ZYRegViewController alloc]init];
<<[UIApplication sharedApplication].keyWindow.rootViewController=reg;//调出主视图(_window)把自己创建出来的视图加载到上面
2>>找到应用程序的委托对象,这个对象的window就是手机屏幕上显示的window
#import “ZYAppDelegate.h"
ZYRegViewController *reg=[[ZYRegViewController alloc]init];
<<ZYAppDelegate *app=[UIApplication sharedApplication].delegate;//返回当前应用程序通过代理找到,主窗口(window)的对象
app.window.rootViewController=reg;
3>> self.window;
15、创建一个页面控制的对象。 把他挂载到主页面 de 3种加载方法:
ZWViewController *page1 = [[ZWViewController alloc]init];
self.window.rootViewController = page1;
[self.window setRootViewController:fire];
[self.window addSubview:ZWFire.view];
16、九宫格 算法
//for循环i从0开始,次数为行数*列数
//单次for循环排列n宫格,x坐标:列间隔+(列间隔+宽)*(i%列数)
//单次for循环排列n宫格,y坐标:行间隔+(行间隔+高)*(i/列数)
封装代码:
-(void)drawNGongGe:(int)rowNum andCol:(int)colNum andWidth:(float)width andHeight:(float)height{
float col=([UIScreen mainScreen].bounds.size.width-width*colNum)/(colNum+1.0);
float row=([UIScreen mainScreen].bounds.size.height-height*rowNum)/(rowNum+1.0);
for(int i=0;i<rowNum*colNum;i++){
UIButton *btn=[UIButton buttonWithType:UIButtonTypeSystem];
btn.frame=CGRectMake(col+(col+width)*(i%colNum), row+(row+height)*(i/colNum), width, height);
btn.backgroundColor=[UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:1];
btn.titleLabel.font=[UIFont systemFontOfSize:8];
[btn setTitle:[NSString stringWithFormat:@"%d",i+1] forState:UIControlStateNormal];
[self.view addSubview:btn];
}
}
17、tag和subviews
>>tag的用法:
1>通过tag的值判断执行哪个方法。例如计算器键盘;
2>通过tag 和父视图 调用父视图上的子视图;
通过[View viewWithtag……]来寻找子视图 会遍历自身、子视图、孙视图、孙孙视图 等等,直到找到第一个符合要求的对象;
>>subviews
通过subviews寻找子视图,只会寻找当前对象的子视图内容。
self.window.subviews 返回一个数组(数组是视图上所有子视图)。
18、三目运算:
int a=5,b=3;
//三目运算符
int c=a>b?1:2;
//相当于
if(a>b){
c=1;
}else{
c=2;
}
19、做球一个一个出来的 圆环动画:
for (UIImageView *bImageView in _bArray) {//数组的遍历。 把小球从数组中一个一个拿出来。
if (ss%3==0 && bImageView.tag==555) {//设置小球拿出的 频率, 频率太高 小球全部练成一串 不分散。
bImageView.tag=0; //取出一个小球修改tag值 ,供下面if调用
break;
}
if (bImageView.tag!=555) {
bImageView.tag +=10; //tag值表示角度, 让角度每次调用加上一定值就动起来了。如果没有可用的tag自己创建一个。
bImageView.center = CGPointMake(_sunImageVIew.center.x+90*cos(M_PI/180*bImageView.tag), _sunImageVIew.center.y-80*sin(M_PI/180*bImageView.tag));
}
}
20、交叉导入问题:
交叉导入是在 .h 中相互导入头文件,会报错。 解决方法是删掉一个头文件的导入, 改成@class; 在.m中导入#import “man”
>>@class man;是告诉系统 man是一个类不要报错了,但系统不知道man中的属性; 所以要在.m中再导入;
21、import 和@class
import 导入头文件后 会编辑所有的类和方法, @class 只声明一个类,不管里面的任何东西。
22、 switch和if
//switch创建对象的时候必须要加{},否则会编译不通过
switch (btn.tag) {
case 1:{…………… }
break;
case 2:
{…………………………}
break;
default:
break;
}
23、//延迟执行方法pickerView是传参数用的,前面方法红有冒号这个才管用;
[self performSelector:@selector(refreeash:) withObject:pickerView afterDelay:.1];
-(void)refreash:(UIPickerView *)pickerView{…………};
24、viewDidLoad和viewWillAppear
- (void)viewDidLoad//只有第一次创建此页面时调用此方法;
{ //先执行Didload 然后执行WillAppear
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated{//每次回到此界面都会调用此方法;(系统和方法要初始化)
//先执行Didload 然后执行WillAppear
[super viewWillAppear:YES];
}
25、单例模式
[UIApplication sharedApplication];
//单例模式,任何时候都返回同一个对象
自定义单例模式>>
static DataBase *db=nil;
+(DataBase *)shareDataBase{
if(!db){
db=[[DataBase alloc] init];
}
return db;
}
26、@selector(myggg) //@selector为全局方法(整个.m中所有类的方法/或者导入头文件的类的方法都可调用)必须保证谁的方法谁调用。
27、双指针给参数复制(逆向赋值)
//常规状态下再加一个”*”指针可以反向利用形参给实参赋值。
int a=100;
int *b=&a;//&a是获取a的内存地址。
*b=88;
[self doTest:b];
-(void)doTest:(int *)num{
*num=89;
}
28、NSFileManager(:NSObject)文件管理类
copy复制文件
//copy数据库到沙盒
NSString *sourcePath=[[NSBundle mainBundle]pathForResource:@"database.sqlite" ofType:nil];
NSString *desPath=[NSHomeDirectory() stringByAppendingPathComponent:@"Documents/orderDishDateBase.sqlite"];
if (![[NSFileManager defaultManager] fileExistsAtPath:goalPath]) {
[[NSFileManager defaultManager] copyItemAtPath:sourchPath toPath:goalPath error:nil];
};
//写文件和写文件夹
[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
[[NSFileManager defaultManager] createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
- (BOOL)fileExistsAtPath:(NSString *)path;//文件文件夹是否存在。
- (BOOL)isReadableFileAtPath:(NSString *)path;//路径是否可读。
- (BOOL)isWritableFileAtPath:(NSString *)path;//路径是否可写。
- (BOOL)isExecutableFileAtPath:(NSString *)path;//路径下文件都否可执行
- (BOOL)isDeletableFileAtPath:(NSString *)path;//路径下文件是否可删除。
- (NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error NS_AVAILABLE(10_5, 2_0);//获取文件属性
29、程序之间的跳转
(I)切换到浏览器
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.baidu.com"]];
(II)自己写的应用之间的切换
>1.设置url
在xx-info.plist文件里面设置一些属性
(1).点击“+”或者(右键—>add row)
(2).新的一行的key:URL Types
(3).打开Item0,设置RUL identifier为:一般倒写公司域名
(4).在Item0上点击“+”添加一行。
(5).在新添加的行上设置key为:URL Schemes
(6).打开URL Schemes里面的item0设置url:自己制定一个就可以了
>2.跳转
//1.创建url
NSURL* url = [NSURL URLWithString:@"myUrl1://"];
//2.判断能否打开
if ([[UIApplication sharedApplication] canOpenURL:url])
{
//3.打开
[[UIApplication sharedApplication] openURL:url];
}
30、判断此方法是否可以被调用
if ([self.delegate respondsToSelector:@selector(imageViewScrollToLeft:)]) {
//如果能调用,我再来调用
}
32、类别:对原有类的一个扩充
类的扩展 重新声明一下原有类的.h文件 用来扩充属性(.m不能这样扩展,所以扩充方法只能用类别)。
@interface 原有 ()
@end
>>>>>>//类别的声明方法
/*
@interface 原有类 (类别的名字)
@end
*/
/*
>>>>>>类别的三大作用:
1.扩充原有类的方法(不能直接扩充属性)
注意:类别不是新的类,只是对原有类的一个扩充。类别不会破坏原有类的内部的机构。不仅可以扩充类方法还可以扩充对象方法。可以间接的扩充属性(@property int age; 会生成一个带下划线的变量:_age)。
类的扩展:轻轻量(10KG) 只扩充属性(只有.h)。
类别:轻量级(50KG) 不是一个新类
继承:重量级(100KG) 是一个新类
2.声明私有方法 在.m中
@interface 类名 ()
//声明私有方法
@end
3.分散类的实现
把一个类按功能分类
*/
>>>>>>>>//建议:一般不要扩充原有类原有的方法,因为系统会分不清该调用哪个方法。
33、对象按照预定格式输出
- (NSString* )description
{
return [NSString stringWithFormat:@"name = %@ tn = %@ age = %@",self.name,self.trueName,self.age];
}
34、修改类的名称:
Edit->refactor->rename。
35、viewDeload里面做动画有些动画会出问题, 用延迟函数 延迟0秒解决。
80、touch事件
BOOL orMove;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
// UITouch *touch=[touches anyObject]; //1.找到touch事件
// CGPoint point= [touch locationInView:self.window];//2.根据touch事件,获取点的坐标
UITouch *touch=[touches anyObject];
if([touch view]==_planeView){
_location= [touch locationInView:_planeView];
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
/*
//获取手指在屏幕上的坐标
CGPoint point=[[touches anyObject] locationInView:self.window];
//判断此时手指在屏幕上的坐标是否在飞机上,也就是说手指是否按在飞机上,如果是的话,改变飞机的中心点坐标到手指的位置上
if(CGRectContainsPoint(_planeView.frame, point)){
_planeView.center=point;
}
*/
UITouch *touch=[touches anyObject];
if([touch view]==_planeView){
CGPoint point= [touch locationInView:_planeView];
float dx=point.x-_location.x;
float dy=point.y-_location.y;
CGPoint center=_planeView.center;
center.x+=dx;
center.y+=dy;
_planeView.center=center;
orMove=YES;
}
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch=[touches anyObject];
if([touch view]==_planeView){
if(!orMove){
[self doBoom];
}
orMove=NO;
}
}