关于UIView, UIWindow

本文详细解析了iOS应用启动过程中的关键组件,包括AppDelegate、UIWindow、UIView等,并深入探讨了这些组件之间的交互方式及各自的作用。此外,还介绍了如何初始化窗口、设置视图属性以及理解frame、bounds和center等概念。

程序结构:

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (retain, nonatomic) UIWindow *window;
// 在刚创建好的工程中, 要把属性的strong修饰词改为retain

@end


AppDelegate 继承了 UIResponder 类(响应者),
其中有一个属性: window, 我们用它来显示界面,
AppDelegate 作为 UIApplication 的委托, 实现 UIApplicationDelegate 协议中的方法. 其中的方法都为optional的. 
而方法:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions NS_AVAILABLE_IOS(3_0);
是程序的入口, 一旦第一次打开程序, 就必定走这个方法. 

在这个方法中, 要初始化window属性, 并创建一个window: 
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // 初始化 _window 成员变量
// 此时 _window 所指向内存空间引用计数为2, alloc一次+1, self.window 调用了一次setter方法+1
[self.window setBackgroundColor:[UIColor whiteColor]];
[self.window makeKeyAndVisible]; // 将这个window设置为主显示window, 一个程序可能有多个window, 因此, 需要标注谁是用来主显示的window
// 此步使引用计数再+1
[self.window release]; // 不要忘记release

另: AppDelegate.m 中, 不需要写便利构造器, 初始化方法, 要写dealloc:
- (void)dealloc{
    [self.window release];
    [super dealloc];
}


UIView:
NS_CLASS_AVAILABLE_IOS(2_0) @interface UIView : UIResponder <NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace>

UIView 继承自 UIResponder. *UIResponder is responsible for receiving events.

UIView 中有初始化方法:
- (instancetype)initWithFrame:(CGRect)frame;

UIView在屏幕中定义了一个长方形的区域, 因此有CGRect 类型的 frame属性, 确定其顶点坐标, 长, 宽.

UIView有以下常用属性:
@property(nonatomic) CGRect            frame;
@property(nonatomic) CGRect            bounds;      // default bounds is zero origin, frame size. animatable
@property(nonatomic) CGPoint          center;      // center is center of frame. animatable
@property(nonatomic,copy)            UIColor          *backgroundColor UI_APPEARANCE_SELECTOR;
@property(nonatomic,readonly) UIView      *superview;
@property(nonatomic,readonly,copy) NSArray *subviews; // 该数组装有以当前UIView对象为父视图的直接子视图, 不包括孙子视图
@property(nonatomic,getter=isHidden) BOOL              hidden; // 控制视图的显隐, YES为隐藏, NO为显示, 默认为NO
@property(nonatomic)                 CGFloat          alpha; // 控制视图的透明度, 取值范围:0~1, 父视图改变, 子视图也一起改变, 孙子视图也一起改变
@property(nonatomic)                                 NSInteger tag; // 给视图添加标记, 被加完标记的视图可以使用viewWithTag:方法取得

以及以下常用方法:
- (void)addSubview:(UIView *)view; // 此步使引用计数+1
- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview;
- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;
- (void)bringSubviewToFront:(UIView *)view;
- (void)sendSubviewToBack:(UIView *)view;
- (void)removeFromSuperview;
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index; // 插入到当前第index个元素之前
- (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2;
- (void)sizeToFit; // Resizes and moves the receiver view so it just encloses its subviews. UILabel添加文字时,会让文字不受UILabel高度的影响,但会受高度的影响

每添加一个子视图, 则会在父视图的 subviews 数组中追加该子视图, 同时, 最后添加的子视图会显示在最上面. 也就是说, 数组最后面的视图显示在最上面, 最前面的元素显示在最下面.
对子视图的移动, 子视图的子视图也会随着该子视图移动.

UIWindow:
NS_CLASS_AVAILABLE_IOS(2_0) @interface UIWindow : UIView

UIWindow 继承自 UIViewUIWindow 没有自己的初始化方法, 因此, 初始化 UIWindow 对象时调用父类 UIView 的初始化方法, 如:
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

UIScreen定义了和基于硬件的显示相关的属性( UIScreen object defines the properties associated with a hardware-based display).
mainScreen是UIScreen类中的类方法, 返回值是一个UIScreen对象, 
bounds 是一个CGRect类型的属性: The bounding rectangle of the screen, measured in points. (read-only)

专属UIWindow的主要方法:
- (void)makeKeyAndVisible; 
Makes the receiver the key window and visible.


CGRectCGSizeCGPoint:

CGRectCGSizeCGPoint 都是 CGGeometry 类中定义的结构体:

CGPoint 规定了坐标:
struct CGPoint {
  CGFloat x;
  CGFloat y;
};
typedef struct CGPoint CGPoint;

CGSize规定了宽和高:
struct CGSize {
  CGFloat width;
  CGFloat height;
};
typedef struct CGSize CGSize;

CGRect 整合了 CGSize 和 CGPoint:
struct CGRect {
  CGPoint origin;
  CGSize size;
};
typedef struct CGRect CGRect;

例: 获取一个UIView对象的宽和高: 
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)]; // CGRectMake函数见下
NSLog(@"%g, %g", view1.frame.size.width, view1.frame.size.height);

