iOS UI 基础笔记

Li文/马文涛(简书作者)

原文链接://www.greatytc.com/p/a86300ec106c

著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

UI Basic Note

UIView的常用方法

获取父/子控件

@property(nonatomic,readonly) UIView *superview;

获得自己的父控件对象

@property(nonatomic,readonly,copy) NSArray *subviews;获得自己的所有子控件对象

@property(nonatomic) NSInteger tag;

控件的ID(标识),父控件可以通过tag来找到对应的子控件。

@property(nonatomic) CGAffineTransform transform;控件的形变属性(可以设置旋转角度、比例缩放、平移等属性)

添加删除控件

- (void)addSubview:(UIView *) view;添加一个子控件view

- (void)removeFromSuperview;从父控件中移除

- (UIView *)viewWithTag:(NSInteger)tag;根据一个tag标识找出对应的控件(一般都是子控件)

控件的位置

@property(nonatomic) CGRect frame;控件矩形框在父控件中的位置和尺寸(以父控件的左上角为坐标原点)

@property(nonatomic) CGRect bounds;控件矩形框的位置和尺寸(以自己左上角为坐标原点,所以bounds的x、y一般为0)

@property(nonatomic) CGPoint center;控件中点的位置(以父控件的左上角为坐标原点)

UIImageView

UIImageView的常用属性

@property(nonatomic,retain) UIImage *image;显示的图片

@property(nonatomic,copy) NSArray *animationImages;

显示的动画图片

@property(nonatomic) NSTimeInterval animationDuration;动画图片的持续时间

@property(nonatomic) NSInteger animationRepeatCount;

动画的播放次数(默认是0,代表无限播放)

动画

- (void)startAnimating;开始动画

- (void)stopAnimating;停止动画

- (BOOL)isAnimating;是否正在执行动画

contentMode属性

带有scale单词的:图片有可能会拉伸

UIViewContentModeScaleToFill

将图片拉伸至填充整个imageView

图片显示的尺寸跟imageView的尺寸是一样的

带有aspect单词的:保持图片原来的宽高比

UIViewContentModeScaleAspectFit

保证刚好能看到图片的全部

UIViewContentModeScaleAspectFill

拉伸至图片的宽度或者高度跟imageView一样

没有scale单词的:图片绝对不会被拉伸,保持图片的原尺寸

UIViewContentModeCenter

UIViewContentModeTop

UIViewContentModeBottom

UIViewContentModeLeft

UIViewContentModeRight

UIViewContentModeTopLeft

UIViewContentModeTopRight

UIViewContentModeBottomLeft

UIViewContentModeBottomRight

initWithImage:方法

利用这个方法创建出来的imageView的尺寸和传入的图片尺寸一样

延迟调用方法

[abcperformSelector:@selector(stand:)withObject:@"123"afterDelay:10];//10s后自动调用abc的stand:方法,并且传递@"123"参数 makeObjectsPerformSelector 让数组中所有对象都执行者个方法

UILabel

常见属性

@property(nonatomic,copy) NSString *text;显示的文字

@property(nonatomic,retain) UIFont *font;字体

@property(nonatomic,retain) UIColor *textColor;文字颜色

@property(nonatomic) NSTextAlignment textAlignment;对齐模式(比如左对齐、居中对齐、右对齐)

@property(nonatomic) NSInteger numberOfLines;文字行数

@property(nonatomic) NSLineBreakMode lineBreakMode;

换行模式

UIFont 常用方法

+ (UIFont *)systemFontOfSize:(CGFloat)fontSize;系统默认字体

+ (UIFont *)boldSystemFontOfSize:(CGFloat)fontSize;粗体

+ (UIFont *)italicSystemFontOfSize:(CGFloat)fontSize;斜体

UILabel实现包裹内容

设置宽度约束为 <= 固定值

设置位置约束

不用去设置高度约束

修改frame的3种方式

直接使用CGRectMake函数

