iOS UIKit 的复习

1,558 阅读5分钟

这是我参与8月更文挑战的第31天,活动详情查看: 8月更文挑战” juejin.cn/post/698796… ”

引言

相信老粉都知道我连续更文一个多月了,接下来就复习下UIKit 包括delegate

UIKit 框架提供了 iOS 或 Apple tvOS app 所需的基础架构。它提供了用于实施界面的窗口和视图架构,用于向 app 提供多点触控和其他类型输入的事件处理基础架构,以及管理用户、系统和 app 之间互动所需的主运行循环。

除非另有说明,否则请仅从 app 的主线程或主调度队列使用 UIKit 类。此限制尤其适用于从 UIResponder 派生而来的类,或涉及以任何方式操作 app 用户界面的类。

I UIKit 的复习

  1. UIButton->UIControl->UIView
  2. UILabel ->UIView
  3. UIImageView->UIView
  4. UITextField->UIControl->UIView

1.1 设置控件的状态

 NS_CLASS_AVAILABLE_IOS(2_0) @interface UIControl : UIView
 
 @property(nonatomic,getter=isEnabled) BOOL enabled;//启用、禁用控件
 
 @property(nonatomic,getter=isSelected) BOOL selected;//选中、不选中
 
 @property(nonatomic,getter=isHighlighted) BOOL highlighted; //高亮、不高亮

1.2 设置控件内容的布局

 @property(nonatomic) UIControlContentVerticalAlignment contentVerticalAlignment;//垂直居中方法
 
 @property(nonatomic) UIControlContentHorizontalAlignment contentHorizontalAlignment;//水平居中方向

1.3 添加监听方法

 - (void)addTarget:(nullable id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;
 
 - (void)removeTarget:(nullable id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;

II 代理设计模式

是oc中最为广泛的一种设计模式

2.1 代理的作用是什么?

  1. 监听哪些“不能通过addTarget方式监听的“事件

  2. 主要负责在,两对象之间,发生某些事件时,数据或消息的传递工作

2.2 代理实现的步骤

  1. 成为(子)控件的代理;父亲(视图控制器)成为儿子(textField)的代理

  2. 可选步骤:遵守协议,利用ide的提示功能,快速编写代码

  3. 实现协议方法

 
 
 
#import "ViewController.h"
 
 
 
 
@interface ViewController ()<UITextFieldDelegate>
 
 
 
 
@end
 
 
 
 
@implementation ViewController
 
 
 
 
 
 
 
/**
 
  
 
 */
 
- (void)viewDidLoad {
 
    [super viewDidLoad];
 
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeContactAdd];
 
    [btn setCenter:self.view.center];
 
    [self.view addSubview:btn];
 
    //将监听方法click注册到“运行循环”,当触发ControlEvent事件时,由“运行循环”通知Target(ViewController) 执行action(@selector)
 
    //Adds a target and action for a particular event (or events) to an internal dispatch table.将特定事件的执行目标和行动添加到内部调度表
 
    [btn addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
 
     
 
    UITextField *textField = [[UITextField alloc]initWithFrame:CGRectMake(100, 100, 80, 20)];
 
    [textField setText:@"lydia"];
 
    [textField setTextColor:[UIColor blackColor]];
 
    [textField setContentHorizontalAlignment:UIControlContentHorizontalAlignmentCenter];
 
    [textField setDelegate:self];
 
    [self.view addSubview:textField];
 
     
 
     
 
     
 
}
 
 
 
 
#pragma mark - 文本框代理
 
/**
 
 成为代理之后要做的事情是什么?以及如何工作
 
 1》协议:一些预先定义的没有具体的实现方法名,每个方法对应不同的事件。@protocol UITextFieldDelegate <NSObject>
 
 
 
 
 */
 
//Asks the delegate if the specified text should be changed.
 
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
 
    NSLog(@"replacementString =%@, textField = %@,NsRange = %@",string,textField.text,NSStringFromRange(range));
 
    //限制输入的长度
 
    long location = range.location;
 
    return location<7;//YEStrue if the specified text range should be replaced; otherwise, NOfalse to keep the old text.
 
}
 
 
 
 
/**
 
  
 
 */
 
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
 
//    NSLog(@"%s",__FUNCTION__);
 
    return YES;// if an editing session should be initiated
 
 
 
 
}
 
- (void)textFieldDidBeginEditing:(UITextField *)textField{
 
//    NSLog(@"%s",__FUNCTION__);
 
 
 
 
}
 
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField{
 
//    NSLog(@"%s",__FUNCTION__);
 
 
 
 
    return YES;//if editing should stop
 
 
 
 
}
 
- (void)textFieldDidEndEditing:(UITextField *)textField{
 
    NSLog(@"%s",__FUNCTION__);
 
 
 
 
 
 
 
}
 
- (BOOL)textFieldShouldClear:(UITextField *)textField{
 
    NSLog(@"%s",__FUNCTION__);
 
 
 
 
    return YES;//if the text field’s contents should be cleared;
 
}
 
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
 
    NSLog(@"%s",__FUNCTION__);
 
    return YES;//if the text field should implement its default behavior for the return button;
 
}
 