CGGeometry中常用的函数有:
CG_INLINE CGRect
CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height)
{
  CGRect rect;
  rect.origin.x = x; rect.origin.y = y;
  rect.size.width = width; rect.size.height = height;
  return rect;
}

用来生成一个CGRect对象.
UIKIT_EXTERN NSString *NSStringFromCGRect(CGRect rect);

用来将一个CGRect对象转换为字符串.

关于center, frame和bounce的讨论:

这是API文档的说法:
The frame rectangle, which describes the view’s location and size in its superview’s coordinate system.
                                   描述了视图在父视图的坐标系统中的位置和尺寸

The bounds rectangle, which describes the view’s location and size in its own coordinate system.
                                   描述了视图在自己坐标系统中的位置和尺寸

关于 frame 和 bounds, 以下为 frame 和 bounds 的 get 方法:
-(CGRect)frame{
    return CGRectMake(self.frame.origin.x,self.frame.origin.y,self.frame.size.width,self.frame.size.height);
}

-(CGRect)bounds{
    return CGRectMake(0,0,self.frame.size.width,self.frame.size.height);
}

Demo:

Before:
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];
view1.backgroundColor = [UIColor redColor];
[self.window addSubview:view1];
[view1 release];
   
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view2.backgroundColor = [UIColor yellowColor];
[view1 addSubview:view2];
[view2 release];

After:
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];
view1.backgroundColor = [UIColor redColor];
[self.window addSubview:view1];
[view1 release];
NSLog(@"view1 before: %@", NSStringFromCGRect(view1.frame));
打印结果: view1 before: {{50, 50}, {200, 200}}

UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (retain, nonatomic) UIWindow *window;
// 在刚创建好的工程中, 要把属性的strong修饰词改为retain

@end

view2.backgroundColor = [UIColor yellowColor];
[view1 addSubview:view2];
[view2 release];
NSLog(@"view2 before: %@", NSStringFromCGRect(view2.frame));
// 打印结果:  view2 before: {{0, 0}, {100, 100}}
view1.bounds = CGRectMake(-50, -50, 200, 200);
NSLog(@"view1 after: %@", NSStringFromCGRect(view1.frame));
// 打印结果:  view1 after: {{50, 50}, {200, 200}}
NSLog(@"view2 after: %@", NSStringFromCGRect(view2.frame));
// 打印结果:  view2 after: {{0, 0}, {100, 100}}

            

当view1将顶点坐标设定为(-50, -50)后, view2若还想在父视图view1中(0, 0)的位置, 则需要向右, 向下各移动50, 便定位到了view1的(0, 0)坐标位置. 当子视图添加到父视图时, 会根据父视图的bounds指定的原点(0, 0)计算frame, 而非左上角.

关于center属性
center.x = frame.origin.x + frame.size.width/2;
center.y = frame.origin.y + frame.size.height/2;


***转载请注明出处

已经博主授权,源码转载自 https://pan.quark.cn/s/053f1da40351 在计算机科学领域,MIPS(Microprocessor without Interlocked Pipeline Stages)被视作一种精简指令集计算机(RISC)的架构,其应用广泛存在于教学实践和嵌入式系统设计中。 本篇内容将深入阐释MIPS汇编语言中涉及数组处理的核心概念与实用操作技巧。 数组作为一种常见的数据结构,在编程中能够以有序化的形式储存及访问具有相同类型的数据元素集合。 在MIPS汇编语言环境下,数组通常借助内存地址与索引进行操作。 以下列举了运用MIPS汇编处理数组的关键要素:1. **数据存储**: - MIPS汇编架构采用32位地址系统,从而能够访问高达4GB的内存容量。 - 数组元素一般以连续方式存放在内存之中,且每个元素占据固定大小的字节空间。 例如,针对32位的整型数组,其每个元素将占用4字节的存储空间。 - 数组首元素的地址被称为基地址,而数组任一元素的地址可通过基地址加上元素索引乘以元素尺寸的方式计算得出。 2. **寄存器运用**: - MIPS汇编系统配备了32个通用寄存器,包括$zero, $t0, $s0等。 其中,$zero寄存器通常用于表示恒定的零值,$t0-$t9寄存器用于暂存临时数据,而$s0-$s7寄存器则用于保存子程序的静态变量或参数。 - 在数组处理过程中,基地址常被保存在$s0或$s1寄存器内,索引则存储在$t0或$t1寄存器中,运算结果通常保存在$v0或$v1寄存器。 3. **数组操作指令**: - **Load/Store指令**:这些指令用于在内存与寄存器之间进行数据传输,例如`lw`指令用于加载32位数据至寄存器,`sw`指令...
根据原作 https://pan.quark.cn/s/cb681ec34bd2 的源码改编 基于Python编程语言完成的飞机大战项目,作为一项期末学习任务,主要呈现了游戏开发的基本概念和技术方法。 该项目整体构成约500行代码,涵盖了游戏的核心运作机制、图形用户界面以及用户互动等关键构成部分。 该项目配套提供了完整的源代码文件、相关技术文档、项目介绍演示文稿以及运行效果展示视频,为学习者构建了一个实用的参考范例,有助于加深对Python在游戏开发领域实际应用的认识。 我们进一步研究Python编程技术在游戏开发中的具体运用。 Python作为一门高级编程语言,因其语法结构清晰易懂和拥有丰富的库函数支持,在开发者群体中获得了广泛的认可和使用。 在游戏开发过程中,Python经常与Pygame库协同工作,Pygame是Python语言下的一款开源工具包,它提供了构建2D游戏所需的基础功能模块,包括窗口系统管理、事件响应机制、图形渲染处理、音频播放控制等。 在"飞机大战"这一具体游戏实例中,开发者可能运用了以下核心知识点:1. **Pygame基础操作**:掌握如何初始化Pygame环境,设定窗口显示尺寸,加载图像和音频资源,以及如何启动和结束游戏的主循环流程。 2. **面向对象编程**:游戏中的飞机、子弹、敌人等游戏元素通常通过类的设计来实现,利用实例化机制来生成具体的游戏对象。 每个类都定义了自身的属性(例如位置坐标、移动速度、生命值状态)和方法(比如移动行为、碰撞响应、状态更新)。 3. **事件响应机制**:Pygame能够捕获键盘输入和鼠标操作事件,使得玩家可以通过按键指令来控制飞机的移动和射击行为。 游戏会根据这些事件的发生来实时更新游戏场景状态。 4. **图形显示与刷新**:...
【顶级SCI复现】高比例可再生能源并网如何平衡灵活性与储能成本?虚拟电厂多时间尺度调度及衰减建模(Matlab代码实现)内容概要:本文围绕高比例可再生能源并网背景下虚拟电厂的多时间尺度调度与储能成本优化问题展开研究,重点探讨如何在保证系统灵活性的同时降低储能配置与运行成本。通过构建多时间尺度(如日前、日内、实时)协调调度模型,并引入储能设备衰减建模,提升调度精度与经济性。研究结合Matlab代码实现,复现顶级SCI论文中的优化算法与建模方法,涵盖鲁棒优化、分布鲁棒、模型预测控制(MPC)等先进手段,兼顾风光出力不确定性与需求响应因素,实现虚拟电厂内部多能源协同优化。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事新能源、智能电网、能源互联网领域的工程技术人员。; 使用场景及目标:① 掌握虚拟电厂多时间尺度调度的核心建模思路与实现方法;② 学习如何将储能寿命衰减纳入优化模型以提升经济性;③ 复现高水平SCI论文中的优化算法与仿真流程,服务于科研论文写作与项目开发。; 阅读建议:建议结合文中提供的Matlab代码逐模块分析,重点关注目标函数设计、约束条件构建及求解器调用过程,配合实际案例数据进行调试与验证,深入理解优化模型与物理系统的映射关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值