@zhuoming
2016-05-20T03:07:19.000000Z
字数 9277
阅读 678
求知若渴 求真教育iOS UI
打开Xcode应用 
我们可以看到以下界面

点击新建一个Xcode项目

添加项目信息

按下next 并选择项目存放目录后我们的第一个UI项目工程就创建完成了。
接下来我们往项目添加即将学到的第一个控件 UIlable

运行得到的结果如下

至此,我们学会了如何创建一个Xcode项目,并通过StoryBoard 添加简单的UILabel控件。
相关知识点介绍
UIApplication
(1)UIApplication对象是应用程序的象征,一个UIApplication对象就代表一个应用程序。
(2)每一个应用都有自己的UIApplication对象,而且是单例的,如果试图在程序中新建一个UIApplication对象,那么将报错提示。
(3)通过[UIApplication sharedApplication]可以获得这个单例对象
(4) 一个iOS程序启动后创建的第一个对象就是UIApplication对象,且只有一个(通过代码获取两个UIApplication对象,打印地址可以看出地址是相同的)。
UIApplication Delegate
(1)每次新建完项目,都有个带有“AppDelegate”字眼的类,它就是UIApplication的代理,AppDelegate默认已经遵守了UIApplicationDelegate协议,已经是UIApplication的代理。
#import "AppDelegate.h"@implementation AppDelegate// 当应用程序启动完毕的时候就会调用(系统自动调用)- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{NSLog(@"didFinishLaunchingWithOptions");return YES;}// 即将失去活动状态的时候调用(失去焦点, 不可交互)- (void)applicationWillResignActive:(UIApplication *)application{NSLog(@"失去焦点");}// 成为活动的,重新获取焦点(能够和用户交互)- (void)applicationDidBecomeActive:(UIApplication *)application{NSLog(@"成为活动的,重新获取焦点");}// 应用程序进入后台的时候调用 点击home键// 一般在该方法中保存应用程序的数据, 以及状态- (void)applicationDidEnterBackground:(UIApplication *)application{NSLog(@"进入后台");}// 应用程序即将进入前台的时候调用// 一般在该方法中恢复应用程序的数据,以及状态- (void)applicationWillEnterForeground:(UIApplication *)application{NSLog(@"进入前台");}// 应用程序即将被销毁的时候会调用该方法// 注意:如果应用程序处于挂起状态的时候无法调用该方法- (void)applicationWillTerminate:(UIApplication *)application{}// 应用程序接收到内存警告的时候就会调用// 一般在该方法中释放掉不需要的内存- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application{NSLog(@"收到内存警告");}@end
整体流程和原理解释
(1) main函数中执行了一个UIApplicationMain这个函数;
(2)UIApplicationMain函数会根据principalClassName创建UIApplication对象,根据delegateClassName创建一个delegate对象,并将该delegate对象赋值给UIApplication对象中的delegate属性;
(3)接着会建立应用程序的Main Runloop(事件循环,可以理解为里面是一个死循环),进行事件的处理(首先会在程序完毕后调用delegate对象的application:didFinishLaunchingWithOptions:方法) 这个时间循环是一个队列(先进先出)先添加进去的先处理;
(4)程序正常退出时UIApplicationMain函数才返回;

什么是UIView
UIView表示屏幕上的一块矩形区域,它在App中占有绝对重要的地位,因为iOS中几乎所有可视化控件都是UIView的子类。
UIView的功能:1.管理矩形区域里的内容2.处理矩形区域中的事件3.子视图的管理 4.实现动画
UIView的继承图

