[3]⾃自定义视图、视图控制器

自定义视图

自定义label-textField视图

height=2height=2width=5width = 10width = 5
width=5UILabelUITextField
height=2
.h文件
#import <UIKit/UIKit.h>
@interface LTView : UIView<UITextFieldDelegate>//加了协议
@property (nonatomic,retain) UILabel * laber;
@property (nonatomic,retain) UITextField *textField;
- (instancetype)initWithFrame:(CGRect)frame labelText:(NSString *)labelText placeHolder:(NSString *)placeHolder;
@end
.m文件
#import "LTView.h"
@implementation LTView
//重写父类的初始化方法,先调用父类的初始化方法,然后在此基础上添加自己的东西
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        CGFloat height = frame.size.height; //LTView的高度
        CGFloat width = frame.size.width;//LTView的宽度
        CGFloat labelHeight = height - 2 * 2;//label的高度
        CGFloat labelWidth = (width - 5 * 3)/3;//label的高度
        CGFloat textFiledHeight = labelHeight;//TextField的高度
        CGFloat textFieldWidth = 2 * labelWidth;
        
        //创建内部的label
        _laber = [[UILabel alloc] initWithFrame:CGRectMake(5, 2, labelWidth, labelHeight)];
        [self addSubview:_laber];        
        //创建内部的输入框
        _textField = [[UITextField alloc] initWithFrame:CGRectMake(10+labelWidth, 2, textFieldWidth, textFiledHeight)];
        _textField.delegate = self;
        

        _textField.borderStyle = UITextBorderStyleRoundedRect;
        [self addSubview:_textField];
        
     
    }
    return self;
}


- (instancetype)initWithFrame:(CGRect)frame labelText:(NSString *)labelText placeHolder:(NSString *)placeHolder
{
    self = [self initWithFrame:frame];
    if (self) {
        _laber.text = labelText;
       _textField.placeholder = placeHolder;
    }
    return self;
}

AppDelegate.m文件天下如下代码 记得引用头文件#import "LTView.h"

    CGFloat x = 30;
    CGFloat y = 50;
    NSArray *labelTexts = @[@"用户名",@"密码",@"确认密码",@"邮箱",@"电话号码"];
    NSArray *placeholder = @[@"6~16位字符",@"6~16位字符",@"再一次输入密码",@"email",@"手机号码"];
    for (int i= 0; i < 5 ; i++)
    {
        LTView *ltView = [[LTView alloc] initWithFrame:CGRectMake(x, y, 300, 40)labelText:labelTexts[i] placeHolder:placeholder[i] ];
        ltView.tag = 100 + i;
        [ self.window addSubview:ltView];
        [ltView release];
        y += 60;
    }    
    LTView *ltV = (LTView *) [self.window viewWithTag:102];
    ltV.textField.placeholder = @"请再输入一次密码";

视图控制器 (处理事件 接收代理)

1.UIViewController:视图控制器
2.控制视图显示,响应事件
3.分担AppDelegate的工作
4.实现模块独立,提高复用性

//创建控制器RootViewController.h/.m 及其创建
//创建一个视图类GetPasswordView
//重写父类的方法,这个方法就一个作用,加载自定义的视图
//loadView这个方法在控制器 第一次使用view的时候,即:第一次[控制器 view]的时候执行!!!第二次就不在执行了.也就是说loadview只执行一次.
//修改AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    //添加内容开始 
    //满足了 AppDelegate的愿望,在程序启动时,给self.window指定了一个根视图控制器.
    //创建一个视图控制器
    RootViewController *rootVC = [[RootViewController alloc] init];
    //指定视图控制器
    self.window.rootViewController = rootVC ;
    //内存处理
    [rootVC release];   
    //添加内容结束 
    [self.window makeKeyAndVisible];
    return YES;
}
-(void)loadView
{
    //self.view = 自定义视图;
    //不管你给定多么大得frame,当它加载时就是按照window的大小 创建的
    GetPasswordView *gtView = [[GetPasswordView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];//也可以写CGRectZero;
    
    //Button的事件拿出去给控制器
    [gtView.getBt addTarget:self action:@selector(getBack) forControlEvents:UIControlEventTouchUpInside];
    
    //输入框中键盘的收回交给控制器去相应
    gtView.emTf.delegate = self;
    self.view = gtView;
    [gtView release];
}
//键盘回收
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return YES;
}
//GetPasswordView.h
#import <UIKit/UIKit.h>
@interface GetPasswordView : UIView
@property (nonatomic,retain) UILabel *emLabel;//邮箱的标签
@property (nonatomic,retain) UITextField * emTf;//邮箱输入框
@property (nonatomic,retain) UIButton *getBt;
@property (nonatomic,retain) UIButton *backBt;
@end
//GetPasswordView.m
#import "GetPasswordView.h"
@implementation GetPasswordView
//要重写dealloc方法释放我们在本类中定义的变量
- (void)dealloc
{
    [_emLabel release];
    [_emTf release];
    [super dealloc];
}
//控制器只负责相应时间,改变根视图的大小,不负责改子视图的大小
//子视图的大小,交给我们自定义的view来修改,
//控制器值负责处理逻辑,不负责界面显示
//这个方法在视图的bounds发生变化时执行.只要bounds发生变化,就会执行这个方法
//横竖颠倒的时候需要调整的
- (void)layoutSubviews
{
    //获取屏幕方法
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    if (orientation == UIInterfaceOrientationLandscapeLeft ||
        orientation == UIInterfaceOrientationLandscapeRight
        )//判断home键在左边或者右边  来判断屏幕是横着的还是竖着的
    {
        //此时改变子视图的大小
        _getBt.frame = CGRectMake(100, 150, 90, 40);
        //其他控件和button类似
    }
    else
    {
        _getBt.frame = CGRectMake(30, 150, 90, 40);//此句不可省略,因为竖屏后还会恢复横屏
    }
}

