存档

文章标签 ‘iOS’

MMHot 代码编写过程及心得

2012年10月17日 没有评论

把先前买的那本 ios 变成的书给撕了,每天在地铁上看一点点,又大致看了几个别人的代码,打算自己写一个应用出来练习下,经过一个星期的琢磨,应用 MMHot 代码部分终于完工了。本来打算花 $99 去买一个开发者帐号的,但是昨天晚上看了下水果的应用商店规范,发现 MMHot 应该不会被审核通过的,于是放弃了。$99 对我来说真心贵,不过这个不妨碍今天和大家一起分享这个应用编写的心得。

简单地说,MMHot 是一个浏览美女图片的 ios 应用。

项目使用了 2 个开源的库:EGOImage 和 ASIHttp,所以我觉得这个作为入口比较适合新手来初步了解和学习 objective-c ,既可以完成任务,又在学习的初期降低了门槛。ASIHttp  封装了网络应用中的大部分功能,可以满足常见的 get/post 例如文件下载、上传。EGOImageView 继承了 UIImageView,支持图片的异步下载。

作业的目标:1、大致了解 EGOImage 和 ASIHttp 的简单使用方法。2、代码添加视图。3、学习使用调试,了解 IDE 的功能。

应用是基于 Xcode 4.5.1 和 iOS 6 。新建项目时,我没有选择 Core Data 和 Automatic Reference Counting 。因为我看的代码都是基于用户自己手动管理内存的方式,ARC 跳跃太大,对我不合适。另外的原因是开源的库当前貌似还不支持ARC。

新建项目后,会自动包含 appDelegate 文件。这块需要注意的是 -(void)application:(UIApplication *) application didFinishLaunchingWithOptions:(NSDictionary *) launchOptions 方法。这个方法里用来设置需要第一个显示的视图。我们在很多应用中都看到当应用第一次运行的时候,会给出引导界面让用户了解大致的流程,第二次运行时就不显示引导界面了,为了实现这样的效果,也可以在这个方法里去实现。

在该方法里,包含下面的语句:

self.window=[[[UIWindow alloc] initWithFram:[[UIScreen mainScreen] bounds]] autorelease];
self.viewController=[[[MainViewController alloc] initWithNibName:@”MainViewController” bundle:nil] autorelease];
self.window.rootViewController=self.viewController;
[self.window makeKeyAndVisible];
return YES;
第一行代码是设置界面的window,由 IDE 自动生成,第二行代码是设置程序显示的第一个界面 MainViewController.xib ,第三回是设置窗体的根视图,对于 ios6 系统,要求每个窗体都必须有根视图。由旧系统转换的时候,如果没有添加的话,IDE 也会给出一个警告。第四、五也是自动生成的,很明了。

接下来,我们转到 MainViewController.h 文件。由于我们使用了前面说的2个开源库,所以需要引用进来。另外,由于应用中使用了手势和图片回调,所以还需要添加对应的 delegate:EGOImageViewDelegate 、UIGestureRecognizerDelegate 。该类有 3个变量和一个属性。

EGOImageView *imageView;
ASIHttpRequest *req;
NSMutableArray *list

@property (nonatomic,retain) EGOImageView *imageView;

然后就是具体的实现了。我们在 viewDidLoad 添加初始化代码,图片浏览嘛,当然要把顶部的任务栏给隐藏掉,所以我首先来隐藏任务栏:[[UIApplication sharedApplication] setStatusBarHidden:YES];

UIImage *image=[UIImage imageNamed:@”1.jpg”];
imageView=[[EGOImageView alloc]initWithImage:image];
[imageView setFrame:CGRectMake(0,0,[UIScreen mainScreen].bounds.size.width,[UIScreen mainScreen].bounds.size.height)];
imageView.delegate=self;
[self.view.assSubview:imageView];