UIView的属性
描述UIView 位置和大小 的三个结构体:CGPoint、CGSize、CGRect
//-------------------------------// 描述位置struct CGPoint {CGFloat x;CGFloat y;};typedef struct CGPoint CGPoint;//-------------------------------//描述大小struct CGSize {CGFloat width;CGFloat height;};typedef struct CGSize CGSize;//-------------------------------// 描述位置和大小struct CGRect {CGPoint origin; //偏移是相对父视图的CGSize size;};typedef struct CGRect CGRect;
| 常用属性 | 定义 |
|---|---|
| 数据结构 | CGRect、CGPoint、CGSize |
| 标记 | @property(nonatomic) NSInteger tag; |
| 渲染层 | @property(nonatomic,readonly,retain) CALayer *layer; |
| 背景颜色 | @property(nullable, nonatomic,copy) UIColor *backgroundColor |
| 形变 | @property(nonatomic) CGAffineTransform transform; |
| 父视图 | @property(nonatomic,readonly) UIView *superview; |
| 子视图数组 | @property(nonatomic,readonly,copy) NSArray *subviews |
| view所处的window | @property(nonatomic,readonly) UIWindow *window |
| 常用属性 | @property(nonatomic) NSInteger tag; |
| 常用方法 | 定义 |
|---|---|
| 添加子视图 | - (void)addSubview:(UIView *)view; |
| 移除视图 | - (void)removeFromSuperview; |
| 将视图移到前面 | - (void)bringSubviewToFront:(UIView *)view; |
| 将视图移到后面 | - (void)sendSubviewToBack:(UIView *)view; |
| 根据frame初始化 | - (instancetype)initWithFrame:(CGRect)frame |
UIWindow是一种特殊的 UIView ,通常在一个App中只会有一个UIWindow iOS程序启动完毕后,创建的第一个视图控件就是UIWindow,接着创建控制器的view,最后将控制器的view添加到UIWindow上,于是控制器的view就显示在屏幕上了
一个iOS程序之所以能显示到屏幕上,完全是因为它有UIWindow。也就说,没有UIWindow,就看不见任何UI界面
应用程序启动之后,先创建Application,再创建它的代理AppDelegate,之后创建UIWindow。UIWindow继承自UIview。
下面是创建UIWindow的相关代码
// 程序加载完成后- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {// 当前屏幕的尺寸CGRect frame = [UIScreen mainScreen].bounds;// 创建一个uiwindowself.window = [[UIWindow alloc]initWithFrame:frame];// 配置window的属性 背景色设置成紫色self.window.backgroundColor = [UIColor purpleColor];// 成为主窗口 并显示[self.window makeKeyAndVisible];return YES;}
为什么没有初始化AppDelegate里的window也可以往里面添加东西呢?
因为程序先执行Main函数,执行UIApplicationMain(),根据其第三个和第四个参数创建Application,创建代理,并且把代理设置给application,根据项目配置文件info.plist里面的storyboard的name,找到对应的storyboard,接下来创建一个window,之后创建它的初始化控制器(就是箭头所指向的控制器),自动把该控制器设置为UIWindow的根控制器,接下来再将window显示出来,即看到了运行后显示的界面。
课程作业
* 创建不同大小、不同位置、不同颜色的View 添加到UIWindow上
UILabel继承于UIView,拥有UIView的所有属性,具有以下常用属性。
| 常用属性 | 定义 |
|---|---|
| 显示的文本 | @property(nonatomic,copy) NSString *text; |
| 字体 | @property(nonatomic,retain) UIFont *font; |
| 文本颜色 | @property(nonatomic,retain) UIColor *textColor; |
| 行数 | @property(nonatomic) NSInteger numberOfLines; |
| 对齐格式 | @property(nonatomic) NSTextAlignment textAlignment; |
UILabel 基本使用
创建一个UILabel并添加到UIWindow上
UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 44)];// 继承自父类UIView的属性label.center = self.window.center;label.backgroundColor = [UIColor blackColor];// 行数为0代表无限行,其他为最大行数label.numberOfLines = 0;// 显示文本内容label.text = @"新研科技";// 字体类型label.font = [UIFont systemFontOfSize:20];// 字体颜色label.textColor = [UIColor whiteColor];// 居中对齐label.textAlignment = NSTextAlignmentCenter;// 添加到UIWindow上[self.window addSubview:label];

