基础笔记

作者: 网络工程  发布:2019-09-13
  • 作用
    • 能为某个类增加额外的属性、成员变量、方法声明
    • 一般将类扩展写到.m文件中
    • 一般将一些私有的属性写到类扩展
  • 使用格式

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; 控件中点的位置(以父控件的左上角为坐标原点)
@interface 类名()/* 属性、成员变量、方法声明 */@end

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}};
    
@interface 类名/* 方法声明 */@end@implementation 类名/* 方法实现 */@end

- 分类只能扩充方法- 如果在分类中声明了一个属性,分类只会生成这个属性的getset方法声明,`并不会生成成员变量`

图片的加载方式


  • 有缓存

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

    NSString *file = [[NSBundle mainBundle] pathForResource:@"图片名" ofType:@"图片的扩展名"];
    UIImage *image = [UIImage imageWithContentsOfFile:@"图片文件的全路径"];
    
    • 使用场合:图片比较大、使用频率较小
    • 不需要缓存的图片不能放在Images.xcassets
    • 放在Images.xcassets里面的图片,只能通过图片名去加载图片
  • Product Name
    • 产品名称
    • 项目名称
    • 软件名称
  • Organization Name
    • 公司名称
  • Organization Identifier
    • 公司的唯一标识
    • 一般用网站域名的反写形式
  • Bundle Identifier
    • 软件的唯一标识
    • 默认 == Organization Identifier + Product Name

音频播放


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

九宫格的计算方式

/************** 一些常用的变量 begin **************/// 每一行的列数NSUInteger colsPerRow = 3;// 获得当前商品的索引NSUInteger index = self.shopsView.subviews.count;// 商品宽度CGFloat shopW = 70;// 商品高度CGFloat shopH = 90;/************** 一些常用的变量 end **************/ /************** 计算X值 begin **************/// 求出列号NSUInteger col = index % colsPerRow;// 每一列之间的间距CGFloat xMargin = (self.shopsView.frame.size.width - colsPerRow * shopW) / (colsPerRow - 1);// 商品XCGFloat shopX = (shopW + xMargin) * col;/************** 计算X值 end **************/ /************** 计算Y值 begin **************/// 求出行号NSUInteger row = index / colsPerRow;// 每一行之间的间距CGFloat yMargin = 20;// 商品YCGFloat shopY = (shopH + yMargin) * row;/************** 计算X值 end **************/

// 内容模式:一般用来控制图片如何显示imageView.contentMode = UIViewContentModeScaleAspectFit;// 裁剪超出imageView边框的部分imageView.clipsToBounds = YES;// 设置动画图片self.imageView.animationImages;// 设置播放次数self.imageView.animationRepeatCount// 设置动画的时间self.imageView.animationDuration// 开始动画[self.imageView startAnimating];

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;

contentMode属性

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

    • UIViewContentModeScaleToFill
      • 将图片拉伸至填充整个imageView
      • 图片显示的尺寸跟imageView的尺寸是一样的
    • 带有aspect单词的:保持图片原来的宽高比
      • UIViewContentModeScaleAspectFit
      • 保证刚好能看到图片的全部
      • UIViewContentModeScaleAspectFill
      • 拉伸至图片的宽度或者高度跟imageView一样
  • 没有scale单词的:图片绝对不会被拉伸,保持图片的原尺寸

    • UIViewContentModeCenter
    • UIViewContentModeTop
    • UIViewContentModeBottom
    • UIViewContentModeLeft
    • UIViewContentModeRight
    • UIViewContentModeTopLeft
    • UIViewContentModeTopRight
    • UIViewContentModeBottomLeft
    • UIViewContentModeBottomRight
  • 不能直接修改:OC对象的结构体属性的成员
  • 下面的写法是错误的
imageView.frame.size = imageView.image.size;
  • 正确写法
CGRect tempFrame = imageView.frame;tempFrame.size = imageView.image.size;imageView.frame = tempFrame;
  • 利用这个方法创建出来的imageView的尺寸和传入的图片尺寸一样
  • 直接使用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 = {{100, 100}, {200, 200}};
  • 图片的加载方式
  • 1、有缓存
UIImage *image = [UIImage imageNamed:@"图片名"];//使用场合:图片比较小、使用频率较高//建议把需要缓存的图片直接放到Images.xcassets
  • 2、无缓存
