iOS开发总结 — UI基础(1)

559 阅读6分钟

基本认识

1. 开发步骤

技术点开发步骤
UI(User Interface)搭建基本的软件界面
网络请求、JSON获取网络数据
Model、UITableView显示数据到软件界面

2. UI界面的组成对象

UI界面上的每一个元素都是对象万物皆对象
文本对象UILabel对象
图片对象UIImageView对象
按钮对象UIButton对象

3. 框架

  • 苹果给开发者提供了一个非常强大的UIKit框架,UIKit框架中包含了丰富多彩的各种UI元素
  • 要想做一个出色完整的iOS应用,还需要学习非常多的框架,比如:QuartzCore、MapKit、CoreLocation、AVFoundation等,每一个框架都有特定的实用功能
  • iOS开发,站在巨人的肩膀上编程

新建项目

1. 项目配置

Product Name项目名
Organization Name组织名/公司名
Organization Identifier组织/公司的唯一标识:如公司域名(com.xxx)

2. storyboard文件的简单认识

  • 用来描述软件界面
  • 描述多个界面之间的关系
  • 控制器用来管理软件界面,处理软件界面的交互事件
  • 监听按钮的点击事件:
/// IBAction修饰方法的返回值类型,返回值其实是void
- (IBAction)methodName;

只要按钮触发了事件,就会自动调用控制器里相关联的方法

  • 通过属性来访问storyboard中的UI对象:
/// IBOutlet修饰属性
@Property (nonatomic, weak) IBOutlet UILabel *label;
  • 简单的启动原理:
    运行程序,首先会加载Main.storyboard文件(Xcode默认配置)
    创建箭头—>所指的控制器对象
    把控制器所管理的软件界面显示出来

3. 类扩展的使用

  • 属性非必要,不要声明在头文件里。声明在.m文件的类扩展里
@interface ViewController ()    
@Property (nonatomic, weak) IBOutlet UILabel *label;
@end
  • 类扩展,写在.m文件里,但是写在.h(头文件)里也不会报错
  • .m文件不能被import, 类会被重定义

4. UIViewController的认识

  • 凡是继承自UIViewController的对象,都是控制器
  • 负责处理软件界面的各种事件(如按钮的点击事件)
  • 负责软件界面的创建和销毁
  • 一个控制器只会专门管理一个软件界面

5. 模拟器的使用

  • 支持不同的iOS系统,支持切换机型
  • 支持Rotate、Shake、Home、Lock、Screenshot等
  • 支持定位、设置手机语言等

6. 常见的错误

  • 属性代码被删除了,属性连线还在,需要删除多余的连线
'[<ViewController 0x7f9669904b90> setValue:forUndefinedKey:]:
this class is not key value coding-compliant for the key label.'
  • 调用了一个不存在的方法
'[ViewController test:]: unrecognized selector sent to instance 0x7f99a0c063c0'

UIView

1. 简单介绍

  • 什么是控件?
    屏幕上的所有UI元素都叫控件/视图/组件
    按钮(UIButton)、文本(UILabel)都是控件
  • 控件的共同属性有哪些?
    尺寸、位置、背景色等
  • 苹果将控件的共同属性都抽取到父类UIView中
    所有的控件最终都继承自UIView
  • 每个控件都是个容器,能容纳其他控件
    内部的控件是外部控件的子控件
    外部的控件是内部控件的父控件
    每个控制器(UIViewController)内部都有个默认的UIView属性
    当控制器的View加载完毕的时候会自动调用一次
- (void)viewDidLoad {
	[super viewDidLoad];
}

2. 常见属性

  • 获取自己的父控件对象
@property(nullable, nonatomic,readonly) UIView *superview;
  • 获取自己的所有子控件对象
@property(nonatomic,readonly,copy) NSArray<__kindof UIView *> *subviews;
  • 控件的ID(标识) 父控件可以通过tag来找到对应的子控件
@property(nonatomic) NSInteger tag; // default is 0
  • 控件的形变属性(可以设置旋转角度、比例缩放、平移等属性)