-(instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        _emLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 80, 90, 40)];
        //创建邮箱输入框
        _emLabel.text = @"邮箱";
        [self addSubview:_emLabel];
        _emTf = [[UITextField alloc] initWithFrame:CGRectMake(140, 80, 200, 40)];
        _emTf.borderStyle = UITextBorderStyleRoundedRect;
        _emTf.placeholder = @"请输入邮箱";
        [self addSubview:_emTf];
        
        //创建找回按钮
        _getBt = [UIButton buttonWithType:UIButtonTypeSystem];
        _getBt.frame = CGRectMake(30, 150, 90, 40);
        [_getBt setTitle:@"找回" forState:UIControlStateNormal];
        [self addSubview:_getBt];
        //创建返回按钮
        _backBt = [UIButton buttonWithType:UIButtonTypeSystem];
        _backBt.frame = CGRectMake(150, 150, 90, 40);
        [_backBt setTitle:@"返回" forState:UIControlStateNormal];
        [self addSubview:_backBt];
    }
    return self;    
}

当一个工程里含有多个视图控制器,我们就要创建一个视图控制器控制器来处理

//.h文件中 引入每个视图的视图控制器,并且把页面跳转的方法写到容器里
#import <UIKit/UIKit.h>
@class LoginViewController;
@class RegisterViewController;
@class FindViewController;

@interface RootViewController : UIViewController

@property (nonatomic, retain) LoginViewController *loginVC;
@property (nonatomic, retain) RegisterViewController *registVC;
@property (nonatomic, retain) FindViewController *findVC;

- (void)login;
- (void)enterRegistView;
- (void)enterGetPasswordView;
- (void)getBackToLoginViewFromRegistView;
- (void)getBackToLoginViewFromFindView;
@end

//.m文件中的方法
-(void)dealloc
{
    [_loginVC release];
    [_registVC release];
    [_findVC release];
    [super dealloc];
}

- (void)login
{
    NSLog(@"登录中");
}

- (void)enterRegistView
{
    [_loginVC.view removeFromSuperview];
    
    _registVC = [[RegisterViewController alloc] init];
//    [_registVC view];//第一次使用视图  第一次调用getter
    
    [self addChildViewController:_registVC];
    [self.view addSubview:_registVC.view];
}

- (void)enterGetPasswordView
{
    [_loginVC.view removeFromSuperview];
    
    _findVC = [[FindViewController alloc] init];
    
    [self addChildViewController:_findVC];
    
    [self.view addSubview:_findVC.view];
}

- (void)getBackToLoginViewFromRegistView
{
    [_registVC.view removeFromSuperview];
    [_registVC removeFromParentViewController];
    [self.view addSubview:_loginVC.view];
}

- (void)getBackToLoginViewFromFindView
{
    [_findVC.view removeFromSuperview];
    [_findVC removeFromParentViewController];
    [self.view addSubview:_loginVC.view];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    //默认的视图写在这边    
    _loginVC = [[LoginViewController alloc] init];
    [self.view addSubview: _loginVC.view];
    
    // Do any additional setup after loading the view.
}
//loadView中创建视图的时候的代码
- (void)loadView
{
    LoginView *loginView = [[LoginView alloc] initWithFrame:[UIScreen mainScreen].bounds];//因为不是直接加载window上面的 如果给0相当于没有 然后 视图越界 点击无效 以后可以都写这种方式
}

视图控制器中写 键盘从第一输入框 跳到第二输入框

-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
    
    UITextField *tf = (UITextField *)[self.view viewWithTag:102];
    //此处为self.view 本控制器为视图控制器 self.view.window也可以
    if (textField.tag == 101)
    {
        [tf becomeFirstResponder];
        [textField resignFirstResponder];
    }
    else
    {
         [tf resignFirstResponder];
    }
    return  YES;
}

//别忘了代理 还有 设置tag值
    loginView.userFiled.delegate = self;
    loginView.userFiled.tag = 101;
    loginView.passFiled.tag = 102;
    loginView.passFiled.delegate = self;

内存警告的实现方法

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
    
    //如果当前视图加载完毕,并且没有在window上面进行显示
   if ([self isViewLoaded] && self.view.window == nil)
   {
       //释放资源
       //比如 view上展示的数据(NSArray,NSDictionary,图片,文字之类的Model)
       self.view = nil;
   }

}

总结:最后一个其实也不是很方便,后期会有更便捷的方式

转载于:https://www.cnblogs.com/ianhao/p/4447277.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值