NSString *file = [[NSBundle mainBundle] pathForResource:@"图片名" ofType:@"图片的扩展名"];UIImage *image = [UIImage imageWithContentsOfFile:@"图片文件的全路径"];//使用场合:图片比较大、使用频率较小//不需要缓存的图片不能放在Images.xcassets//放在Images.xcassets里面的图片,只能通过图片名去加载图片
  • 凡是继承自UIControl的控件,都可以通过addTarget:...方法来监听事件
  • 内容包含模式
UILabel *la = [[UILabel alloc] init];la.lineBreakMode = NSLineBreakByWordWrapping;//保持单词的完整性
  • assign
    • 基本数据类型枚举结构体等非OC对象类型
  • weak
    • OC对象类型(比如NSArray、NSDate、NSNumber、模型类)
  • strong
    • OC对象类型(比如NSArray、NSDate、NSNumber、模型类)
    • 一个对象只要有强指针引用着,就不会被销毁
  • copy
    • 一般用在NSStringblock类型上

模型


  • 概念

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

    • 一般直接继承自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;
    }
    

1、通过纯代码自定义控件

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

Plist解析


  1. 获得Plist文件的全路径

    NSBundle *bundle = [NSBundle mainBundle];
    NSString *path = [bundle pathForResource:@"shops" ofType:@"plist"];
    
  2. 加载plist文件

    _shops = [NSArray arrayWithContentsOfFile:path];
    

2、通过xib自定义控件

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

通过代码自定义控件


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

中间的提醒内容

  • 指示器、HUD、遮盖、蒙板
  • 半透明的指示器如何实现?
    • 指示器的alpha = 1.0
    • 指示器的背景色是半透明的

通过xib自定义控件


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

创建颜色

  • 直接创建对应的颜色
+ (UIColor *)blackColor; // 0.0 white+ (UIColor *)darkGrayColor; // 0.333 white+ (UIColor *)lightGrayColor; // 0.667 white+ (UIColor *)whiteColor; // 1.0 white+ (UIColor *)grayColor; // 0.5 white+ (UIColor *)redColor; // 1.0, 0.0, 0.0 RGB+ (UIColor *)greenColor; // 0.0, 1.0, 0.0 RGB+ (UIColor *)blueColor; // 0.0, 0.0, 1.0 RGB+ (UIColor *)cyanColor; // 0.0, 1.0, 1.0 RGB+ (UIColor *)yellowColor; // 1.0, 1.0, 0.0 RGB+ (UIColor *)magentaColor; // 1.0, 0.0, 1.0 RGB+ (UIColor *)orangeColor; // 1.0, 0.5, 0.0 RGB+ (UIColor *)purpleColor; // 0.5, 0.0, 0.5 RGB+ (UIColor *)brownColor; // 0.6, 0.4, 0.2 RGB+ (UIColor *)clearColor; // 透明色

view 封装


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

按钮

  • 自定义按钮:调整内部子控件的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;

控件初始化调用的方法


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

图片拉伸

  • iOS5之前
// 只拉伸中间的1x1区域- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight;
  • iOS5开始
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets;- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode;

渐变动画

  • 方式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)
    

拷贝

  • 实现拷贝的方法有2个
    • copy:返回不可变副本
    • mutableCopy:返回可变副本
  • 普通对象实现拷贝的步骤
    • 遵守NSCopying协议
    • 实现-copyWithZone:方法
      • 创建新对象
      • 给新对象的属性赋值

图片 1copy

  • 全称:Key Value Coding
  • 赋值
// 能修改私有成员变量- setValue:value forKey:(NSString *)key;- setValue:value forKeyPath:(NSString *)keyPath;- setValuesForKeysWithDictionary:(NSDictionary *)keyedValues;
  • 取值
// 能取得私有成员变量的值- valueForKey:(NSString *)key;- valueForKeyPath:(NSString *)keyPath;- (NSDictionary *)dictionaryWithValuesForKeys:(NSArray *)keys;

