快乐的鲸鱼

iOS开发简单全流程

2015/12/16

前言

这是一个iOS全流程的一个简单简介,并不会很严谨地构架一个项目,我们会讲如何做一个提问详情显示的页面,主要目的还是为没有接触过iOS开发的同学揭开App制作的神秘面纱。

大纲

  1. 开发准备介绍。开发环境,开发语言,开发工具。
  2. Objective-C语法简介。
  3. 开始编码。

正文

开发准备介绍

  • 开发环境:

    开发环境必须是在苹果公司的OS X系统,根据情况可以使用Mac电脑或者在虚拟机下体验。

  • 开发语言:

    进行iOS开发,官方提供两种语言可供选择,分别是Objective-C, Swift。我们这里选择Objective-C。值得一说的是,Facebook公司的开源项目React Native 可以让你用JavaScript进行iOS开发,更加简便。

  • 开发工具:

    使用苹果公司的开发软件Xcode,在App Store免费下载使用。

Objective-C语法简易简介

Objective-C (下文简称OC)是在C语言的基础上封装起来的。Objective-C是一门真正的面向对象的语言。

  1. 数据类型:

    • NSString - 字符串类型

    • NSDictionary - 不可变字典类型

    • NSMutableDictionary - 可变字典类型

    • NSArray - 不可变数组类型

    • NSMutableArray - 可变数组类型

      这里只介绍将会用到的常用Objective-C特有类型,C语言中存在的类型在Objective-C中也可以使用,不过推荐用Objective-C内提供的数据类型

2.方法定义与调用:

  • 类方法定义:
1
2
3
+ (void)sayHello {
NSLog("Hello World!");
}
  • OC的方法定义和其他语言看起来有很大区别,类方法的定义是要用”+”号开头。

实例方法定义:

1
2
3
4
- (void)setTitle {
self.title = "Hello";
NSLog("This title is %@", self.title);
}

实例方法的定义是需要用”-“开头。

  • 方法的调用:
1
[self setTitle];

在OC中方法的调用是需要”[ ]” 括起来,前半部分是对象,后半部分是具体的方法。

在OC中还有其他更高级的一些语法,需要深入了解可以参考一些OC入门书籍。

开始

打开Xcode并执行File\New\Project。选择Application\Single View Application。将项目命名为PageSample,单击下一步,选择一个目录去保存你的项目,然后点击Create。 现在,你的基础项目已经完成。下一步是集成你的第三方工具。但首先你要关闭Xcode,确保他不会影响下一步。

Cocoapods

用来导入开源项目,并且导入所导入项目所需要的依赖的其它开源项目。使用教程点这里

AFNetworking

高效并且使用简单的网络库。在本次项目中需要用到,请在pod中导入(或者你可以直接将文件拖入项目中)。

SDWebImage

高效的异步加载网络图片的开源项目,我们用来加载图片。

MBProgressHUD

丰富的活动提示器,可以提示用户程序当前正在工作。

将开源项目添加到项目中

直接将三个开源项目的文件夹分别拖到项目工作区。记得勾选Copy items if needed 与Create groups 还有Add to targets。如下图所示:

添加开源项目

运行程序

快捷键Command + R 可以在iPhone模拟器中运行你刚刚构建好的项目。

或者点击左上角的三角符号也可以运行程序。

运行程序

增加新的视图控制器和数据模型类

选中PageSample项目,单击File\New\File,并且选择Cocoa Touch\Objective-C class. 命名为JWController,并设置为UIViewController的子类。如下图所示:

创建文件

打开JWViewController.m然后用如下所示替换-viewDidLoad方法:

1
2
3
4
[super viewDidLoad];

//设置一个白色的背景
[self.view setBackgroundColor:[UIColor whiteColor]];

接下来再增加一个模型,用来进行从服务器获取数据和对数据进行处理。

单击File\New\File…并选择Cocoa Touch\Objective-C class。命名为JWGetdata并使其为NSObject的子类。

创建一个点击会跳转到视图控制器JWViewController的按钮

打开ViewController.m在文件开头import JWViewController.h,如下:

1
#import "JWViewController.h"