@property(nonatomic) CGAffineTransform transform;

3. 常见方法

  • 添加一个子控件View
- (void)addSubview:(UIView *)view;
  • 从父控件中移除
- (void)removeFromSuperview;
  • 根据一个tag标识找出对应的控件
    视图遍历顺序:
    首先看当前控件的tag是否匹配
    第一个子控件的tag是否匹配
    遍历第一个子控件的子控件,看tag是否匹配
    第二个子控件是否匹配
    ......
    不建议使用该方法,存在性能问题且不好维护
- (nullable __kindof UIView *)viewWithTag:(NSInteger)tag;

4. 位置和尺寸

  • frame、bounds、center
// 控件矩形框在父控件中的位置和尺寸(以父控件的左上角为坐标原点)
@property(nonatomic) CGRect frame;
// 控件矩形框的位置和尺寸(以自己的左上角为坐标原点)
@property(nonatomic) CGRect bounds;
// 控件中心点的位置(以父控件的左上角为坐标原点)
@property(nonatomic) CGPoint center;  

UIImageView

1. frame

  • initWithImage
// 根据传入的图片创建iconImageView, 并且iconImageView的尺寸等于图片的尺寸
UIImageView *iconImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"icon"]];
  • 错误代码:
// 错误原因:不能直接修改OC对象结构体属性的成员
imageView.frame.size.width = 30;
  • 常见写法
    直接使用CGRectMake函数
    利用临时结构体变量
    直接使用结构体赋值
CGRect tempFrame = imageView.frame;  
tempFrame.size.width = 100;
imageView.frame = tempFrame;

// (CGRect)强转二维数组
imageView.frame = (CGRect){{0,0}, {100,100}};

2. 资源引用问题

选择说明
Copy items if needed不勾选,项目文件夹中是没有的,仅仅是引用
尽量勾选,不会影响源文件
Create groups创建一个虚拟文件夹,黄色
Create folder references创建一个真实文件夹,蓝色
Add to targets把图片打包到软件的安装包中
// 获取沙盒路径
po NSHomeDirectory()

3. 帧动画的使用

/// 设置帧动画的图片
@property (nullable, nonatomic, copy) NSArray<UIImage *> *animationImages; 
/// 设置动画的时间
@property (nonatomic) NSTimeInterval animationDuration;
/// 设置动画的次数
@property (nonatomic) NSInteger      animationRepeatCount;  
/// 开始动画
- (void)startAnimating;
/// 停止动画
- (void)stopAnimating;

4. 获取资源路径,播放音频文件

/**
 资源的路径:网络资源 http://www.baidu.com/123/123.png;  
 本地资源 file:///Users/本地资源路径;  
 添加到项目里,通过mainBundle获取
 */
NSBundle *bundle = [NSBundle mainBundle];
// 返回值是NSURL
[bundle URLForResource:@"aaa" withExtension:@"mp3"];
[bundle URLForResource:@"aaa.mp3" withExtension:@"nil"];
// 返回值是NSString
[bundle pathForResource:@"aaa" ofType:@"mp3"];

NSURL *url = [NSURL URLWithString:@""];
// 局部变量会释放,播放失败
self.player = [AVPlayer playerWithURL:url];
[self.player play];

5. 加载无缓存图片

/**
 放在Assets.xcassets文件夹里的图片,只能通过图片名去访问
 没有全路径(mainBundle里的Assets.car文件)
 有缓存
 使用场景:图片比较小,使用频率比较高
 */
[UIImage imageNamed:@"test"];

/**
 不放在Assets.xcassets文件夹里,通过全路径去访问
 只要方法名带有file的,都传全路径
 没有缓存
 使用场景:图片比较大,使用频率比较低
 */
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"imageName" ofType:@"png"];
[UIImage imageWithContentsOfFile:imagePath]

6. 延迟做一些事情

[objc performSelector:@selector(test:) withObject:@"123" afterDelay:10];
// 10秒后调用objc的test:  方法,并且传递参数 @"123"
// objc可以是任何对象