现在的位置: 首页 > 综合 > 正文

iOS开发笔记

2013年12月02日 ⁄ 综合 ⁄ 共 16560字 ⁄ 字号 评论关闭
文章目录

0 编程习惯

在viewDiUnload中重置变量为nil

- (void)viewDidUnload {

    [super viewDidUnload];
	self.mapView = nil;
	self.infoButton = nil;
    self.tocViewController = nil;
    if([[AGSDevice currentDevice] isIPad])
        self.popOverController = nil;
}

1 为按钮控件增加事件处理

方法1:从storyboard中拖动按钮到controller.h中,选择Action,然后输入操作方法名即可,在controller.h controller.m中都有自动生成的代码

或者事先在.h文件中写好Action操作函数,然后在xib文件中拖动控件到File's owner上,注意File's owner的类

方法2:选择Outlet,然后输入Name,然后在controller.m中手动添加处理方法

    //为按钮绑定事件
    [_btnLayers addTarget:self action:@selector(changeLayerAction:) forControlEvents:UIControlEventTouchUpInside];
-(void) changeLayerAction:(id)sender
{   
    
//    UIAlertView *alertView=[[UIAlertView alloc] initWithTitle:@"温馨提示"
//                                                      message:@"我被单击了!"
//                                                     delegate:nil
//                                            cancelButtonTitle:@"OK"
//                                            otherButtonTitles:nil];
//    [alertView show];
  
   
}

2 增加委托

方法1 控件的storyboard界面方式。按住control键退动文本框到界面黄色标记的按钮上,点击delegate选项,然后在controller.h controller.m中分别添加代码

@interface dcecViewController : UIViewController<UITextFieldDelegate>
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    if (textField==self.textField1 || textField==self.textField2) {
        
        [textField resignFirstResponder];
    }
    return YES;
}

 方法2,在代码中设置

在controller.h中

@interface dcecViewController : UIViewController<UISearchBarDelegate>

    //搜索框
    _searchBar=[[UISearchBar alloc]initWithFrame:CGRectMake(0,0,320,41)];
    _searchBar.delegate=self;
    _searchBar.placeholder=@"名字 ";
    _searchBar.showsSearchResultsButton=YES;
    [_mapView addSubview:_searchBar];
//SearchBar协议的方法实现
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
   
}

3 引入第三方库

http://mobile.51cto.com/iphone-407056.htm

方法一:直接复制所有源文件到项目中

这种方法就是把第三方类库的所有源文件复制到项目中,直接把所有.h和.m文件拖到XCode项目中即可。如果第三方类库引用了一些系统自带类库,那么在项目中还需要额外引用那些类库。

如果当前的项目启用了ARC,而引用的第三方类库未使用ARC,那还需要在项目信息的Targets – Build Parses里找到第三方类库的.m文件,并为它们加上-fno-objc-arc标记。

而对于在未启用ARC的项目用引用使用了ARC的第三方类库,则需要为第三方类库的.m文件加上-fobjc-arc标记。

另外,在源代码中可以通过一个编译器指令__has_feature(objc_arc)来检测项目是否使用了ARC,具体见http://clang.llvm.org/docs/LanguageExtensions.html#langext-has-feature-has-extension

方法二:引用.xcodeproj生成静态链接库并引用

首先,在XCode中把第三方类库的.xcodeproj文件拖到当前项目中;如果第三方类库封装了一些资源在.bundle文件里,那么.bundle文件需要和.xcodeproj一起拖到项目中。

然后,在项目的Targets – Summary – Linked Frameworks and Libraries或者在Targets – Build Phases – Link Binary With Libraries添加第三方类库生成的静态链接库引用。