然后用如下所示替换-viewDidLoad方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
- (void)viewDidLoad {
[super viewDidLoad];

//1
self.view.backgroundColor = [UIColor grayColor];

//2
UIButton *btn = [[UIButton alloc]init];
[btn setTitle:@"点我跳转" forState:UIControlStateNormal];
[btn setFrame:CGRectMake(110, 200, 100, 30)];
[btn addTarget:self action:@selector(jump:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
  1. 设置当前视图控制器的视图的背景颜色为灰色。
  2. 在当前视图控制器的视图上增加一个按钮。
    • setTitle:(nullable NSString *) forState:(UIControlState) 方法设置标题,对应的状态是UIControlStateNormal
    • setFrame:(CGRect *) 方法可以设置按钮所在的坐标和它的尺寸。
    • addTarget:(nullable id) action:(nonnull SEL) forControlEvents:(UIControlEvents)方法Target是关联到哪个控制器,这里选择self(本控制器)。action填写@selector(jump:),即是用选择器选择jump方法,因为这是UIButton对象,所以后面的”:”不能少,用来传递本按钮对象。forControlEvents表示这个action在什么事件触发的时候会有响应,这里选择的是UIControlEventTouchUpInside,表示”手指在按钮范围内点触后抬起”。
    • 每个Cocoa框架里面的方法都可以按住Command键再点击方法来查看方法的定义

接下来我们写上面按钮关联到的跳转方法:

1
2
3
4
- (void)jump:(UIButton *)sender {
JWViewController *jwVC = [[JWViewController alloc] init];
[self presentViewController:jwVC animated:YES completion:nil];
}

现在启动调试之后第一页应该是这样的:

首页预览

打开JWViewController.m在文件开头import需要的开源项目,如下:

1
2
#import "UIImageView+WebCache.h"	//用于异步加载网络图片
#import "AFNetworking/AFNetworking/AFNetworking.h" //用于网络请求

然后用如下所示替换-viewDidLoad方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
- (void)viewDidLoad {
[super viewDidLoad];

//设置一个白色的背景
[self.view setBackgroundColor:[UIColor whiteColor]];

//1
UIView *statueBarBGView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 23)];
[statueBarBGView setBackgroundColor:[UIColor colorWithRed:249/255.0 green:249/255.0 blue:249/255.0 alpha:1.0]];
[self.view addSubview:statueBarBGView];

//增加一个导航栏
UINavigationBar *navbar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 22, 320, 44)];
[self.view addSubview:navbar];

//2 增加一个关闭视图按钮
UIButton *closeBtn = [[UIButton alloc] initWithFrame:CGRectMake(10, 10, 46, 30)];
[closeBtn setTitle:@"关闭" forState:UIControlStateNormal];
[closeBtn setTitleColor:[UIColor colorWithRed:0 green:145/255.0 blue:255/255.0 alpha:1.0] forState:UIControlStateNormal];
[closeBtn addTarget:self action:@selector(closeView:) forControlEvents:UIControlEventTouchUpInside];
[navbar addSubview:closeBtn];

//增加一个导航栏标题
UILabel *titleLab = [[UILabel alloc] init];
titleLab.text = @"问题详情";
titleLab.frame = CGRectMake(129, 15, 69, 21);
[navbar addSubview:titleLab];
}
  1. 通过放一个与下面增加的NavBar同样颜色的view在状态栏的地方来曲线救国达到修改StatusBar背景颜色。
  2. 在这段代码后面是[navbar addSubview:closeBtn] 说明这个对象是加到navbar里面去,成为了navbar的子成员。

接下来我们写上面按钮关联到的关闭窗体的方法:

1
2
3
- (void)closeView:(UIButton *)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}

接下来是看看点击”点我跳转”按钮之后跳转到的界面:

点我跳转

到这里我们的基本框架算是有了,但是上面的构建程序的方法并不是值得提倡的,深入学习之后你会发现上面的做法极其低效,尽管上面的写法很繁琐,但是这有助于没有iOS开发基础的认识到如何利用OC进行iOS开发。

构建我们的视图

我们继续在JWViewController.m文件下编写代码。

我们接下来在写一个方法来构建我们的界面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#pragma mark - 构建视图
- (void)setupView {
// 用户头像
_userHeaderImage = [[UIImageView alloc] initWithFrame:CGRectMake(20, 5, 50, 50)];
_userHeaderImage.backgroundColor = [UIColor clearColor];
CALayer *layer = [_userHeaderImage layer];
[layer setMasksToBounds:YES];
[layer setCornerRadius:25.0];
[self.view addSubview:_userHeaderImage];

// 用户名
_userNameLbl = [[UILabel alloc] initWithFrame:CGRectMake(20 + 50 + 20, 5, 320 - 120, 50/2)];
_userNameLbl.textAlignment = NSTextAlignmentLeft;
_userNameLbl.font = [UIFont systemFontOfSize:15.0];
_userNameLbl.textColor = [UIColor colorWithRed:62/255.0 green:79/255.0 blue:125/255.0 alpha:1.0];
[self.view addSubview:_userNameLbl];

// 个人资料
_userIntroLbl = [[UILabel alloc] initWithFrame:CGRectMake(20 + 50 + 20, 5 + 50/2 , 320 - 120, 50/2)];
_userIntroLbl.numberOfLines = 1;
_userIntroLbl.font = [UIFont systemFontOfSize:14.0];
_userIntroLbl.textColor = [UIColor grayColor];
[self.view addSubview:_userIntroLbl];

// 内容label
_contentLbl = [[UILabel alloc] init];
_contentLbl.numberOfLines = 0;
_contentLbl.font = [UIFont systemFontOfSize:15.0];
[self.view addSubview:_contentLbl];
}

