IOSday04 UIButton使用

UIButton

UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
千万不要这样写:
 btn.titleLabel.text = @"我是按钮";
  • 一般情况下给按钮设置内容都是setXXX
  • [btn setTitle:@"我是按钮" forState:UIControlStateNormal];
  • [btn setTitle:@"哥是高亮" forState:UIControlStateHighlighted];

2.设置标题颜色

  btn.backgroundColor = [UIColor redColor];
 [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    ```
#### 设置图标
```objc
   [btn setImage:[UIImage imageNamed:@"common_icon_check"] forState:UIControlStateNormal];
    ```
####设置背景图片
```objc
   [btn setBackgroundImage:[UIImage imageNamed:@"common_button_big_blue_highlighted"] forState:UIControlStateDisabled];
    ```
####监听按钮的点击
    Target:让谁监听按钮
       action:监听到之后需要执行的方法
       Events:事件的类型
- 规律:
   -  只要是继承于UIControl的控件, 都可以通过addTarget来添加监听
     ```objc
   [btn addTarget:self action:@selector(customBtnClick) forControlEvents:UIControlEventTouchUpInside];
     ```
---   
######UISwitch sw = nil;
 ```objc
   [sw addTarget:<#(nullable id)#> action:<#(nonnull SEL)#> forControlEvents:<#(UIControlEvents)#>]
     ```
###### UISegmentedControl *sc = nil;
 ```objc
  [sc addTarget:<#(nullable id)#> action:<#(nonnull SEL)#> forControlEvents:<#(UIControlEvents)#>]
     ```
###### UITextField *tf = nil;
 ```objc
   [tf addTarget:<#(nullable id)#> action:<#(nonnull SEL)#> forControlEvents:<#(UIControlEvents)#>]
     ```
####设置字体
 ```objc
  btn.titleLabel.font = [UIFont systemFontOfSize:30];
      ```
####设置frame
```objc
   btn.frame = CGRectMake(100, 100, 100, 100);  ```

 ```    [self.view addSubview:btn];  ```

---
###UIButton图片拉伸
   
---    
- iOS5以前

- LeftCapWidth: 左边多少不能拉伸
   - 右边多少不能拉伸 = 控件的宽度 - 左边多少不能拉伸 - 1
    -  right  =  width - leftCapWidth - 1  
    - 1 = width - leftCapWidth - right  

- topCapHeight: 顶部多少不能拉伸
   - 底部有多少不能拉伸 = 控件的高度 - 顶部多少不能拉伸 - 1
   -  bottom =  height - topCapWidth - 1
   - 1 = height - topCapWidth - bottom
   
     ```UIImage *newImage = [image stretchableImageWithLeftCapWidth:5 topCapHeight:5];  ```
----
- iOS5开始
  
   - UIEdgeInsets是告诉系统哪些地方需要受保护, 也就是不可以拉伸
   - resizableImageWithCapInsets默认拉伸方式是平铺
  
  
  ```UIEdgeInsets insets = UIEdgeInsetsMake(image.size.height * 0.5, image.size.width *     0.5, image.size.height * 0.5, image.size.width * 0.5);  ```
   
   - UIImage *newImage =  [image resizableImageWithCapInsets:insets];
  
---
- iOS6开始
  
   - resizingMode指定拉伸模式
    - 平铺
    - 拉伸
     ```UIEdgeInsets insets = UIEdgeInsetsMake(5, 5, 5, 5);  ```
      
       ```objc
   UIImage *newImage =  [image resizableImageWithCapInsets:insets     resizingMode:UIImageResizingModeStretch];

     ```
     
#currentTitle和btn.titlelabel.text 区别
 UIButton *btn = [UIButtonbuttonWithType:UIButtonTypeCustom];

   1、[btn setTitle:@"测试一下" forState:UIControlStateNormal];

   输出:CurrentTitleLabel:测试一下,currentTitle:测试一下。模拟器button上显示:测试一下

   2、btn.titlelabel.text = @"测试一下";

   输出:CurrentTitleLabel:测试一下,currentTitle:(null)。模拟器button上无显示

   3、[btn setTitle:@"测试一下" forState:UIControlStateNormal];

   btn.titlelabel.text = @"测试二下";

   输出:CurrentTitleLabel:测试二下,currentTitle:测试一下。模拟器button上显示:测试二下

   4、btn.titlelabel.text = @"测试二下";

   [btn setTitle:@"测试一下" forState:UIControlStateNormal];

   输出:CurrentTitleLabel:测试一下,currentTitle:测试一下。模拟器button上显示:测试一下

   currentTitle 和titlelabel 不一样。按钮上显示的是CurrnetTitle,而不是titlelabel。    
---    
#KVC
Person *p = [Person new];```

p.name = @"lmj";

p.money = 998;

p.dog = [Dog new];

p.dog.name = @"wangcai";

p.dog.price = 110;

获取单个值

NSString *name = [p valueForKey:@"name"];

double money = [[p valueForKey:@"money"] doubleValue];

获取多层值

NSString *dogName = [p valueForKey:@"dog.name"];
NSString *dogName = [p valueForKeyPath:@"dog.name"];

模型转字典

NSDictionary *dict = [p dictionaryWithValuesForKeys:@[@"name", @"money"]];

获取数组中对象的值
Person *p1 = [Person new];
p1.name = @"zs";
p1.money = 111;

Person *p2 = [Person new];
p2.name = @"ls";
p2.money = 222;

Person *p3 = [Person new];
p3.name = @"ww";
p3.money = 666;

NSArray *arr = @[p1, p2, p3];
  • 如果数组中的元素都是同一种类型的数据, 可以使用KVC获取数组中所有对象的某个属性的值

NSArray *res = [arr valueForKeyPath:@"name"];

运算符

id res1 = [arr valueForKeyPath:@"@avg.money"];

单个值
  • KVC == KEY VALUE CODING
    • Value : 值, 只能传对象
    • forKey: 需要给谁(哪个属性)赋值
    • setValue:forKey:方法, 只能给对象的直接属性赋值
    • [p setValue:@"lmj" forKey:@"name"];
    • @(998.0) == [NSNumber numberWithDouble:(double)]
    • [p setValue:@(668.0) forKey:@"money"];
多层赋值

p.dog = [Dog new];

p.dog.name == [[p dog] setName:]

p.dog.name = @"wangwang";

p.dog.price = 110.0;

  • setValue:forKeyPath: 可以给对象的间接属性赋值. 多层赋值

    • 建议: 以后在开发中都使用setValue:forKeyPath:

    [p setValue:@"xiaoqiang" forKeyPath:@"dog.name"];

[p setValue:@(110) forKeyPath:@"dog.price"];

给私有成员变量赋值

[p setValue:@" ydz " forKey:@"_name"];

[p setValue:@(30) forKey:@"_age"];

  • 用sel可以调用私有方法

    SEL sel = @selector(say);

    [p performSelector:sel];

    [p say];

字典转模型
NSDictionary *dict = @{
                       @"name":@"xxx",
                       @"money": @(998.1),
                                        @"score":@(100)
                       @"dog":@{
                               @"name":@"wangcai",
                               @"price":@(110)
                               }
                       };
     p.name = dict[@"name"];
       p.money = [dict[@"money"] doubleValue];
  • 注意点:
    - 1.如果想使用KVC进行字典转模型, 那么字典中的key必须和模型中的属性一模一样(个数 + 名称)

        ``` this class is not key value coding-compliant for the key score.'```
    
    • 2.如果使用KVC进行字典转模型, 只能对当前调用KVC方法的对象进行转换, 不能对它的属性的对象进行转换
setValuesForKeysWithDictionary:方法内部的实现原理
  • 1.会拿到字典中的key, 然后根据这个key取出字典中的值, 然后再根据这个key赋值给对象

    [p setValue:@"xxx" forKey:@"name"];

    [p setValuesForKeysWithDictionary:dict];


KVO

KVO == Key Value Observing

  • 作用: 可以监听某个对象属性的改变

      Person *p = [Person new];
      p.name = @"ydz";
          p.age = 30;
    
    • 第一个参数: 告诉系统哪个对象监听

    • 第二个参数: 监听当前对象的哪个属性

    • 第三个参数: 监听到属性改变之后, 传递什么值

    • 第四个参数: 需要传递的参数 (这个参数不是传递给属性的)

    • 给p这个对象添加一个监听 , 监听p对象的age属性的改变, 只要age属性改变就通知self

    [p addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];

    p.age = 50;

    NSLog(@"-------------------");

    p.age = 100;

  • 注意: 如果使用KVO监听某个对象的属性, 当对象释放之前一定要移除监听
    reason: 'An instance 0x7f9483516610 of class Person was deallocated while key value observers were still registered with it.

  • 注意: KVO只能监听通过set方法修改的值

KVO的原理:
 只要给一个对象注册一个监听, 那么在运行时, 系统就会自动给该对象生成一个子类对象,
 并且重写自动生成的子类对象的被监听属性的set方法, 然后在set方法中通知监听者
  NSKVONotifying_Person

p->_age = 998;
  • 从p对象上移除self对它的age属性的监听

    [p removeObserver:self forKeyPath:@"age"];

  • 只要监听到属性的改变就会调用

    • keyPath: 被监听的属性名称

    • object : 被监听的对象

    • context: 注册监听的时候传入的值

        - (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary *)change context:    (nullable void *)context
      
        {
        NSLog(@"keyPath = %@, object = %@ , change = %@, context                 = %@", keyPath, object, change, context);
        }
      

提示框(HUD)

1.创建一个AlertController

- (void)touchesBegan:(nonnull NSSet<UITouch *> *)touches     withEvent:(nullable UIEvent *)event
{
       
        UIAlertController *alertVc = [UIAlertController         alertControllerWithTitle:@"标题" message:@"正文"         preferredStyle:UIAlertControllerStyleActionSheet];


UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * __nonnull action) {
    NSLog(@"点击了确定");
}];
UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * __nonnull action) {
    NSLog(@"点击了取消");
}];

[alertVc addAction:action1];
[alertVc addAction:action2];

注意: 如果UIAlertController的样式是ActionSheet, 就不能添加输入框

 reason: 'Text fields can only be added to an alert controller of style UIAlertControllerStyleAlert'

[alertVc addTextFieldWithConfigurationHandler:^(UITextField * __nonnull textField) {
    
}];


2.显示
[self presentViewController:alertVc animated:YES completion:nil];

}