imageView.frame = CGRectMake(100,100,200,200);

利用临时结构体变量

CGRect tempFrame = imageView.frame; tempFrame.origin.x =100; tempFrame.origin.y =100; tempFrame.size.width =200; tempFrame.size.height =200; imageView.frame = tempFrame;

使用大括号{}形式

imageView.frame = (CGRect){{100,100}, {200,200}};

图片的加载方式

有缓存

UIImage*image = [UIImageimageNamed:@"图片名"];

使用场合:图片比较小、使用频率较高

建议把需要缓存的图片直接放到Images.xcassets

无缓存

NSString*file = [[NSBundlemainBundle] pathForResource:@"图片名"ofType:@"图片的扩展名"];UIImage*image = [UIImageimageWithContentsOfFile:@"图片文件的全路径"];

使用场合:图片比较大、使用频率较小

不需要缓存的图片不能放在Images.xcassets

放在Images.xcassets里面的图片,只能通过图片名去加载图片

音频播放

创建一个音频文件的URL(URL就是文件路径对象)

NSURL *url = [[NSBundle mainBundle] URLForResource:@"音频文件名" withExtension:@"音频文件的扩展名"];

创建播放器

self.player = [AVPlayer playerWithURL:url];

播放

[self.player play];

init 内部会调用 initWithFrame方法

UIButton

监听按钮点击

[button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];

凡是继承自UIControl的控件,都可以通过addTarget:...方法来监听事件

自定义按钮:调整内部子控件的frame

方式1:实现titleRectForContentRect:和imageRectForContentRect:方法,分别返回titleLabel和imageView的frame

方式2:在layoutSubviews方法中设置

内边距

设置按钮内容的内边距(影响到imageView和titleLabel)

@property(nonatomic) UIEdgeInsets contentEdgeInsets;

设置titleLabel的内边距(影响到titleLabel)

@property(nonatomic) UIEdgeInsets titleEdgeInsets;

设置imageView的内边距(影响到imageView)

@property(nonatomic)UIEdgeInsets imageEdgeInsets;

模型

概念

专门用来存放数据的对象

特点

一般直接继承自NSObject

在.h文件中声明一些用来存放数据的属性

模型定义示例

@interfaceShop:NSObject/** 名字 */@property(nonatomic,strong)NSString*name;/** 图标 */@preperty (nonatomic,strong)NSString*icon;@end

字典转模型示例

-(instancetype)initWithDict:(NSDictionary*)dict  {if(self== [superinit]) {self.name= dict[@"name"];self.icon= dict[@"icon"];      }returnself;  }

Plist解析

获得Plist文件的全路径

NSBundle*bundle = [NSBundlemainBundle];NSString*path = [bundle pathForResource:@"shops"ofType:@"plist"];

加载plist文件

_shops = [NSArrayarrayWithContentsOfFile:path];

通过代码自定义控件

继承自系统自带的控件,写一个属于自己的控件

目的:封装控件内部的细节,不让外界关心

步骤

新建一个继承UIView的类

在initWithFrame:方法中添加子控件

在layoutSubviews方法中设置子控件的frame

一定要调用[super layoutSubviews];

提供一个模型属性,重写模型属性的set方法

在set方法中取出模型属性,给对应的子控件赋值

通过xib自定义控件

新建一个继承UIView的类

新建一个xib文件(xib的文件名最好跟控件类名一样)

添加子控件、设置子控件属性

修改最外面那个控件的class为控件类名

将子控件进行连线

提供模型属性,重写模型的set方法

在set方法中给子控件设置数据

- (void)awakeFromNib;xib 加载完成之后调用

view 封装

如果一个view内部的子控件比较多,一般会考虑自定义一个view,把它内部子控件的创建屏蔽起来,不让外界关心

外界可以传入对应的模型数据给view,view拿到模型数据后给内部的子控件设置对应的数据

封装控件的基本步骤

在initWithFrame:方法中添加子控件,提供便利构造方法