再将[self setupView]; 放到[navbar addSubview:titleLab];之后。这样子就将基本需要的东西都放上去了,不过我们还没填充内容,所以界面上并没有变化。

数据请求与处理

接下来我们就从网络的接口取回数据并且填充到上面构建的视图中。为了避免回调的语法,我们暂且将数据请求的方法也写在JWViewControll.m中。

我们先在JWViewControll.m的开头声明几个需要用到的对象当作数据模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@interface JWViewController ()

/** 用户头像 */
@property (nonatomic, strong) UIImageView *userHeaderImage;

/** 用户名 */
@property (nonatomic, strong) UILabel *userNameLbl;

/** 用户资料 */
@property (nonatomic, strong) UILabel *userIntroLbl;

/** 问题内容 */
@property (nonatomic, strong) UILabel *contentLbl;

@end

我们的网络请求将会用到的接口https://ucqa.dawnlightning.com/capi/space.php?uid=29&do=bwzt&id=116,返回的是JSON格式的数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"code": 0,
"data": {
"bwzt": {
"message": "眼睛干干,难睁开",
"username": "13650458186",
"subject": "有什么好用的眼药水推荐",
"sex": "男",
"age": "21",
"dateline": "1451123548",
"status": "0",
"name": "雨梦",
"avatar_url": "https://ucqa.dawnlightning.com/ucenter/data/avatar/000/00/00/29_avatar_middle.jpg"
}
},
"msg": "进行的操作完成了",
"action": "do_success"
}

接下来我们根据上面的JSON接口写我们的获取数据和设置内容的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#pragma mark - 网络请求和数据处理
- (void)requestAndSetupData {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *url = @"https://ucqa.dawnlightning.com/capi/space.php?uid=29&do=bwzt&id=116";
[manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {

NSData *html = operation.responseData;
NSDictionary *backJSON = [NSJSONSerialization JSONObjectWithData:html options:NSJSONReadingMutableLeaves error:nil];

//result "0"是成功, "1"是失败
NSNumber *result = [backJSON valueForKey:@"code"];
if ([result isEqualToNumber:[NSNumber numberWithInt:1]]) {
NSLog(@"获取数据失败");

} else {
NSLog(@"获取数据成功");

//获得数据
NSDictionary *data = [backJSON objectForKey:@"data"];
NSDictionary *bwzt = [data objectForKey:@"bwzt"];
NSString *name = [bwzt objectForKey:@"name"];
NSString *sex = [bwzt objectForKey:@"sex"];
NSString *age = [bwzt objectForKey:@"age"];
NSURL *headimageURL = [NSURL URLWithString:[bwzt objectForKey:@"avatar_url"]];
NSString *content = [bwzt objectForKey:@"message"];

//设置内容
_userNameLbl.text = name;
_userIntroLbl.text = [NSString stringWithFormat:@"性别:%@ 年龄:%@", sex, age];
[_userHeaderImage sd_setImageWithURL:headimageURL];

//设置contentLbl内容,并且多行显示内容
CGSize labelSize = {0, 0};
labelSize = [content sizeWithFont:[UIFont systemFontOfSize:15]

constrainedToSize:CGSizeMake(280.0, 5000)

lineBreakMode:UILineBreakModeWordWrap];
_contentLbl.frame = CGRectMake(20, 140, 280, labelSize.height);
_contentLbl.text = content;

}

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

}];
}

再将[self setupView]; 放到[self requestAndSetupData];之后运行程序便可以看到以下的效果。

最终效果

到这里我们的小demo就结束了。开始你的iOS开发之旅吧。

CATALOG
  1. 1. 前言
  2. 2. 大纲
  3. 3. 正文
    1. 3.1. 开发准备介绍
    2. 3.2. Objective-C语法简易简介
    3. 3.3. 开始
      1. 3.3.1. Cocoapods
      2. 3.3.2. AFNetworking
      3. 3.3.3. SDWebImage
      4. 3.3.4. MBProgressHUD
      5. 3.3.5. 将开源项目添加到项目中
      6. 3.3.6. 运行程序
      7. 3.3.7. 增加新的视图控制器和数据模型类
      8. 3.3.8. 创建一个点击会跳转到视图控制器JWViewController的按钮
      9. 3.3.9. 构建我们的视图
      10. 3.3.10. 数据请求与处理