美文网首页
iOS UI 基础笔记

iOS UI 基础笔记

作者: 马文涛 | 来源:发表于2015-09-10 23:01 被阅读1219次

    UI Basic Note

    UIView的常用方法


    • 获取父/子控件
      1. @property(nonatomic,readonly) UIView *superview;
        获得自己的父控件对象
      2. @property(nonatomic,readonly,copy) NSArray *subviews; 获得自己的所有子控件对象
      3. @property(nonatomic) NSInteger tag;
        控件的ID(标识),父控件可以通过tag来找到对应的子控件。
      4. @property(nonatomic) CGAffineTransform transform; 控件的形变属性(可以设置旋转角度、比例缩放、平移等属性)
    • 添加删除控件
      1. - (void)addSubview:(UIView *) view;添加一个子控件view
      2. - (void)removeFromSuperview; 从父控件中移除
      3. - (UIView *)viewWithTag:(NSInteger)tag; 根据一个tag标识找出对应的控件(一般都是子控件)
    • 控件的位置
      1. @property(nonatomic) CGRect frame; 控件矩形框在父控件中的位置和尺寸(以父控件的左上角为坐标原点)
      2. @property(nonatomic) CGRect bounds; 控件矩形框的位置和尺寸(以自己左上角为坐标原点,所以bounds的x、y一般为0)
      3. @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属性

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

        • UIViewContentModeScaleToFill
          • 将图片拉伸至填充整个imageView
          • 图片显示的尺寸跟imageView的尺寸是一样的
      2. 带有aspect单词的:保持图片原来的宽高比

        • UIViewContentModeScaleAspectFit
          • 保证刚好能看到图片的全部
        • UIViewContentModeScaleAspectFill
          • 拉伸至图片的宽度或者高度跟imageView一样
      3. 没有scale单词的:图片绝对不会被拉伸,保持图片的原尺寸

        • UIViewContentModeCenter
        • UIViewContentModeTop
        • UIViewContentModeBottom
        • UIViewContentModeLeft
        • UIViewContentModeRight
        • UIViewContentModeTopLeft
        • UIViewContentModeTopRight
        • UIViewContentModeBottomLeft
        • UIViewContentModeBottomRight
    1. initWithImage:方法

      • 利用这个方法创建出来的imageView的尺寸和传入的图片尺寸一样
    2. 延迟调用方法

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

    UILabel


    1. 常见属性

      • @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;
        换行模式
    2. UIFont 常用方法

      • + (UIFont *)systemFontOfSize:(CGFloat)fontSize; 系统默认字体
      • + (UIFont *)boldSystemFontOfSize:(CGFloat)fontSize; 粗体
      • + (UIFont *)italicSystemFontOfSize:(CGFloat)fontSize; 斜体
    3. UILabel实现包裹内容

      • 设置宽度约束为 <= 固定值
      • 设置位置约束
      • 不用去设置高度约束

    修改frame的3种方式


    1. 直接使用CGRectMake函数

      imageView.frame = CGRectMake(100, 100, 200, 200);
      
    2. 利用临时结构体变量

      CGRect tempFrame = imageView.frame;
      tempFrame.origin.x = 100;
      tempFrame.origin.y = 100;
      tempFrame.size.width = 200;
      tempFrame.size.height = 200;
      imageView.frame = tempFrame;
      
    3. 使用大括号{}形式

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

    图片的加载方式


    • 有缓存

      UIImage *image = [UIImage imageNamed:@"图片名"];
      
      • 使用场合:图片比较小、使用频率较高
      • 建议把需要缓存的图片直接放到Images.xcassets
    • 无缓存

      NSString *file = [[NSBundle mainBundle] pathForResource:@"图片名" ofType:@"图片的扩展名"];
      UIImage *image = [UIImage imageWithContentsOfFile:@"图片文件的全路径"];
      
      • 使用场合:图片比较大、使用频率较小
      • 不需要缓存的图片不能放在Images.xcassets
      • 放在Images.xcassets里面的图片,只能通过图片名去加载图片

    音频播放


    1. 创建一个音频文件的URL(URL就是文件路径对象)
      • NSURL *url = [[NSBundle mainBundle] URLForResource:@"音频文件名" withExtension:@"音频文件的扩展名"];
    2. 创建播放器
      • self.player = [AVPlayer playerWithURL:url];
    3. 播放
      • [self.player play];
    4. init 内部会调用 initWithFrame方法

    UIButton


    • 监听按钮点击
      • [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
      • 凡是继承自UIControl的控件,都可以通过addTarget:...方法来监听事件
    • 自定义按钮:调整内部子控件的frame
      • 方式1:实现titleRectForContentRect:和imageRectForContentRect:方法,分别返回titleLabel和imageView的frame
      • 方式2:在layoutSubviews方法中设置
    • 内边距
      1. 设置按钮内容的内边距(影响到imageView和titleLabel)
        • @property(nonatomic) UIEdgeInsets contentEdgeInsets;
      2. 设置titleLabel的内边距(影响到titleLabel)
        • @property(nonatomic) UIEdgeInsets titleEdgeInsets;
      3. 设置imageView的内边距(影响到imageView)
        • @property(nonatomic)UIEdgeInsets imageEdgeInsets;

    模型


    • 概念

      • 专门用来存放数据的对象
    • 特点

      • 一般直接继承自NSObject
      • 在.h文件中声明一些用来存放数据的属性
    • 模型定义示例

      @interface Shop : NSObject
      /** 名字 */
      @property (nonatomic, strong) NSString *name;
      /** 图标 */
      @preperty (nonatomic, strong) NSString *icon;
      @end
      
      
    • 字典转模型示例

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

    Plist解析


    1. 获得Plist文件的全路径
      NSBundle *bundle = [NSBundle mainBundle];
      NSString *path = [bundle pathForResource:@"shops" ofType:@"plist"];
      
      
    2. 加载plist文件
      _shops = [NSArray arrayWithContentsOfFile:path];
      

    通过代码自定义控件


    • 继承自系统自带的控件,写一个属于自己的控件
    • 目的:封装控件内部的细节,不让外界关心
    • 步骤
      • 新建一个继承UIView的类
      • initWithFrame:方法中添加子控件
      • layoutSubviews方法中设置子控件的frame
        • 一定要调用[super layoutSubviews];
      • 提供一个模型属性,重写模型属性的set方法
        • 在set方法中取出模型属性,给对应的子控件赋值

    通过xib自定义控件


    • 新建一个继承UIView的类
    • 新建一个xib文件(xib的文件名最好跟控件类名一样)
      • 添加子控件、设置子控件属性
      • 修改最外面那个控件的class为控件类名
      • 将子控件进行连线
    • 提供模型属性,重写模型的set方法
      • 在set方法中给子控件设置数据
    • - (void)awakeFromNib; xib 加载完成之后调用

    view 封装


    • 如果一个view内部的子控件比较多,一般会考虑自定义一个view,把它内部子控件的创建屏蔽起来,不让外界关心
    • 外界可以传入对应的模型数据给view,view拿到模型数据后给内部的子控件设置对应的数据
    • 封装控件的基本步骤
      1. 在initWithFrame:方法中添加子控件,提供便利构造方法
      2. 在layoutSubviews方法中设置子控件的frame(一定要调用super的layoutSubviews)
        增加模型属性,在模型属性set方法中设置数据到子控件上,只要 frame 发生改变就会调用本方法。

    控件初始化调用的方法


    • 一个控件有2种创建方式
      1. 通过代码创建
        初始化时一定会调用initWithFrame:方法
      2. 通过xib\storyboard创建
        -初始化时不会调用initWithFrame:方法,只会调用initWithCoder:方法
        • 初始化完毕后会调用awakeFromNib方法
      3. 有时候希望在控件初始化时做一些初始化操作,比如添加子控件、设置基本属性
        • 这时需要根据控件的创建方式,来选择在initWithFrame:、initWithCoder:、awakeFromNib的哪个方法中操作

    渐变动画

    • 方式1:头尾式

      [UIView beginAnimations:nil context:nil];
      [UIView setAnimationDuration:2.0];
      
      /* 需要执行动画的代码 */
      
      [UIView commitAnimations];
      
      
    • 方式2:block式

          [UIView animateWithDuration:2.0 delay:1.0 options: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(键值监听)

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

    • 步骤

      1. 添加监听器
      • 利用b对象来监听a对象name属性的改变
      [a addObserver:b forKeyPath:@"name" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:@"test"];
      
      1. 在监听器中实现监听方法

        • 如果属性发生改变会自动调用下面方法
        - (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的基本用法
      1. 添加内容到UIScrollVive
      2. 设置 contentSize 属性,滚动范围
      3. 如果 UIScrollView 无法滚动
        • 没有设置 contentSize
        • scrollEnabled = NO;
        • userInteractionEnabled = NO 没有用户交互
          • 设置按钮的userInteractionEnabled并不能让按钮和其他控件达到这个状态
      4. 注意点
        • 通过代码创建的scrollView没有子控件(滚动条)
        • 通过 storyBoard、xib 创建的会有滚动条
    • 常见属性
      1. contentOffset用来表示偏移量,内容左上角与 scrollview 的间距值
      2. contentSize 表示内容的尺寸,滚动的范围
      3. contentInset 内间距,scrollview 4周增加额外的滚动区域,一般用来避免scrollView的内容被其他控件挡住
      4. bounces 是否需要弹簧效果
      5. 始终有弹簧效果(一般用于上/下拉刷新功能),即使没设置 contengSize 也会有效果
        • alwaysBounceVertical
        • alwaysBounceHorizontal
    • Delegate
      1. 设置代理为为控制器的对象(监听 scrollView 的各种行为) scrollView.delegate = 控制器

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

      3. 监听 scrollView 的滚动

        • - (void)scrollViewDidScroll 只要 scrollView 滚动就会调用
        • - (void)scrollViewDidEndDragging...(BOOL)decelerate; 停止滚动有2种状: decelerate 为0表示停止滚动,完全禁止,为1表示用户停止拖拽,由于 scrollview 惯性,会,会继续滚动,并且减速
        • - (void)scrollViewDidEndDecelerating... 表示停止减速
      4. 缩放

        • 实现步骤
          • 设置UIScrollView的id<UIScrollViewDelegate> delegate代理对象
          • 设置minimumZoomScale :缩小的最小比例
          • 设置maximumZoomScale :放大的最大比例
          • 让代理对象实现下面的方法,返回需要缩放的视图控件
          • - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView; 用户在UIScrollView身上使用捏合手势时,UIScrollView会调用代理的viewForZoomingInScrollView:方法,这个方法返回的控件就是需要进行缩放的控件
      5. 分页

        • 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


    1. 代码创建

      • 使用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上
    2. VFL

    • 全称Visual Format Lanuage 可视化格式语言, 是苹果公司为了简化 autolayout 的编码而推出的抽象语言
          H:[cancelButton(72)]-12-[acceptButton(50)]
          canelButton宽72,acceptButton宽50,它们之间间距12
      
          H:[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(...)`
    
    

    相关文章

      网友评论

          本文标题:iOS UI 基础笔记

          本文链接:https://www.haomeiwen.com/subject/hlypcttx.html