接着,还需要在Targets – Build Settings – Search PathsUser Header Search Paths参数中加入第三方类库的头文件路径,可以是绝对路径如:/Users/libpath,也可以是相对路径(相对于当前项目文件夹)如:../**。

最后,有些静态链接库引用进来可能还需要增加一些标记,在Targets – Build Settings – LinkingOther Linker Flags参数中增加:-Objc–all_load这一类标记。

通过以上几步,一般都可以成功编译。

当然还有一些例外的情况:

  1. 当前项目和第三方类库同时使用了另外的一些第三方类库,这个时候还需要额外做一些处理才能成功编译:在引用的第三方类库的.xcodeproj项目 – Targets – Build Phases中的Compile SourcesCopy Headers把重复的.m和.h文件移除掉。
  2. 第三方类库引用的一些系统自带类库,如果项目中没有引用,也可能会引起编译错误,这时还需要在项目中引用第三方类库引用的一些系统自带类库。比如:第三方类库引用了QuartzCore.framework,而项目中未引用QuartzCore.framework则可能引起编译错误,就需要在项目中也引用QuartzCore.framework。

4 UITableviewCell添加自定义控件

//ManagerLayers.h文件
#import <UIKit/UIKit.h>

#import "MyCell.h"

#define NotificationLayerChange @"NotificationLayerChange"

@interface ManagerLayers : UITableViewController
{
    NSArray *layers;
}
@property (strong, nonatomic) IBOutlet MyCell *tvc;

@property (strong,nonatomic) UIPopoverController *container;
@property NSInteger selIndex;

@end



//ManagerLayers.m文件
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //方法1,在代码中增加一个子视图
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

        //标签
        UILabel *label=[[UILabel alloc]init];
        label.frame=CGRectMake(1,0,60, cell.contentView.bounds.size.height);
        label.tag=1;
        [cell.contentView addSubview:label];
        
        //slider
        UISlider *slider=[[UISlider alloc]initWithFrame:CGRectMake(65,10,150,cell.contentView.bounds.size.height)];
        slider.minimumValue = 0;//指定可变最小值
         slider.maximumValue = 100;//可变最大值
        slider.value = 50;//指定初始值
        slider.tag=2;
        [slider addTarget:self action:@selector(sliderAction:event:) forControlEvents:UIControlEventValueChanged];//设置响应事件
        [cell.contentView addSubview:slider];
    
        //开关类型
        UISwitch *switchview = [[UISwitch alloc] initWithFrame:CGRectZero];
        switchview.tag=3;//[indexPath row];//在后面可以直接使用这个tag来确定是触发了哪个cell
        [switchview addTarget:self action:@selector(switchAction:) forControlEvents:UIControlEventValueChanged];
        cell.accessoryView = switchview;
    
        //cell.accessoryType=UITableViewCellAccessoryCheckmark;
        //cell.accessoryType=UITableViewCellAccessoryNone;
    
    }
    UILabel *label=(UILabel*)[cell viewWithTag:1];
    label.text=[layers objectAtIndex:indexPath.row];
    
//    //方法2, 定义cell类
//    static NSString *CellIdentifier = @"LayerCell";
//    
//    LayerCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//    if (cell == nil) {
//        NSArray *array = [[NSBundle mainBundle]loadNibNamed:CellIdentifier owner:self options:nil];
//        cell = [array objectAtIndex:0];
//    }
//    cell.label.text = [layers objectAtIndex:indexPath.row];
//
    
    //方法3,定义cell类,并设置file's owner和添加输出口变量与对应
    //将MyCell.xib文件的file‘s owner关联到ManagerLayer类,然后在ManagerLayer.h中添加输出口tvc并赋予MyCell.xib的file's owner.
    //static NSString *cellIdentifier=@"MyCell";
    //MyCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    //if(cell==nil)
    //{
    //    [[NSBundle mainBundle] loadNibNamed:@"MyCell" owner:self options:nil];
    //    cell=self.tvc;
    //}
    
    //引用控件方式1
    //通过设置xib的uitableviewcell的继承类,并添加在MyCell.h中添加了输出口属性的方式访问label控件
    //cell.label.text=[layers objectAtIndex:indexPath.row];
    
    //引用控件方式2
    //在xib中设置了label的tag属性,然后在此通过这个属性调用label
    //UILabel *label=(UILabel*)[cell viewWithTag:2];
    //label.text=[layers objectAtIndex:indexPath.row];

     return cell;
}

//响应方法。通过点击位置确定操作的cell

- (void) sliderAction:(id)sender event:(id)event
{
    NSSet *touches = [event allTouches];
    UITouch *touch = [touches anyObject];
    CGPoint currentTouchPosition = [touch locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:currentTouchPosition];
    if(indexPath != nil)
    {
        //[self tableView:self.tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
        _selIndex=indexPath.row;
        [[NSNotificationCenter defaultCenter] postNotificationName:NotificationLayerChange object:self];
    }
}

//响应方式,通过获取父视图确定操作的cell
- (void)switchAction:(id)sender
{
    UISwitch *switchLayer=(UISwitch*)sender;    
    
    UITableViewCell *cell=(UITableViewCell*)[[sender superview]spuerview];
    NSIndexPath *indexPath=[self.tableView indexPathForCell:cell];
    
    NSInteger selectIndex=[indexPath row];
    NSLog(@"---%d----",selectIndex);
}

示例二

#pragma mark -
#pragma mark Tabel Datasource Methods

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return  20;
    
}

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//方式一,自定义一个tableViewCell子类,关联一个xib文件
//    static NSString *customCellIdentifier=@"CustomCell";
//    static BOOL nibsRegistered = NO;
//    if (!nibsRegistered) {
//注意这种赋值方式
//        UINib *nib = [UINib nibWithNibName:@"CustomCell" bundle:nil];
//        [tableView registerNib:nib forCellReuseIdentifier:customCellIdentifier];
//        nibsRegistered = YES;
//    }
//    
//    CustomCell *customCell=[tableView dequeueReusableCellWithIdentifier:customCellIdentifier];
//    NSString *num=[NSString stringWithFormat:@"%d",indexPath.row];
//    customCell.label.text=num;
//    return customCell;


//方式二,单独采用xib文件
    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:@"CustomCellIdentifier2"];
    if (!cell) {
//注意这种赋值方式
        cell=[[[NSBundle mainBundle]loadNibNamed:@"CustomCell2" owner:self options:nil]lastObject];
    }
    NSString *num=[NSString stringWithFormat:@"%d",indexPath.row];
    UILabel *label=(UILabel*)[cell viewWithTag:12];
    label.text=num;
    
    return cell;

}

#pragma mark Table Delegate Methods
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 60.0;
}

- (NSIndexPath*)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    return  nil;
}
@end


自定义cell的消息传递方法

1、通知的方式

2、委托的方式

在cell中定义委托,如下

xxxCell.h文件

#import <Foundation/Foundation.h>

//声明协议
@protocol LayerInfoCellDelegate;

@interface LayerInfoCell : UITableViewCell {
    UILabel *_valueLabel;   
    id <LayerInfoCellDelegate> __weak _layerInfoCellDelegate;
}

@property (nonatomic, strong) UILabel *valueLabel;
@property (nonatomic, weak) id <LayerInfoCellDelegate> layerInfoCellDelegate;

- (id)initWithStyle:(UITableViewCellStyle)style 
	reuseIdentifier:(NSString *)reuseIdentifier 
			  level:(NSUInteger)level 
canChangeVisibility:(BOOL)canChangeVisibility
         visibility:(BOOL)visibility
		   expanded:(BOOL)expanded;

@end

//协议
@protocol LayerInfoCellDelegate <NSObject>

- (void)layerVisibilityChanged:(BOOL)visibility forCell:(UITableViewCell *)cell;

@end

在xxxCell.m文件中使用delegate

- (IBAction)visibilityChanged {       
    [self.visibilitySwitch changeCheckBox];
    [self.layerInfoCellDelegate layerVisibilityChanged:self.visibilitySwitch.isChecked forCell:self];
}


//在deallloc中重置为nil
- (void)dealloc {
    self.layerInfoCellDelegate = nil;
} 

在调用xxxCell的类中实现delegate协议、实现委托方法

@interface TOCViewController() <LayerInfoCellDelegate, UITableViewDelegate, UITableViewDataSource>

//使用委托的方式,在cell中操作委托给调用cell的类
- (void)layerVisibilityChanged:(BOOL)visibility forCell:(UITableViewCell *)cell
{
    //retrieve the corresponding cell
    NSIndexPath *cellIndexPath = [self.tableView indexPathForCell:cell];
    
    //get the layer info represented by the cell
    LayerInfo *layerInfo = [[self.mapViewLevelLayerInfo flattenElementsWithCacheRefresh:NO withLegend:YES] objectAtIndex:(cellIndexPath.row)];
    
    //set the visibility of the layer info. 
    [layerInfo setVisible:visibility];
}

5. 访问WebService服务

(1)SOAP

采用第三方库ASIHTTPRequest

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    NSLog(@"Want to redeem: %@", textField.text);
    
    // Get device unique ID
    UIDevice *device = [UIDevice currentDevice];
    NSString *uniqueIdentifier = [device uniqueIdentifier];
    
    // Start request
    NSString *code = textField.text;
//    NSURL *url = [NSURL URLWithString:@"http://192.168.133.179:7777/CXFDemo/ws/v1/say/1"];
    NSURL *url=[NSURL URLWithString:@"http://192.168.133.179:7777/CXFDemo/ws/helloService"];
    ASIHTTPRequest *request=[ASIHTTPRequest requestWithURL:url];
    
//    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
//    [request setPostValue:@"1" forKey:@"rw_app_id"];
//    [request setPostValue:code forKey:@"code"];
//    [request setPostValue:uniqueIdentifier forKey:@"device_id"];

//    NSString *soapMsgBody=@"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:q0=\"http://server.dcec/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n<soapenv:Body>\n<q0:test>\n<arg0>fafadfadf</arg0>\n</q0:test>\n</soapenv:Body>\n</soapenv:Envelope>";
    NSString *soapMsgBody = [NSString stringWithFormat:
                         @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
                         "<soapenv:Envelope "
                         "xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" "
                         "xmlns:q0=\"http://server.dcec\">"
                         "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
                         "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
                         "<soapenv:Body>"
                         "<q0:test>"
                         "<arg0>苏州</arg0>"
                         "</q0:test>"
                         "</soapenv:Body>"
                         "</soapenv:Envelope>"];
    NSLog(@"%@",soapMsgBody);
    
    NSString *msgLength=[NSString stringWithFormat:@"%d",[soapMsgBody length]];
    [request addRequestHeader:@"Content-Type" value:@"txt/xml; charset=utf-8"];
    //[request addRequestHeader:@"SOAPAction" value:@"http://server.dcec/helloService\""];
    //value:[NSString stringWithFormat:@"%@%@", xmlNS, wsName]];
    
    [request addRequestHeader:@"Content-Length" value:msgLength];
    [request setRequestMethod:@"POST"];
    [request appendPostData:[soapMsgBody dataUsingEncoding:NSUTF8StringEncoding]];
    
    [request setDefaultResponseEncoding:NSUTF8StringEncoding];
    
    [request setDelegate:self];
    [request startAsynchronous];
        
    // Hide keyword
    [textField resignFirstResponder];
    
    // Clear text field
    textView.text = @"";
    
    // Start hud
    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    hud.labelText = @"Redeeming code...";
    
    return TRUE;
}

- (void)requestFinished:(ASIHTTPRequest *)request
{    
    [MBProgressHUD hideHUDForView:self.view animated:YES];
    if (request.responseStatusCode == 400) {
        textView.text = @"Invalid code";        
    } else if (request.responseStatusCode == 403) {
        textView.text = @"Code already used";
    } else if (request.responseStatusCode == 200) {
        NSString *responseString = [request responseString];
        NSDictionary *responseDict = [responseString JSONValue];
        
        NSString *unlockCode = [responseDict objectForKey:@"unlock_code"];
        
//        if ([unlockCode compare:@"com.razeware.test.unlock.cake"] == NSOrderedSame) {
//            textView.text = @"The cake is a lie!";
//        } else {        
//            textView.text = [NSString stringWithFormat:@"Received unexpected unlock code: %@", unlockCode];
//        }
        NSLog(@"%@",responseString);
        textView.text=responseString;
        
    } else {
        textView.text = @"Unexpected error";
    }
    
}

- (void)requestFailed:(ASIHTTPRequest *)request
{    
    [MBProgressHUD hideHUDForView:self.view animated:YES];
    NSError *error = [request error];
    textView.text = error.localizedDescription;
}

(2)REST  AFNetWorking 2.0框架处理

- (IBAction)action_test:(id)sender {
//    
//    UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"提示"
//                                                 message:@"测试结果"
//                                                 delegate:nil
//                                       cancelButtonTitle:@"取消"
//                                       otherButtonTitles:nil];
//    [alert show];

    //请求的URL需要添加_type=json
    //GET 请求一
//    NSString *url =@"http://192.168.133.179:7777/ychserver/ws/v1/hello/say/33您好?_type=json";
//    NSString *url2=@"http://192.168.133.179:7777/ychserver/ws/v1/hello/getUser/23/33?_type=json";
//    AFHTTPRequestOperationManager *manager=[AFHTTPRequestOperationManager manager];
//    [manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
//        NSLog(@"JSON :\n%@",responseObject);
//    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//        NSLog(@"错误  Error:%@",error);
//    }];

    //GET 请求二
    //http://192.168.133.179:7777/ychserver/ws/v1/hello/login?name=chen陈&pw=密码123&_type=json
    NSString *url =@"http://192.168.133.179:7777/ychserver/ws/v1/hello/login";
    NSMutableDictionary *params=[NSMutableDictionary dictionary];
    [params setObject:@"陈" forKey:@"name"];
    [params setObject:@"密码123" forKey:@"pw"];
    [params setObject:@"json" forKey:@"_type"];
   
    AFHTTPRequestOperationManager *manager=[AFHTTPRequestOperationManager manager];
    
    [manager GET:url parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"响应结果 \n%@",responseObject);
//此时得到的是unicode方式的编码,测试的时候即后台服务设置输出utf-8的编码也会在此处变成unicode
//,汉字不能正常输出。当把这个转成NSDictionary时,编码又自动转了,可以正常输出汉字
        
        NSDictionary *info=(NSDictionary *)responseObject;
        NSLog(@"name  %@",[info objectForKey:@"name"]);
        NSLog(@"pw  %@",[info objectForKey:@"pw"]);
        
        //Dictionary转json
        if ([NSJSONSerialization isValidJSONObject:info])
        {
            NSError *error;
            NSData *jsonData = [NSJSONSerialization dataWithJSONObject:info options:NSJSONWritingPrettyPrinted error:&error];
            NSString *json =[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
            NSLog(@"json data:\n%@",json);
        }
        
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"错误  Error:%@",error);
    }];
    
    NSLog(@"结束。。。");
}

6. ARC中__weak的使用

//当两个对象存在一种类似父子关系的时候,会用到它:parent拥有一个child的强指针,但是反过来,child却只有parent的一个弱指针。一个很典型的例子就是delegate。view controller 通过一个强指针保存一个UITableView对象,那么这个table view的delegate和data source就会用一个若指针指向这个viewcontroller,

可在property中声明一个对象的这个属性,如下:

@property (nonatomic, strong) NSString * aname;
@property (nonatomic, weak) id<MyDelegate> delegate;
@interface LayerInfoCell : UITableViewCell {    
    id <LayerInfoCellDelegate> __weak _layerInfoCellDelegate;//委托
}

说明:在A类中有B的实例,B的delegate是A,当A销毁时,若是strong强指针,则B中的A(delegate)依然存在,这样会引起错误;若使weak弱指针,则B中的delegate(A)就变成了nil.

7. 导航视图控制器的几种方式

在Delegate.h文件中声明一个导航控制器对象

@interface szdcecAppDelegate : UIResponder <UIApplicationDelegate>{
    UINavigationController *navController;
}

在Delegate.m文件中实例化

    //自定义导航控制器
    CityViewController *cityController=[[CityViewController alloc]init];
    cityController.title=@"旅游指南";

    //方式一,初始化根视图的方式
//    navController =[[UINavigationController alloc]initWithRootViewController:cityController];
//    self.window.rootViewController=navController;

    //方式二,调用push方法
//    navController=[[UINavigationController alloc]init];
//    [navController pushViewController:cityController animated:NO];
//    [self.window addSubview:navController.view];
    
    //方式三,调用setViewController方式
    navController=[[UINavigationController alloc]init];
    [navController setViewControllers:[NSArray arrayWithObject:cityController]];
    //self.window.rootViewController=navController;
    [self.window addSubview:navController.view];
    
    [self.window makeKeyAndVisible];
    return YES;



两个视图传递参数

当A中定义了B的变量对象,可在A中调用B的属性变量,实现传递数据。在B中使用委托的方式,将B的数据传递给A。在B中定义委托,在A中实现委托赋值并实现委托的方法。

8. IOS字符集编码转换

(1)Unicode转汉字

//测试用例     name = "\U9648";  陈
//pw = "\U5bc6\U7801123";  密码123

- (NSString *)replaceUnicode:(NSString *)unicodeStr {
    NSString *tempStr1 = [unicodeStr stringByReplacingOccurrencesOfString:@"\\u"withString:@"\\U"];
    NSString *tempStr2 = [tempStr1 stringByReplacingOccurrencesOfString:@"\""withString:@"\\\""];
    NSString *tempStr3 = [[@"\""stringByAppendingString:tempStr2]stringByAppendingString:@"\""];
    NSData *tempData = [tempStr3 dataUsingEncoding:NSUTF8StringEncoding];
    NSString* returnStr = [NSPropertyListSerialization propertyListFromData:tempData
                                                          mutabilityOption:NSPropertyListImmutable
                                                                    format:NULL
                                                          errorDescription:NULL];
    
    return [returnStr stringByReplacingOccurrencesOfString:@"\\r\\n"withString:@"\n"];
    
    
}

抱歉!评论已关闭.