在layoutSubviews方法中设置子控件的frame(一定要调用super的layoutSubviews)

增加模型属性,在模型属性set方法中设置数据到子控件上,只要 frame 发生改变就会调用本方法。

控件初始化调用的方法

一个控件有2种创建方式

通过代码创建

初始化时一定会调用initWithFrame:方法

通过xib\storyboard创建

-初始化时不会调用initWithFrame:方法,只会调用initWithCoder:方法

初始化完毕后会调用awakeFromNib方法

有时候希望在控件初始化时做一些初始化操作,比如添加子控件、设置基本属性

这时需要根据控件的创建方式,来选择在initWithFrame:、initWithCoder:、awakeFromNib的哪个方法中操作

渐变动画

方式1:头尾式

[UIViewbeginAnimations:nilcontext:nil];  [UIViewsetAnimationDuration:2.0];/* 需要执行动画的代码 */[UIViewcommitAnimations];

方式2:block式

[UIViewanimateWithDuration:2.0delay:1.0options:kNilOptions animations:^{/*需要执行动画的代码 */} completion:nil]// 1s后,再执行动画(动画持续2s)

图片拉伸

iOS5之前

只拉伸中间的1x1区域

- (UIImage *)stretchableImageWithLeftCapWidth:        (NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight;

iOS5开始

- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets;

- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode; (拉伸还是平铺);

KVC

全称:Key Value Coding(键值编码)

赋值

(void)setValue:(id)value forKey:(NSString *)key;

(void)setValue:(id)value forKeyPath:(NSString *)keyPath;

(void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues;

取值

能取得私有成员变量的值

(id)valueForKey:(NSString *)key;

(id)valueForKeyPath:(NSString *)keyPath;

(NSDictionary)dictionaryWithValuesForKeys:(NSArray)keys;

KVO

全称:Key Value Observing(键值监听)

作用:监听模型的属性值改变

步骤

添加监听器

利用b对象来监听a对象name属性的改变

[a addObserver:b forKeyPath:@"name"options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNewcontext:@"test"];

在监听器中实现监听方法

如果属性发生改变会自动调用下面方法

```

(void)observeValueForKeyPath:(NSString)keyPath ofObject:(id)object change:(NSDictionary)change    context:(void *)context

{

NSLog(@"%@ %@ %@ %@", object, keyPath, change, context);

}

```

如何监听控件的行为

通过addTarget:

只有继承自UIControl的控件,才有这个功能

UIControlEventTouchUpInside : 点击事件(UIButton)

UIControlEventValueChanged : 值改变事件(UISwitch、UISegmentControl、UISlider)

UIControlEventEditingChanged : 文字改变事件(UITextField)

addTarget调用的方法的参数可以把自己传入进去

通过delegate

只有拥有delegate属性的控件,才有这个功能

UIScrollView

UIScrollView的基本用法

添加内容到UIScrollVive

设置 contentSize 属性,滚动范围

如果 UIScrollView 无法滚动

没有设置 contentSize

scrollEnabled = NO;

userInteractionEnabled = NO 没有用户交互

设置按钮的userInteractionEnabled并不能让按钮和其他控件达到这个状态

注意点

通过代码创建的scrollView没有子控件(滚动条)

通过 storyBoard、xib 创建的会有滚动条

常见属性

contentOffset用来表示偏移量,内容左上角与 scrollview 的间距值

contentSize表示内容的尺寸,滚动的范围

contentInset内间距,scrollview 4周增加额外的滚动区域,一般用来避免scrollView的内容被其他控件挡住

bounces是否需要弹簧效果

始终有弹簧效果(一般用于上/下拉刷新功能),即使没设置 contengSize 也会有效果

alwaysBounceVertical

alwaysBounceHorizontal

Delegate

设置代理为为控制器的对象(监听 scrollView 的各种行为) scrollView.delegate =控制器

在私有扩展里面(匿名分类)遵守协议

监听 scrollView 的滚动

- (void)scrollViewDidScroll只要 scrollView 滚动就会调用

- (void)scrollViewDidEndDragging...(BOOL)decelerate;停止滚动有2种状: decelerate  为0表示停止滚动,完全禁止,为1表示用户停止拖拽,由于 scrollview 惯性,会,会继续滚动,并且减速

- (void)scrollViewDidEndDecelerating...表示停止减速

缩放

实现步骤

设置UIScrollView的id delegate代理对象

设置minimumZoomScale :缩小的最小比例

设置maximumZoomScale :放大的最大比例

让代理对象实现下面的方法,返回需要缩放的视图控件

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView;用户在UIScrollView身上使用捏合手势时,UIScrollView会调用代理的viewForZoomingInScrollView:方法,这个方法返回的控件就是需要进行缩放的控件

分页

UIScrollView 的 pageEnabled 设置 YES

@property(nonatomic) NSInteger numberOfPages;一共有多少页

@property(nonatomic) NSInteger currentPage;当前显示的页码

@property(nonatomic) BOOL hidesForSinglePage;只有一页时,是否需要隐藏页码指示器

@property(nonatomic,retain) UIColor *pageIndicatorTintColor;其他指示器页码的颜色

@property(nonatomic,retain) UIColor*currentPageIndicatorTintColor;

当前页码指示器的颜色

NSTimer

NSTimer叫做“定时器”,它的作用如下

在指定的时间执行指定的任务

每隔一段时间执行指定的任务

调用下面的方法就会开启一个定时任务

+ (NSTimer*)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;  每隔ti秒,调用一次aTarget的aSelector方法,yesOrNo决定了是否重复执行这个任务

通过invalidate方法可以停止定时器的工作,一旦定时器被停止了,就不能再次执行任务。只能再创建一个新的定时器才能执行新的任务

- (void)invalidate;

解决定时器在主线程不工作的问题

[[NSRunLoop mainRunLoop]addTimer:timer forMode:NSRunLoopCommonModes];

Autolayout

代码创建

使用NSLayoutConstraint的类方法

+(id)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;  view1 :要约束的控件  attr1 :约束的类型(做怎样的约束)  relation :与参照控件之间的关系  view2 :参照的控件  attr2 :约束的类型(做怎样的约束)  multiplier :乘数  c :常量

添加约束对象到相应的view上

-(void)addConstraint:(NSLayoutConstraint *)constraint;-(void)addConstraints:(NSArray *)constraints;

代码实现Autolayout的注意点

要先禁止autoresizing功能,设置view的下面属性为NO

view.translatesAutoresizingMaskIntoConstraints = NO,添加约束之前,一定要保证相关控件都已经在各自的父控件上不用再给view    设置frame

约束规则创建约束之后,需要将其添加到作用的view上

对于两个同层级view之间的约束关系,添加到它们的父view上

对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上

对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上

VFL

全称Visual Format Lanuage 可视化格式语言, 是苹果公司为了简化 autolayout 的编码而推出的抽象语言

H:[cancelButton(72)]-12-[acceptButton(50)]  canelButton宽72,acceptButton宽50,它们之间间距12H:[wideView(>=60@700)]  wideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束越先被满足)  V:[redBox][yellowBox(==redBox)]  竖直方向上,先有一个redBox,其下方紧接一个高度等于redBox高度的yellowBox  H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|  水平方向上,Find距离父view左边缘默认间隔宽度,  之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField它和FindNext以及父view右边缘的间距都是默认宽度。  竖线“|”表示superview的边缘

使用VFL来创建约束数组

+ (NSArray*)constraintsWithVisualFormat:(NSString*)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary*)metrics views:(NSDictionary*)views;format :VFL语句opts :约束类型metrics :VFL语句中用到的具体数值views :VFL语句中用到的控件

创建一个字典(内部包含VFL语句中用到的控件)的快捷宏定义

NSDictionaryOfVariableBindings(...)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容