ios 控制器ios 改变view的framee打印出来跟我想的为什么不一样

iOS个人整理05-应用程序的启动流程--视图控制器ViewController的加载过程--MVC架构
一、应用程序启动流程
main函数中的操作
创建整个应用程序
创建整个应用程序的代理
指定应用程序的代理
把应用程序放在RunLoop中,等待--处理--等待
再执行- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
int main(int argc, char * argv[]) {
@autoreleasepool {
//配置应用的一个main函数
//前面两个参数是启动必要的数据,系统自己配置
//第三个参数:将应用程序的类名转换为字符串作为该函数的参数,如果赋值为nil,意味着默认值为@”UIApplication&,这个参数可以是UIApplication的子类,这个参数就是应用对象
//第四个参数:创建了应用的代理
//当应用程序对象和代理对象创建完成后,将二者建立关联,也就是应用程序将代理对象指定为整个应用程序的代理,协助应用程序处理逻辑操作
//当应用程序和代理对象建立关联后,会将整个应用程序放入RunLoop中,不退出就会一直循环运行。他有三种状态, 等待状态-》接到操作-》处理操作-》等待状态
NSLog(@&delegate - - -- %@&,NSStringFromClass([AppDelegate class]));
//此函数在内部根据字符串创建该字符串类型的对象所需的方法,将及辅材转换为类
NSClassFromString(@&AppDelegate&);
return UIApplicationMain(argc, argv, NSStringFromClass([UIApplication class]), NSStringFromClass([AppDelegate class]));
进入代理后方法的执行
AppDelegate.m
#import &AppDelegate.h&
#define A 1000
#define myMAX(A,B) ((A)&(B)?(A):(B))
//宏定义的参数要加括号,返回值也要加括号
#define RGBA(r,g,b,a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:(a)]
//宏定义截取字符串
#define sub(a,b) [(a) substringToIndex:(b)];
@interface AppDelegate ()
@implementation AppDelegate
//当main函数执行完,应用程序创建好了,应用的代理也指定为当前类的对象,这时当前类的对象也将应用放到了RunLoop中,这时整个应用程序才算加载完毕。当应用程序加载完毕,就调用此代理方法,进行界面设置
//告诉delegate程序启动即将完成,程序准备要运行。(delegate实现这个方法时,要创建window对象,将程序内容通过window呈现给用户)
- (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 {
//打印方法
NSLog(@&fuc1 = %s&,__func__);
//程序已经进入后台,一般我们将一些重要数据进行保存,因为苹果应用进入后台之后,如果长时间不操作,就会推出
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(@&fuc2 = %s&,__func__);
//程序即将进入前端,应用变得活跃,此方法中,需要将刚才暂停的一些操作重新开启
- (void)applicationWillEnterForeground:(UIApplication *)application {
NSLog(@&fuc2 = %s&,__func__);
//程序已经变得活跃
- (void)applicationDidBecomeActive:(UIApplication *)application {
//程序将要退出
- (void)applicationWillTerminate:(UIApplication *)application {
NSLog(@&exit&);
一个帮助理解的练习:用自定义的类做应用程序的代理
1.创建一个类继承于UIResponder
2.遵守UIApplicationDelegate协议
3.实现协议方法(实现一个didFinish方法,里面写个nslog打印就行)
4.&return UIApplicationMain(argc, argv, nil, NSStringFromClass([TestResponder class])); 在这个指定应用程序代理类为自定义的类(TestResponder)
二、ViewController的加载流程
之前我们所有的View都是写在Appdelegate.m的launch函数里的,这样显然不方便,太臃肿,系统给我们生成的模板就有一对ViewController文件,在其中对视图进行具体操作。
而我们要在Appdelegate.m里创建视图控制器对象,作为window的根视图控制器。
视图控制器是应用程序数据和视图直接的重要桥梁,每个IOS程序只显示一个用户界面,显示的内容是由控制器或一组视图控制器协调管理的,所有视图控制器提供了一个基本的框架来构建应用程序。
首先command+N创建一个ViewController类,继承于UIViewController。
然后在Appdelegate.m,导入ViewController类,在launch函数中创建一个ViewController对象,并把他设置为window的根视图控制器
ViewController作为视图控制器会自动创建一个底层View
#import &ViewController.h&
&&& ViewController *firstVC = [[ViewController alloc]init];
&&& //生命周期开始
&&& self.window.rootViewController = firstVC;
这时运行程序会自动将ViewController.view加载到self.window上
在ViewController.m中,有多种方法,表示了一个View的产生到结束的过程
loadView(加载视图)---&
viewDidLoad(加载完毕)---&
viewWillAppear(即将出现)---&
viewDidAppear(已经出现)---&
viewWillDisAppear(即将消失)---&
viewDidDisAppear(已经消失)
一般我们将视图的控件写在ViewController.m的viewDidLoad()方法里面
//视图加载完毕
-(void)viewDidLoad
//父类的viewDidLoad
[super viewDidLoad];
//创建Label
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(40, 200, 80, 40)];
label.text = @&文本框&;
//创建button
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.backgroundColor = [UIColor greenColor];
[btn setTitle:@&ok& forState:UIControlStateNormal];
btn.frame = CGRectMake(150, 300, 80, 40);
[btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];
//创建TextField
UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(100, 200, 200, 40)];
text.borderStyle = UITextBorderStyleRoundedR
//把控件添加到View上
[self.view addSubview:text];
[self.view addSubview:btn];
[self.view addSubview:label];
三、MVC架构
MVC就是model(数据模型),View(视图),Control(控制)的简写。
视图和数据模型通过Control模块进行交互,二者不直接交互。
这样结构的好处是数据和视图显示可以分离,结构更加清晰,两部分可以分开写,耦合性低,修改视图不会影响数据,反之亦然
所以之后我们的工程目录结构就是这样的
RootViewController作为视图控制器,继承的是UIViewController,也可以理解为MVC架构中的Control,在这里面进行接收数据,在视图上显示数据的功能
其余的TouchView等文件就是视图文件,继承的是UIView,也就是MVC中的View,我们在其中进行控件的设置和布局。
在以后学习到.xib文件的时候,会更方便,这是后话。
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?iOS自定义转场动画 – 王技术
iOS常用的转场方式包括push,Modal等
本文介绍自定义Modal转场动画来实现展示小菜单功能
效果图如下:
功能由四个类组成分别是:
ViewController: 控制器
HXPopoverAnimator: 自定义Modal动画管理者
HXJumpViewController: 要弹出的控制器(小菜单)
HXPresentationController:管理弹出的控制器HXJumpViewController
首先是主控制器界面ViewController
控制器和非常简单,设置titleView后监听titleView的点击弹出jumpVc
jumpVc是要Modal出来的控制器
HXPopoverAnimator是自定义用来管理转场动画的类,我会在下面介绍
需要注意的是这句:
jumpVc.modalPresentationStyle = UIModalPresentationC
这句的作用是让新控制器Modal出来之后
新控制器下面的旧控制器依然显示
如果不设置是不显示的
因为我们新Modal出来的控制器是一个菜单,他并不是全屏显示
所以如果不让旧控制器显示,后果将不堪设想….
我们平时正常的Modal展示出的控制器都是占据整个屏幕
所以旧控制器就算不显示也不会有影响
弹出后效果图:
- (void)setUpTitleView{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:@"菜单" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.titleView =
- (void)btnClick{
//创建弹出的控制器
HXJumpViewController *jumpVc = [[HXJumpViewController alloc]init];
//设置modal的样式
默认是UIModalPresentationNone:该控制器后面的控制器不会显示
jumpVc.modalPresentationStyle = UIModalPresentationC
//设置弹出View的frame 是自定义的属性
self.popoverAnimator.presentFrame = CGRectMake(100, 55, 180, 250);
//transitioningDelegate实现动画 交给popoverAnimator来做
jumpVc.transitioningDelegate = self.popoverA
[self presentViewController:jumpVc animated:YES completion:nil];
//这里的popoverAnimator一定要是强引用
//不然等btnClick 执行结束后 popoverAnimator销毁了,就不会执行popoverAnimator中定义的dismiss代理方法,我就被坑了...
- (HXPopoverAnimator *)popoverAnimator{
if (!_popoverAnimator) {
_popoverAnimator = [[HXPopoverAnimator alloc]init];
return _popoverA
然后是比较简单的HXPresentationController:
Modal的实现原理是:
把将要弹出控制器的View塞进UIPresentationController里面弹出
所以要自定义了Modal
就要自己操作UIPresentationController
UIPresentationController很简单,只做两件事:
1:添加手势View监听点击dismiss自己
2:设置弹出View的Frame
效果图可参考上图
- (void)containerViewWillLayoutSubviews{
[super containerViewWillLayoutSubviews];
//设置弹出View的Frame
self.presentedView.frame = self.presentF
//添加手势View
[self.containerView insertSubview:self.maskView atIndex:0];
- (void)tapGes{
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
//懒加载背景View
- (UIView *)maskView{
if (!_maskView) {
_maskView = [[UIView alloc]init];
_maskView.backgroundColor = [UIColor colorWithWhite:0.8 alpha:0.2];
_maskView.frame = self.containerView.
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapGes)];
[_maskView addGestureRecognizer:tap];
return _maskV
最后是HXPopoverAnimator:
HXPopoverAnimator是继承NSObject 遵循UIViewControllerTransitioningDelegate,UIViewControllerAnimatedTransitioning协议的类
用来管理Modal动画
类代码较多,就不在文章里粘了,请移步demo:
/huberyhx/HXCustomModal.git
demo中有详细的代码注释在iOS中view的frame属性使用地太频繁了,尤其是调UI的时候。我们知道,正常情况下我们无法对frame的某个属性(x,y,width,height等)进行单独修改,比如:
someView.frame.x = 100;
这种方式是不允许的,但实际上我们更经常遇到的是frame的大部分元素值保持不变,只改变其中的一部分。相信这个烦恼困扰了不少人,于是我们不得不用以下两种方法去达到目的:
CGRect frame = someView.
frame.x =100;
frame.width = 200;
someView.frame =
someView.frame = CGRectMake(100, XXX, 200, XXX);
法2看起来也很精简,但实际上也很麻烦,因为实际应用场景中x, y, width, height四个值都是依赖别的变量,导致法2的语句非常长。简而言之,以上方法都不够&优雅&。那怎样才算优雅呢?我觉得如果我们能如下这样直接修改某个值就完美了:
someView.x = 100;
someView.width = 200;
我们跳过someView的frame属性,直接修改了我们想要的元素值。幸运的是,我们使用category可以相当方便地达到目的,这是一件一劳永逸的事情,引入一次category后整个工程都可以使用这种修改方法:
UIView+Frame.h
WZLCodeLibrary
Created by wzl on 15/3/23.
Copyright (c) 2015年 Weng-Zilin. All rights reserved.
9 #import &UIKit/UIKit.h&
11 @interface UIView (Frame)
13 @property (nonatomic, assign) CGF
14 @property (nonatomic, assign) CGF
15 @property (nonatomic, assign) CGF
16 @property (nonatomic, assign) CGF
17 @property (nonatomic, assign) CGP
18 @property (nonatomic, assign) CGS
UIView+Frame.m
WZLCodeLibrary
Created by wzl on 15/3/23.
Copyright (c) 2015年 Weng-Zilin. All rights reserved.
9 #import "UIView+Frame.h"
11 @implementation UIView (Frame)
13 - (void)setX:(CGFloat)x
CGRect frame = self.
frame.origin.x =
self.frame =
20 - (CGFloat)x
return self.frame.origin.x;
25 - (void)setY:(CGFloat)y
CGRect frame = self.
frame.origin.y =
self.frame =
32 - (CGFloat)y
return self.frame.origin.y;
37 - (void)setOrigin:(CGPoint)origin
CGRect frame = self.
frame.origin =
self.frame =
44 - (CGPoint)origin
return self.frame.
49 - (void)setWidth:(CGFloat)width
CGRect frame = self.
frame.size.width =
self.frame =
56 - (CGFloat)width
return self.frame.size.
61 - (void)setHeight:(CGFloat)height
CGRect frame = self.
frame.size.height =
self.frame =
68 - (CGFloat)height
return self.frame.size.
73 - (void)setSize:(CGSize)size
CGRect frame = self.
frame.size =
self.frame =
80 - (CGSize)size
return self.frame.
这种策略虽然简单,说破了就不值钱了,但是实用!希望这篇文章能帮大家打破思维定势,不要再被frame困扰!
=======================================================
原创文章,转载请注明 编程小翁@博客园,邮件zilin_,微信Jilon,欢迎各位与我在C/C++/Objective-C/机器视觉等领域展开交流!
&=======================================================
阅读(...) 评论()
我是来自厦门的Jilon. 翁,请关注我的微博:真实的weng,或关注微信:Jilon拒绝访问 | www. | 百度云加速
请打开cookies.
此网站 (www.) 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(380a19d3c181439a-ua98).
重新安装浏览器,或使用别的浏览器[iOS基础控件-6.11.1]-控制器&控制器view_iOS开发_动态网站制作指南
[iOS基础控件-6.11.1]-控制器&控制器view
来源:人气:401
A.控制器的创建 控制器常见的创建方式有以下几种通过storyboard创建 直接创建
<span style="color: # ViewController *vc = [[ViewController alloc] init];
&& & xib设置了class后,当xib的文件名跟controller类名一样的时候,用这个方法默认就会加载xib中的controller
指定xib文件来创建
<span style="color: # ViewController *vc = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
1.从storyboard中创建
(1)创建一个Empty
(不带storyboard)
(2)创建window并加到screen上
<span style="color: # - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
<span style="color: #
// 手动添加window到screen
<span style="color: #
self.window = [[UIWindow alloc] init];
<span style="color: #
self.window.frame = [[UIScreen mainScreen] bounds];
<span style="color: #
self.window.backgroundColor = [UIColor grayColor];
<span style="color: #
[self.window makeKeyAndVisible];
<span style="color: #
return YES;
<span style="color: # }
(3)创建一个storyboard,拖入一个controller
(4)取出storyboard(其实就是相当于xib)
<span style="color: #
// 2.取得stroyboard
<span style="color: #
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"mysb" bundle:nil];
(5)设置storyboard上controller为rootViewController
有两种方式取得storyboard上的controller
a.直接使用入口controller,这个view的背景色是橄榄绿
设置storyboard中的ViewController的class为自定义的controller
<span style="color: #
// 3.1直接使用InitialViewController
<span style="color: #
self.window.rootViewController = [sb instantiateInitialViewController];
设置ViewController的class
再拖入一个ViewController,设置view的背景色是黄色,设置ID是”vc2"
<span style="color: #
// 4.使用ID取得controller, 设置rootViewController
<span style="color: #
self.window.rootViewController = [sb instantiateViewControllerWithIdentifier:@"vc2"];
完成的加载过程:
1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 1.手动添加window到screen
self.window = [[UIWindow alloc] init];
self.window.frame = [[UIScreen mainScreen] bounds];
self.window.backgroundColor = [UIColor grayColor];
[self.window makeKeyAndVisible];
// 2.取得stroyboard
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"mysb" bundle:nil];
<span style="color: #
<span style="color: #
// 3.取出storyboar中的controller
<span style="color: #
// 3.1直接使用InitialViewController
<span style="color: #
ViewController *controller = [sb instantiateInitialViewController];
<span style="color: #
<span style="color: #
// 3.2使用ID
<span style="color: #
ViewController2 *controller2 = [sb instantiateViewControllerWithIdentifier:@"vc2"];
<span style="color: #
<span style="color: #
// 4.设置rootViewController
<span style="color: #
self.window.rootViewController = controller2;
<span style="color: #
<span style="color: #
return YES;
<span style="color: # }
1.创建Single View Application的时候,项目会自带一个storyboard,其实就是做了上面的事情
设置了Main storyboard 的文件,就会自动加载storyboard
2.不同的controller类负责不同的界面的操作
2.直接创建
(不详述)
3.指定xib文件创建
在之前没有storyboard的时候使用这种方法
(1)创建一个controller
(2)创建一个xib
(3)在xib拖入两个view,设置一些特征标识,方便对比
(4)设置其中一个view为控制器的view
a.更改 File’s Owner 的class为自定义的controller
b.设置controller的view
(5)从xib加载controller,并把view显示到window上
1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 1.手动添加window到screen
self.window = [[UIWindow alloc] init];
self.window.frame = [[UIScreen mainScreen] bounds];
self.window.backgroundColor = [UIColor grayColor];
[self.window makeKeyAndVisible];
// 从xib加载控制器, 设置rootViewController
self.window.rootViewController = [[XibViewController alloc] initWithNibName:@"myx" bundle:nil];
<span style="color: #
<span style="color: #
return YES;
<span style="color: # }
1.storyboard:(这里使用ViewController2为rootViewController)
xib:(使用view1作为显示的view)
B.创建控制器的view
控制器的view创建有多种方式,(按照优先级进行创建,仅使用最优先的方式)
loadView代码(controller实现loadView方法)
storyboard描述
最新版的官方文档:
1.通过loadView
(1)创建一个controller、storyboard、xib
(2)配置好storyboard和xib的class为自定义的controller
(3)给storyboard和xib的view加上明显的标志
(4)在controller类中实现loadView(当controller的view是空的时候,就会调用loadView)
1 // 加载view,这是延迟加载,当需要使用view而view是空的时候调用
2 - (void)loadView {
NSLog(@"loadView...");
self.view = [[UIView alloc] init];
self.view.frame = [[UIScreen mainScreen] bounds];
UILabel *label = [[UILabel alloc] init];
label.frame = CGRectMake(<span style="color: #, <span style="color: #, <span style="color: #0, <span style="color: #0);
label.text = @"loadView";
[self.view addSubview:label];
<span style="color: # }
(5)在delegate中配置controller到window上
a.配置storyboard的controller为rootViewController
1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 配置window
self.window = [[UIWindow alloc] init];
self.window.frame = [[UIScreen mainScreen] bounds];
self.window.backgroundColor = [UIColor grayColor];
// 配置storyboard中的controller为rootViewController
self.window.rootViewController = [[UIStoryboard storyboardWithName:@"test" bundle:nil] instantiateInitialViewController];
<span style="color: #
// 配置xib中的controller为rootViewController,主要要使用带有loadView的controller
<span style="color: # //
self.window.rootViewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
<span style="color: #
<span style="color: #
// 显示window
<span style="color: #
[self.window makeKeyAndVisible];
<span style="color: #
return YES;
<span style="color: # }
<span style="color: #
会发现没有起作用
b.同样,使用xib中的controller为rootViewController,只要loadView存在,也不会起作用
<span style="color: #
// 配置xib中的controller为rootViewController,主要要使用带有loadView的controller
<span style="color: #
self.window.rootViewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
在配置rootViewController的时候,如果配置的controller中实现了loadView方法,就会覆盖storyboard或xib中的view
优质网站模板

我要回帖

更多关于 ios view frame 的文章

 

随机推荐