引言
相信老粉都知道我连续更文一个多月了,接下来就复习下UIKit 包括delegate
UIKit 框架提供了 iOS 或 Apple tvOS app 所需的基础架构。它提供了用于实施界面的窗口和视图架构,用于向 app 提供多点触控和其他类型输入的事件处理基础架构,以及管理用户、系统和 app 之间互动所需的主运行循环。
除非另有说明,否则请仅从 app 的主线程或主调度队列使用 UIKit 类。此限制尤其适用于从 UIResponder 派生而来的类,或涉及以任何方式操作 app 用户界面的类。
I UIKit 的复习
- UIButton->UIControl->UIView
- UILabel ->UIView
- UIImageView->UIView
- 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 代理的作用是什么?
- 监听哪些“不能通过addTarget方式监听的“事件
- 主要负责在,两对象之间,发生某些事件时,数据或消息的传递工作
2.2 代理实现的步骤
- 成为(子)控件的代理;父亲(视图控制器)成为儿子(textField)的代理
- 可选步骤:遵守协议,利用ide的提示功能,快速编写代码
- 实现协议方法
#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 计时器的播放实现
https://kunnan.blog.csdn.net/article/details/119905079
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];
参数说明
- seconds:double 时间间隔
- target:The object to which to send the message specified by aSelector when the timer fires. 监听时钟触发的对象
- Selector:The message to send to target when the timer fires.调用的方法
>The selector should have the following signature: timerFireMethod:
- (void)timerFireMethod:(NSTimer *)timer
- 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