目录
- 自定义视图
- 自定义label-textField视图
- AppDelegate.m文件天下如下代码 记得引用头文件#import "LTView.h"
- 视图控制器 (处理事件 接收代理)
- 当一个工程里含有多个视图控制器,我们就要创建一个视图控制器控制器来处理
- 视图控制器中写 键盘从第一输入框 跳到第二输入框
- 内存警告的实现方法
自定义视图
自定义label-textField视图
height=2 | height=2 | width=5 | width = 10 | width = 5 |
width=5 |
|
| ||
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;
}
}
总结:最后一个其实也不是很方便,后期会有更便捷的方式