====

1.创建alert控制器

- (void)useAlertControllerAlert
{

UIAlertController *alertVc = [UIAlertController alertControllerWithTitle:@"哥是标题" message:@"姐是正文..." preferredStyle:UIAlertControllerStyleAlert];

// 2.添加一个按钮
// Title : 按钮上显示的文字
// style: 按钮的样式
// handler: 点击按钮之后的回调
UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * __nonnull action) {
    NSLog(@"点击了确定按钮");
}];

UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * __nonnull action) {
    NSLog(@"点击了取消按钮");
}];


[alertVc addAction:action1];
[alertVc addAction:action2];

// 3.添加一个输入框
[alertVc addTextFieldWithConfigurationHandler:^(UITextField * __nonnull textField) {
    textField.text = @"用户名";
    NSLog(@"textField");
}];
[alertVc addTextFieldWithConfigurationHandler:^(UITextField * __nonnull textField) {
    textField.secureTextEntry = YES;
    NSLog(@"textField");
}];
[alertVc addTextFieldWithConfigurationHandler:^(UITextField * __nonnull textField) {
    NSLog(@"textField");
}];

// 4.presentViewController弹出一个控制器
[self presentViewController:alertVc animated:YES completion:nil];

}

===

1.创建UIActionSheet

- (void)useActionSheet
{
// 2.UIActionSheet
//
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"哥是标题" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"确定" otherButtonTitles:@"其它", @"Other", nil];
// 2.显示UIActionSheet
[sheet showInView:self.view];
}