图片拉伸


  • iOS5之前
    • 只拉伸中间的1x1区域
      • - (UIImage *)stretchableImageWithLeftCapWidth: (NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight;
  • iOS5开始
    • - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets;
    • - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode; (拉伸还是平铺);

KVO

  • 全称:Key Value Observing
  • 作用:监听模型的属性值改变
  • 步骤
    • 添加监听器
// 利用b对象来监听a对象name属性的改变[a addObserver:b forKeyPath:@"name" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:@"test"];
  • 在监听器中实现监听方法
 -observeValueForKeyPath:(NSString *)keyPath ofObject:object change:(NSDictionary *)change context:context { NSLog(@"%@ %@ %@ %@", object, keyPath, change, context); }
  • 定义一份代理协议
    • 协议名字的格式一般是:类名 + Delegate
      • 比如UITableViewDelegate
    • 代理方法细节
      • 一般都是@optional
      • 方法名一般都以类名开头
        • 比如- scrollViewDidScroll:
      • 一般都需要将对象本身传出去
        • 比如tableView的方法都会把tableView本身传出去
    • 必须要遵守NSObject协议
      • 比如@protocol XMGWineCellDelegate <NSObject>
  • 声明一个代理属性
    • 代理的类型格式:id<协议> delegate
@property (nonatomic, weak) id<XMGWineCellDelegate> delegate;
  • 设置代理对象
xxx.delegate = yyy;
  • 代理对象遵守协议,实现协议里面相应的方法
  • 当控件内部发生了一些事情,就可以调用代理的代理方法通知代理
    • 如果代理方法是@optional,那么需要判断方法是否有实现
if ([self.delegate respondsToSelector:@selector(wineCellDidClickPlusButton:)]) { [self.delegate wineCellDidClickPlusButton:self];}
  • 通过addTarget:
    • 只有继承自UIControl的控件,才有这个功能
    • UIControlEventTouchUpInside : 点击事件
    • UIControlEventValueChanged : 值改变事件(UISwitch、UISegmentControl、UISlider)
    • UIControlEventEditingChanged : 文字改变事件(UITextField)
  • 通知(NSNotificationCenterNSNotification)
    • 任何对象之间都可以传递消息
    • 使用范围
      • 1个对象可以发通知给N个对象
      • 1个对象可以接受N个对象发出的通知
    • 必须得保证通知的名字在发出和监听时是一致的
  • KVO
    • 仅仅是能监听对象属性的改变(灵活度不如通知和代理)
  • 代理delegate
    • 只有拥有delegate属性的控件,才有这个功能
    • 使用范围
      • 1个对象只能设置一个代理(假设这个对象只有1个代理属性)
      • 1个对象能成为多个对象的代理
    • 通知规范
    • 建议使用代理多于通知

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;

1.全局刷新

[self.tableView reloadData];

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);
      }
      

2.局部刷新

  • 2.1 增加模型数组
//在index插入一个模型数据-insertObject:anObject atIndex:(NSUInteger)index;//添加模型- addObject:anObject;
  • 2.1.1 增加数据后刷新
-insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
  • 2.2 删除模型数组
//移除最后一个模型- removeLastObject;//移除index位置的的数据模型- removeObjectAtIndex:(NSUInteger)index;//用anObject取代index位置的模型- replaceObjectAtIndex:(NSUInteger)index withObject:anObject;
  • 2.2.1 删除数据后刷新
-deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
  • 2.3 更改模型数组
-reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;

如何监听控件的行为


  • 通过addTarget:
    • 只有继承自UIControl的控件,才有这个功能
    • UIControlEventTouchUpInside : 点击事件(UIButton)
    • UIControlEventValueChanged : 值改变事件(UISwitch、UISegmentControl、UISlider)
    • UIControlEventEditingChanged : 文字改变事件(UITextField)
    • addTarget 调用的方法的参数可以把自己传入进去
  • 通过delegate
    • 只有拥有delegate属性的控件,才有这个功能

左滑删除功能

//只要实现了这个方法,左滑出现Delete按钮的功能就有了;点击了“左滑出现的Delete按钮”也会调用这个方法-tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;//修改右侧Delete的文字-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath;
  • 2.左滑出现多个按钮
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{UITableViewRowAction *action0 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"关注" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) { NSLog; // 收回左滑出现的按钮 tableView.editing = NO; }]; UITableViewRowAction *action1 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"删除" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) { [self.wineArray removeObjectAtIndex:indexPath.row]; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; }]; return @[action1, action0];}

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;
        当前页码指示器的颜色

批量删除功能

//开启批量删除功能[self.tableView setEditing:!self.tableView.isEditing animated:YES];//开启批量删除功能后,可以编辑self.tableView.allowsMultipleSelectionDuringEditing = YES;

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(...)`

本文由今晚买四不像发布于网络工程,转载请注明出处:基础笔记

关键词:

上一篇:没有了
下一篇:没有了