//添加手势识别
UISwipGestureRecognizer *swipLeft=[[UISwipGestureRecognizer alloc] initWithtarget:self action:@selector(handleSwipGesture:)];
swipLeft.direction=UISwipGuestureRecognizerDirectionLeft;
[self.view addGuestureRecognizer:swipLeft]; //为了防止图片旋转后,手势也跟随变化,所以把手势添加到根视图中,而非 imageView
[swipLeft release];

//发送请求
req=[ASIHttpRequest requestWithURL:[NSURL URLWithString:@”http://www.withonly.com”]];
[req setDelegate:self];
[req setDidFinishSelector:@selector(ASIHttpRequestFinished:)];
[req setDidFailSelector:@selector(ASIHtppRequestFailed:)];
[req startAsynchronous];

视图在显示的时候,首先显示一个本地图片文件 1.jpg ,这样的话可以避免网络延迟带来的视觉等待,然后将视图添加到窗体视图中。手势识别没有什么好说的,都一样。最后是发送请求,请求成功时执行ASIHttpRequestFinished,失败时执行ASIHtppRequestFailed。需要提醒大家的是第 4 行,我3天晚上没有睡好觉就是因为少了这一行代码。

-(void) ASIHttpRequestFinished:(ASIHttpRequest *) request{
NSString *info=[request responseString];
NSMutableString *str=[[NSMutalbeString stringWithString:info];
NSError *error;
NSRegularExpression *regex=[NSRegularExpression regularExpressionWithPattern:@”img src=\”(.*?)\”” options:NSRegularExpressionCaseInsensitive| NSRegularExpressionDotMatchesLineSeparators error:&error];
NSArray *matches=[regex matchesInString:str options:NSMatchingCompleted range:NSMakeRange(0,[str length])];
if([matches count]>0){
[list removeAllObjects];
}

for(NSTextCheckingResult *match in matches){
NSRange range=[match rangeAtIndex:1];
[list addObject:[str substringWithRange:range]];
}
if([list count]>0){
[imageView setImageURL:[NSURL URLWithString:[list objectAtIndex:0]]];
[self ResizeImage]; //图片缩放
}

}

当请求成功后,通过正则提取返回结果里的图片 url 地址,并且保存在 list 变量里。最开始的时候是打算使用xml 来解析的。可是网上搜索了下2种关于xml解析的思路,和 java 是一个味道,擦的,难道没有net 风格的么。于是换做正则来提取。解析完了后,如果 list 里有记录,则显示第一条记录里放的图片。其它的方法都差不多了,没有啥好说的。

在文章的最后,我说一说那个让我好几天没有睡好觉的问题。因为在加载图片后,还需要对图片进行缩放。但是由于图片的下载过程是一个异步的操作,最开始的缩放代码里总是会崩溃,因为那时图片都没有下载回来。我很期待有一个类似图片加载完的回调方法。

后来,查看了EGOImageView 的源文件,发现里面有 imageViewLoadedImage 方法,然后添加到文件里,发现没有效果,后来又发现了imageButtonLoadedImage ,添加进去还是没有效果。很崩溃,于是在网上看到有用 NSNotification  来解决的。赶紧添加进去,还是不行。弄了几个晚上都没有有效的方法。

最后才发现,其实 EGOImageView 已经内部实现了 NSNotification 的相关方法了,只需要在代码里添加 imageView.delegate=self ,然后在 imageViewLoadedImage 实现回调例如图片的缩放就可以了。

分类: iOS, 日常 标签: , , , ,

loaded the “ViewControl” nib but the view outlet was not set 错误的解决办法

2012年10月10日 没有评论

糗事的 ios 项目最近一直都无法编译运行,因为每次 command+R 的时候都出现了 loaded the “ViewControl” nib but the view outlet was not set  这个错误提示。本来英语就不咋滴,再加上对 xcode 和 objective-c 不熟悉,简直弄昏了头。

后来发现了解决方法,很简单,基本功的问题。

1、先点击 File’s Owner ,然后选择右边的 Identity inspector 选项卡,Custom Class 窗口,Class 文本框里输入 xib 文件的文件名,这里是 ViewControl ,回车。

2、在 File’s Owner 里添加一个 Outlet 到 view 控件。具体方法见上一篇文章

3、重新编译,就可以运行了。

 

原因分析:由于当初新建项目时默认的 View 控件被我给删除了,后来我又添加的一个 view 控件。和新建项目默认的view不一样的地方在于,File’s Owner 的 Class 默认为 NSObject ,所以需要手工修改和当前的nib文件关联。

感觉在学习多视图处理的时候如果不注意应该也会碰到这个问题吧。

分类: iOS, 日常 标签: , ,

Xcode 中插座变量和动作释疑

2012年10月10日 没有评论

几乎在一年前,我的博客里《iOS版本的hello world》是发表的第一篇关于 ios 开发的文章,那只是一个很简单的示例,之后我就在没有再写了。一来是因为我很懒,另外一个很重要的原因就是我被一个问题弄迷惑了。

一年前,我从网上下了几个电子书,晚上躲在被窝里慢慢看。你知道的,现在我几乎很少买书的,这方面的书都太贵了,到后来才买的一本书。正是这书里的内容让我迷惑了很久很久。在  cocoaChina 上看了下,感觉有点高级不太针对入门的人,朋友中也没有人可以问,所以一直在困惑。

我们来举一个例子来说明下,在视图中有一个文本框和一个按钮,点击按钮显示文本框里的内容。要如何实现呢?

1、在 h 文件里添加一个属性,代码为 @property (nonatomic,retain) IBOutlet UITextView *txtInfo;

2、在 h 文件里添加一个动作 -(IBAction) btnClick:(id) sender;

3、在m文件里写实现代码 @synthesize txtInfo;  -(IBAction)btnClick:(id)sender{//这里是具体的点击实现按钮}

在这个时候来运行程序的话,应该是得不到预期的效果,为什么呢?因为还没有把控件和代码变量绑定起来。

接下来是第4步,4、切换到 xib 文件,拖动 File’s Owner 到文本框上去;然后拖动按钮到 File’s Owner 上去。需要注意的是,他们的拖动方向相反,前后并不一致。此时编译运行程序,应该就可以得到预期效果了。

其实第4步操作就是标题所述的绑定插座变量和动作。这个时候,我的疑问就来了。为什么要拖动方向相反呢,我要如何记住拖动的方向呢?

我就一直在纠结,为什么 xcode 不能像 vs 那样友好一些,拖下控件就可以写代码多好呀。

只到上个周末,我突然就明白了,那本书坑爹呀。

第4步是可以用一个方向来完成的,在 File’s Owner 上面点击右键,会弹出菜单。将里面的 + 号拉到控件上去一样第可以实现目的。插座变量,动作都可以用相同的顺序来。其实在 .net 里,是vs帮我们完成了这个绑定的操作。例如:

protected Button btn;  btn.Click+=new btn_Click;  protected void btn_Click(object sender, EventArgs e){}

分类: iOS, 日常 标签: , , ,

iOS版本的hello world

2011年12月1日 没有评论

在以前的博客中,我搞了个 Android 版本的 hello world。今天 iOS 版本的也出来了。

老实说,这次比以前要花费了更多的时间。

还是先上图吧。

在网上下了几个电子书,并奉献了几个通宵大致给浏览过了一下。讲的都是 objective-c 的基本知识,看的有点似懂非懂,同时也木有找到关于 Xcode 4.2 的介绍。又在网上看了点视频,总算有点眉目了。感觉看到的内容都太坑爹了。

最后学习到的:

1、icon 图标为57*57。

2、@property。这个貌似是objective-c 2才出来的功能。

3、内存管理意识。先前无论是NET还是java,都有GC去处理,在这里不行了。

接下来需要处理的是如何发布app和加快编译速度。

分类: iOS, 日常 标签: