专栏首页iOS开发日记iOS开发系列——纯代码实现iOS开发
原创

iOS开发系列——纯代码实现iOS开发

storyboard进行界面设计固然不错,特别是对于初学者经常会使用设计器进行界面设计,但是实际开发过程中我们很多情况下会直接使用代码进行界面布局,特别是对于复杂的界面布局更是如此。下面我们就从一个空项目建立一个类似于前面的登录界面。

小编有个自己学习交流群681503716(验证编号:大鲨)在iOS学习道路上的小伙伴可以加一下哦~

直接在Xcode中创建“Empty Application”(注意在Xcode6中这个选项已经没有了,这里采用Xcode5.1),此时会发现已经没有ViewController和storyboard文件,我们需要手动创建一个视图控制器(在项目中右键选择Objective-c class,默认继承自UIViewController,输入类名:KCMainViewController即可)。

新建的视图控制器默认情况下是无法加载到程序运行界面上的,此时需要在应用程序代理的程序加载完毕事件中手动加载并显示我们的视图。修改之前KCAppDelegate.m代码如下:

//  KCAppDelegate.m
//  IOSByCode
//
//  Created by Kenshin Cui on 14-2-23.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import "KCAppDelegate.h"

@implementation KCAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

我们修改上面- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions的代码如下:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //设置window属性(在KCAppDelegate中定义的window属性),初始化windows的大小和位置
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    //设置window的背景
    self.window.backgroundColor = [UIColor whiteColor];
    
    //初始化KCMainViewController
    KCMainViewController *mainController=[[KCMainViewController alloc]init];
    //设置自定义控制器的大小和window相同,位置为(0,0)
    mainController.view.frame=self.window.bounds;
    //设置此控制器为window的根控制器
    self.window.rootViewController=mainController;
    
    //设置window为应用程序主窗口并设为可见
    [self.window makeKeyAndVisible];
    return YES;
}

然后在我们自定义的KCMainViewController.m中添加一个UIImageView、两个控件UITextField和一个UIButton控件,并且实现具体的登录方法。

KCMainViewController.h

//
//  KCMainViewController.h
//  IOSByCode
//
//  Created by Kenshin Cui on 14-2-23.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface KCMainViewController : UIViewController

#pragma mark logo
@property (nonatomic,strong) UIImageView *logo;
#pragma mark 手机号码
@property (nonatomic,strong) UITextField *phoneNumber;
#pragma mark 密码
@property (nonatomic,strong) UITextField *password;
#pragma mark 登录按钮
@property (nonatomic,strong) UIButton *loginButton;

#pragma mark 点击事件
-(void)login:(UIButton *)btn;

@end

KCMainViewController.m

//
//  KCMainViewController.m
//  IOSByCode
//
//  Created by Kenshin Cui on 14-2-23.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import "KCMainViewController.h"

@interface KCMainViewController ()

@end

@implementation KCMainViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    //self.view.backgroundColor=[UIColor redColor];
    
    //添加图片
    CGRect logoRect=CGRectMake(100, 50, 100, 200);
    _logo=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"LoginBackground.png"]];//设置图片
    _logo.contentMode=UIViewContentModeScaleAspectFit;//设置内容填充模式
    _logo.frame=logoRect;//设置控件大小和位置(相对于父控件的位置)
    [self.view addSubview:_logo];//添加到KCMainViewController的View中
    
    //添加手机号码输入框
    CGRect phoneNumberRect=CGRectMake(20, 320, 280, 30);
    _phoneNumber=[[UITextField alloc]initWithFrame:phoneNumberRect];
    _phoneNumber.borderStyle=UITextBorderStyleRoundedRect;//设置文本框的边框样式
    [self.view addSubview:_phoneNumber];
    
    //添加密码输入框
    CGRect passwordRect=CGRectMake(20, 380, 280, 30);
    _password=[[UITextField alloc]initWithFrame:passwordRect];
    _password.borderStyle=UITextBorderStyleRoundedRect;
    [self.view addSubview:_password];
    
    //添加登录按钮
    CGRect loginButtonRect=CGRectMake(10, 440, 300, 25);
    _loginButton=[[UIButton alloc]initWithFrame:loginButtonRect];
    [_loginButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];//设置标题内容颜色
    [_loginButton setTitle:@"登录" forState:UIControlStateNormal];//设置按钮标题
    [_loginButton addTarget:self action:@selector(login:) forControlEvents:UIControlEventTouchUpInside];//添加点击事件
    [self.view addSubview:_loginButton];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)login:(UIButton *)btn{
    if ([_phoneNumber.text isEqual:@"123"]&&[_password.text isEqual:@"456"]) {
        NSLog(@"登录成功!");
    }else{
        NSLog(@"登录失败!");
    }
}


@end

运行效果如下,与之前使用storyboard创建的界面类似,同时也能点击登录:

UIView

在这里我们需要对上面的代码一样解释,在弄清上面的代码之前我们不得不熟悉一个UIKit中最重要的类UIView。

  1. UIView就是指界面可见的控件元素,所有的控件最终都继承自UIView,UIView中还可以添加其他UIView(通过addSubView方法);
  2. 在一个iOS应用中必须有一个主窗口UIWindow(理论上也可以有多个UIWindow但是只有一个是主Window,而且只有主Window可以和用户交互),UIWindow也是继承自UIView,它拥有UIView的所有属性、方法;
  3. 在UIWindow中必须有一个根控制器,这个控制器距离UIWindow是最近的;设置一个控制器为根控制器和直接通过addSubView添加控制器的视图(view属性)到window并不完全一样(例如如果仅仅添加控制器视图那么应用虽然可以显示但是不支持旋转);
  4. UIViewController是视图控制器,主要用来控制UIView,在UIViewController内部有一个UIView(view属性);

在上面的代码中我们首先在应用程序加载完毕之后加载一个UIWindow对象,同时把我们的视图控制器KCMainController设置为UIWindow的根视图控制器,然后设置这个UIWindow为主窗口并可见。当主窗口设置为可见过程中会调用视图控制器的loadView方法来加载视图(注意视图控制器的loadView方法是延迟加载的,第一次调用视图控制器的view属性才会调用此方法;由于makeKeyAndVisible方法中会使用视图控制器的view属性所以此时会调用视图控制器的loadView方法),视图加载完之后调用viewDidLoad方法,在这个方法中我们添加登录相关控件并将这些控件加载到视图控制器KCMainViewController的视图view中。

下面我们看一下应用程序最终的布局,相信通过这张图大家对于iOS的布局会有一个大致了解:

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • iOS开发系列——第一个iOS程序和运行过程

    这里我想强调一下,前面的知识是你日后开发IOS的基础,没有那些知识你开发IOS会很痛苦,现在很多开发人员做开发都是一知半解,程序质量确实令人担忧,所以还是希望大...

    Kris大鲨
  • 给我十个可爱的订阅的粉丝带来的一篇iOS面经。。。。

    大大小小参加过不下30+公司的面试,其中不乏BAT、TMD等一线互联网公司,总结一下,发现大厂招聘都有一个共性。

    Kris大鲨
  • 六个方向关于iOS100个面试题,你都会了吗?

    请概括一下你在构建iOS应用时的测试过程。iOS应用如何实现对其他语言、日期格式以及货币单位的支持?

    Kris大鲨
  • 在Linux上手动安装教程Huginn抓取全文RSS和微信公众号

    Huginn是一个神器,它是一个私人IFTTT,例如搭建任务采集触发平台,自动跟进实时提醒(用Email Slack Telegeram QQ 微信接受推送),...

    huginn 中文网
  • Centos 安装SVN

    接下来,将/data/svn/conf目录下的svnserve.conf文件复制到/data/svn/test/conf/目录下。如下所示。

    程序员同行者
  • request和response接口

    东风冷雪
  • 一种非常简单的Android屏幕适配方案

    作为一个Android开发人员,你还在为了适配各种尺寸的屏幕而苦恼吗?你还在为了出现一个新的机型而修改着数不尽的dimens和layout吗?你还在为了UI...

    Android技术干货分享
  • 在非原子路由策略中,针对信息设计的半定方法(CS GT)

    我们研究出了一种存在于非原子代理下的路由策略。在该种情况下,处于不定网络状态中的连接延迟函数是有条件的。所有的代理针对前期状态都怀有相同的目标,但是只有固定比例...

    Donuts_choco
  • 统计学习导论 Chapter8 -- Tree-Based Methods

    Book: An Introduction to Statistical Learning with Applications in R http:...

    用户1148525
  • HDUOJ--------1003 Max Sum

    Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (J...

    Gxjun

扫码关注云+社区

领取腾讯云代金券