UIlabel高阶使用
字符属性可以应用于 attributed string 的文本中。
NSString *const NSFontAttributeName;(字体)NSString *const NSParagraphStyleAttributeName;(段落)NSString *const NSForegroundColorAttributeName;(字体颜色)NSString *const NSBackgroundColorAttributeName;(字体背景色)NSString *const NSLigatureAttributeName;(连字符)NSString *const NSKernAttributeName;(字间距)NSString *const NSStrikethroughStyleAttributeName;(删除线)NSString *const NSUnderlineStyleAttributeName;(下划线)NSString *const NSStrokeColorAttributeName;(边线颜色)NSString *const NSStrokeWidthAttributeName;(边线宽度)NSString *const NSShadowAttributeName;(阴影)NSString *const NSVerticalGlyphFormAttributeName;(横竖排版)
NSFontAttributeName(字体)
该属性所对应的值是一个 UIFont 对象。该属性用于改变一段文本的字体。如果不指定该属性,则默认为12-point Helvetica(Neue)。
NSParagraphStyleAttributeName(段落)
该属性所对应的值是一个 NSParagraphStyle 对象。该属性在一段文本上应用多个属性。如果不指定该属性,则默认为
NSParagraphStyle 的defaultParagraphStyle 方法返回的默认段落属性。
NSForegroundColorAttributeName(字体颜色)
该属性所对应的值是一个 UIColor 对象。该属性用于指定一段文本的字体颜色。如果不指定该属性,则默认为黑色。
NSBackgroundColorAttributeName(字体背景色)
该属性所对应的值是一个 UIColor 对象。该属性用于指定一段文本的背景颜色。如果不指定该属性,则默认无背景色。
NSLigatureAttributeName(连字符)
该属性所对应的值是一个 NSNumber 对象(整数)。连体字符是指某些连在一起的字符,它们采用单个的图元符号。0 表示没有连体字符。1 表示使用默认的连体字符。2表示使用所有连体符号。默认值为 1(注意,iOS 不支持值为 2)。
NSKernAttributeName(字间距)
该属性所对应的值是一个 NSNumber 对象(整数)。字母紧排指定了用于调整字距的像素点数。字母紧排的效果依赖于字体。值为 0 表示不使用字母紧排。默认值为0。
NSStrikethroughStyleAttributeName(删除线)
该属性所对应的值是一个 NSNumber 对象(整数)。该值指定是否在文字上加上删除线,该值参考“Underline Style Attributes”。默认值是NSUnderlineStyleNone。
NSUnderlineStyleAttributeName(下划线)
该属性所对应的值是一个 NSNumber 对象(整数)。该值指定是否在文字上加上下划线,该值参考“Underline Style Attributes”。默认值是NSUnderlineStyleNone。
NSStrokeColorAttributeName(边线颜色)
该属性所对应的值是一个 UIColor 对象。如果该属性不指定(默认),则等同于 NSForegroundColorAttributeName。否则,指定为删除线或下划线颜色。更多细节见“Drawing attributedstrings that are both filled and stroked”。
NSStrokeWidthAttributeName(边线宽度)
该属性所对应的值是一个 NSNumber 对象(小数)。该值改变描边宽度(相对于字体size 的百分比)。默认为 0,即不改变。正数只改变描边宽度。负数同时改变文字的描边和填充宽度。例如,对于常见的空心字,这个值通常为3.0。
NSShadowAttributeName(阴影)
该属性所对应的值是一个 NSShadow 对象。默认为 nil。
NSVerticalGlyphFormAttributeName(横竖排版)
该属性所对应的值是一个 NSNumber 对象(整数)。0 表示横排文本。1 表示竖排文本。在 iOS 中,总是使用横排文本,0 以外的值都未定义。
代码演示
UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 300, 300)];// 继承自父类UIView的属性label.center = self.window.center;label.numberOfLines = 0;NSMutableAttributedString * string = [[NSMutableAttributedString alloc]initWithString:@"red blue green 一 二 三 四 五"];// 字体颜色[string addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0,3)];[string addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(4,5)];[string addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(9,6)];// 字体[string addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Arial-BoldItalicMT" size:30.0] range:NSMakeRange(0, 3)];[string addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"HelveticaNeue-Bold" size:20.0] range:NSMakeRange(4, 5)];[string addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Courier-BoldOblique" size:30.0] range:NSMakeRange(9, 6)];//下划线[string addAttribute:(NSString *)NSUnderlineStyleAttributeNamevalue:(id)[NSNumber numberWithInt:NSUnderlineStyleSingle]range:NSMakeRange(15, 8)];// 注意不是textlabel.attributedText = string;[self.window addSubview:label];
运行效果如下

UILabel的宽高适配
我们知道UILabel的字体、字号和换行等属性决定了内容的宽高,一旦内容要求size的小于label自身的frame.size后面的字就会用... 来代替。所以我们需要根据内容来计算label的size,然后更新label的Frame。
/*** 方法一 这是常见但(iOS7)已被弃用的方法** @param label.frame.size.width 最大的宽度* @param MAXFLOAT 最大的高度** @return 一个最大不超过约束的尺寸*/CGSize labelSize = [label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(label.frame.size.width, MAXFLOAT)];
/*** 方法二 iOS7后替代了方法一,需要提供一个描述字典(详细参考之前的attributed string 的相关用法)*/NSDictionary *attributes1 = @{NSFontAttributeName:label.font};CGSize labelSize2 = [label.text boundingRectWithSize:CGSizeMake(label.frame.size.width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes1 context:nil].size;
/*** 方法三 最简单的计算方法*/CGSize labelSize3 = [label sizeThatFits:CGSizeMake(label.frame.size.width, MAXFLOAT)];
/*** 方法四 直接自动适配 不需要再更新Frame*/[label sizeToFit];
1、创建一个工程,公司名为 新研科技公司(用whunf代替),项目名自定义,然后在StoryBoard里面拖拽不同label等控件,最后运行到模拟器上。
2、在AppDelegate 的合适方法上手动创建UIWindow,设置window的颜色为红色,并显示出来。
3、在AppDelegate中和合适的方法,创建一般的Label和带描述的Label,并添加到window上。
4、计算Label的size,保证不管Label上的字体有多少都能完整显示。