UIActionSheetDelegate

  • 只要UIActionSheet上的按钮被点击就会调用

  • actionSheet:谁触发事件就会把谁传递进来

  • clickedButtonAtIndex:当前被点击按钮的索引

    {
        NSLog(@"%ld", buttonIndex);
    }```
    
    ===
    

1.UIAlerView

  • 如果看到iOS提供的方法中有... 就代表是一个可变参数
  • 可以传一个或者多个

代理的应用场景:

 A对象向监听B对象的变化, A对象就可以成为B对象的代理
 B对象发生一些变化想通知A对象, 那么A对象就可以成为B对象的代理
 
 监听
 
 规律:
    1.以后但凡看到iOS中需要传递对象成为某个对象的代理, 那么直接写上某个对象的类名 + Delegate即可
    2.一般情况下, 代理中的方法都是以控件的名称去掉前缀开头
 例如: 要成为UIAlertView的代理 , 写上 UIAlertViewDelegate


    - (void)useAlert
    {

           UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"哥是标题" message:@"姐是正文..." delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
           
alert.alertViewStyle =  UIAlertViewStyleLoginAndPasswordInput;
        }

UIAlertViewDelegate

  • 只要UIAlertView上的按钮被点击, 就会调用
  • alertView:谁触发事件就会把谁传递进来
  • ButtonAtIndex: 当前被点击按钮的索引
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonInde
posted @ 2015-07-29 00:07  daizeng3344  阅读(297)  评论(0编辑  收藏  举报