- (void)click:(UIButton *)button{
 
    NSLog(@"%s",__FUNCTION__);
 
    [button removeTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
 
}

III contentSize和contentInset的区别

contentSize 会根据ContentInset调整offset--除了赋值,还实现了其他动作

contentInset不会根据contentSize调整offset--单纯给属性赋值

setter方法的实现差别(可采用设置断点进行查看)

//  ViewController.m
@interface ViewController ()
 
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
 
@property (weak, nonatomic) IBOutlet UIButton *lastButton;
 
@end
 
@implementation ViewController
/**
 
 
 */
 
//系统加载了storyBoard之后,调用setScrollView:方法对scrollView对象进行赋值
 
- (void)setScrollView:(UIScrollView *)scrollView{//本方法先于viewDidLoad:执行;本方法由系统底层自动调用
 
    _scrollView = scrollView;//1》setter 方法的第一句,就是赋值
 
    //2》其他的动作
 
    [_scrollView setContentInset:UIEdgeInsetsMake(64, 0, 10, 0)];
 
    [_scrollView setContentSize:CGSizeMake(0, CGRectGetMaxY(self.lastButton.frame))];
 
}
 
/**
 
 视图加载完成之后执行
 
 */
 
- (void)viewDidLoad {
 
    [super viewDidLoad];
 
    //1.设置间距:只是指定内容外侧的边距,并不会根据contentSize自动调整contentOffset
 
//    [self.scrollView setContentInset:UIEdgeInsetsMake(64, 0, 0, 0)];
 
    //2.  设置滚动视图内容大小
 
    //1> 若有间距contentInset,根据间距自动调整contentOffset
 
    //2> 若无contentInset,contentOffset是(0,0)
 
//    [self.scrollView setContentSize:CGSizeMake(0, CGRectGetMaxY(self.lastButton.frame)+10)];//CGRectGetMaxY(self.lastButton.frame)+10) 是为了能更清楚的显示最后一个按钮
 
    //3.设置偏移位置
 
//    [self.scrollView setContentOffset:CGPointMake(0, -64)];
}
@end

IV 计时器的播放实现

kunnan.blog.csdn.net/article/det…

4.1 将timer添加到运行循环

往运行循环添加timer的方式一

Creates and returns a new NSTimer object and schedules it on the current run loop in the default mode.

  self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTimer:) userInfo:nil repeats:YES];

参数说明

  1. seconds: double 时间间隔
 2. target: The object to which to send the message specified by aSelector when the timer fires. 监听时钟触发的对象
 3. SelectorThe message to send to target when the timer fires.调用的方法
  >The selector should have the following signature: timerFireMethod:
     - (void)timerFireMethod:(NSTimer *)timer

  1. userInfo: The user info for the timer.通常为nil,可用于区分计时器

repeats:if YES, the timer will repeatedly reschedule itself until invalidated. If NO, the timer will be invalidated after it fires.是否重复


 
 
 将timer添加到运行循环的方式二


 
#import "ViewController.h"
 
 
 
 
@interface ViewController () <UIAlertViewDelegate>
 
@property (weak, nonatomic) IBOutlet UILabel *counterLabel;
 
@property (nonatomic,strong) NSTimer *timer;
 
 
 
 
@end
 
 
 
 
@implementation ViewController
 
 
 
 
#pragma mark - 计时器的播放实现
 
- (IBAction)start{
 
    NSLog(@"%s",__FUNCTION__);
 
    //间隔一秒更新counterLabel的显示
 
    //计时器
 
 
    //将timer添加到运行循环的方式二-------------------------------------------
 
    self.timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(updateTimer:) userInfo:nil repeats:YES];
 
    //Registers a given timer with a given input mode.NSRunLoopCommonModes (监听滚动模式)
 
    [[NSRunLoop  currentRunLoop] addTimer:self.timer forMode: NSRunLoopCommonModes];
 
     
 
}
 
 
 
 
 

4.2 时钟更新方法

/**
 
 时钟更新方法
 
 */
 
- (void) updateTimer:(NSTimer *) timer{
 
    //1>取出标签的数字
 
    int count = self.counterLabel.text.intValue;
 
    //若counterLabel.text.intValue =0 ,弹出一些提示信息,否则进行倒计时
 
    if (0 > --count) {//count-- 先赋值,再自减
 
        [self pause];
 
        [[[UIAlertView alloc]initWithTitle:@"start" message:@"In the beginning, laydia" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"done",@"kevin",nil] show];
 
        return;
 
    }
 
    //2》修改counterLabel的text信息
 
    self.counterLabel.text = [NSString stringWithFormat: @"%d",count];//--count 先自减,再赋值
 
    
 
}

4.3 停止时钟

一旦调用invalidate:方法,timer就失效,如果要重新启动时钟,需要重新实例化

- (IBAction)pause{
 
    NSLog(@"%s",__FUNCTION__);
 
    //停止时钟,一旦调用invalidate:方法,timer就失效,如果要重新启动时钟,需要重新实例化
 
    [self.timer invalidate];//唯一停止时钟的方法
 
}
 
- (IBAction)clean{
 
    NSLog(@"%s",__FUNCTION__);
 
}
#pragma mark - UIAlertViewDelegate 的协议方法
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
 
    NSLog(@"%lu",buttonIndex);
 
}
- (void)alertViewCancel:(UIAlertView *)alertView{
 
    NSLog(@"%s",__FUNCTION__);
 
}
-(BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView{
    NSLog(@"%s",__FUNCTION__);
    return NO;
}
 
@end

see also

更多内容请关注公众号:iOS逆向,掘金由于不能自动同步公众号文章,所以想第一时间获取最新文章,敬请关注公众号:iOS逆向

developer.apple.com/cn/document…