关闭

iOS开发系列课程(02) --- 视图交互和事件机制

标签: iOS事件机制UIButton视图控制器
2393人阅读 评论(1) 收藏 举报
分类:

UIButton详解

UIButton和UILabel的区别和联系

  为什么要讨论这个看似没有营养的问题,因为大家都知道UIButton是按钮而UILabel是标签,这明显是两个不同的东西。事实上,UIButton和UILabel都是UIView的子类型,UIView及其子类型都代表一个矩形区域,UILabel直接继承了UIView,而UIButton的父类UIControl继承了UIView,这有什么区别吗?答案是肯定的,UIView有一个叫做userInteractionEnabled的属性,UIView将其默认值设置为YES,但UILabel的这个属性默认是NO。换句话说,只有UIControl的子类将这个属性设置为YES,因此这些控件在默认的情况下是交互型控件,能够跟用户进行交互,比如UIButton可以接受用户点击的操作,而且UIControl的子类可以通过addTarget方法设置要处理的事件及其处理代码。

这里写图片描述

创建和使用UIButton对象

  • +buttonWithType:类方法,在创建按钮时指定按钮的类型。(iOS 7开始取消了圆角矩形按钮类型,但是仍然可以通过其他方式做出圆角矩形的按钮,因为很多时候按钮都是以图片的形态呈现,有了这个圆角矩形反而不方便定制)

UIButton常用属性和方法

配置按钮标题的属性和方法:

  • titleLabel属性:按钮标题的标签
  • -titleForState:方法:指定状态下的按钮标题
  • -setTitle:forState:方法:设置指定状态下按钮的标题
  • -titleColorForState:方法:指定状态下的按钮标题颜色
  • -setTitleColor:forState:方法:设置指定状态下按钮标题的颜色
  • -setTitleShadowColor:forState:方法:设置指定状态下按钮标题阴影的颜色

配置按钮显示的方法:

  • -backgroundImageForState:方法:获得指定状态下的背景图
  • -setBackgroundImage:forState:方法:设置指定状态下的背景图
  • -imageForState:方法:获得指定状态下的按钮图片
  • -setImage:forState:方法:设置指定状态下的按钮图片

配置边距的属性:

  • contentEdgeInsets属性:内容的边距
  • titleEdgeInsets属性:标题的边距
  • imageEdgeInsets属性:图片的边距

获取按钮当前状态的属性:

  • buttonType属性:可能的取值包括UIButtonTypeCustom、UIButtonTypeSystem、UIButtonTypeDetailDisclosure、UIButtonTypeInfoLight、UIButtonTypeInfoDark、UIButtonTypeContactAdd、UIButtonTypeRounedRect(过时)。
  • currentTitle属性:按钮上当前显示的标题
  • currentTitleColor属性:当前标题颜色
  • currentImage属性:按钮上当前显示的图片
  • currentBackgroundImage属性:按钮上当前显示的背景图片
  • imageView属性:按钮上的图片视图

继承自UIControl的属性和方法:

  • -addTarget:action:forControlEvents:方法:将为事件添加的消息接受者和对应的动作加入事件派发表,简而言之就是为控件绑定事件处理的回调方法
  • -removeTarget:action:forControlEvents:方法:与上面方法的作用相反
  • -enabled属性:控件是启动还是禁用
  • -state属性:控件所处的状态

UIButton的常用事件和状态

  我们先说一下UIControl的所有可能的事件。

事件类型 说明
UIControlEventTouchDown 单点触摸按下事件,用户点触屏幕,或者又有新手指落下的时候
UIControlEventTouchDownRepeat 多点触摸按下事件,点触计数大于1:用户按下第二、三、或第四根手指的时候
UIControlEventTouchDragInside 当一次触摸在控件窗口内拖动时
UIControlEventTouchDragOutside 当一次触摸在控件窗口之外拖动时
UIControlEventTouchDragEnter 当一次触摸从控件窗口之外拖动到内部时
UIControlEventTouchDragExit 当一次触摸从控件窗口内部拖动到外部时
UIControlEventTouchUpInside 所有在控件之内触摸抬起事件
UIControlEventTouchUpOutside 所有在控件之外触摸抬起事件(点触必须开始与控件内部才会发送通知)
UIControlEventTouchCancel 所有触摸取消事件,即一次触摸因为放上了太多手指而被取消,或者被上锁或者电话呼叫打断
UIControlEventValueChanged 当控件的值发生改变时,发送通知。用于滑块、分段控件、以及其他取值的控件。你可以配置滑块控件何时发送通知,在滑块被放下时发送,或者在被拖动时发送
UIControlEventEditingDidBegin 当文本控件中开始编辑时发送通知
UIControlEventEditingChanged 当文本控件中的文本被改变时发送通知
UIControlEventEditingDidEnd 当文本控件中编辑结束时发送通知
UIControlEventEditingDidOnExit 当文本控件内通过按下回车键(或等价行为)结束编辑时,发送通知
UIControlEventAlltouchEvents 通知所有触摸事件
UIControlEventAllEditingEvents 通知所有关于文本编辑的事件
UIControlEventAllEvents 通知所有事件

  对于UIButton来说,可能绝大多数处理的都是UIControlEventTouchUpInside事件,简单的说就是按钮点击的事件。

  下面的例子中我们在窗口上放置一个标签和一个按钮,通过点击按钮修改标签上的文字,效果如下图所示。

这里写图片描述

AppDelegate类的实现代码

#import "AppDelegate.h"

@interface AppDelegate () {
    NSArray *infos;
}

@end

@implementation AppDelegate


- (instancetype)init {
    if(self = [super init]) {
        infos = @[@"Hello, world!", @"How are you?", @"Nice to meet you!", @"See you!", @"Good night!"];
    }
    return self;
}


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor whiteColor];

    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGPoint centerPoint = CGPointMake(screenRect.size.width / 2.0, screenRect.size.height / 2.0);

    UILabel *infoLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
    centerPoint.y -= 50;
    infoLabel.center = centerPoint;
    infoLabel.textAlignment = NSTextAlignmentCenter;
    infoLabel.font = [UIFont systemFontOfSize:36];
    infoLabel.text = infos[0];
    infoLabel.textColor = [UIColor redColor];
    infoLabel.tag = 101;
    infoLabel.adjustsFontSizeToFitWidth = YES;

    UIButton *okButton = [UIButton buttonWithType:UIButtonTypeSystem];
    okButton.frame = CGRectMake(0, 0, 80, 40);
    centerPoint.y += 100;
    okButton.center = centerPoint;
    [okButton setTitle:@"OK" forState:UIControlStateNormal];
    okButton.layer.borderColor = [UIColor blackColor].CGColor;
    okButton.layer.borderWidth = 1;
    okButton.layer.cornerRadius = 5;

    [okButton addTarget:self action:@selector(okButtonClicked) forControlEvents:UIControlEventTouchUpInside];

    [self.window addSubview:infoLabel];
    [self.window addSubview:okButton];

    [self.window makeKeyAndVisible];

    return YES;
}

- (void) okButtonClicked {
    UILabel *infoLabel = (id)[self.window viewWithTag:101];
    int randomIndex = arc4random() % [infos count];
    infoLabel.text = infos[randomIndex];
}

@end

自定义UIButton

  为什么需要定制按钮呢,如果大家用过酷狗音乐就知道,它的播放按键是带进度提示功能的,这样的按钮肯定需要我们自行定制,看看下面的例子。

这里写图片描述

#import <UIKit/UIKit.h>

/**带进度的按钮*/
@interface CDMyPlayButton : UIButton

/**完成进度(0.0-1.0)*/
@property (nonatomic, assign) double value;

@end
#import "CDMyPlayButton.h"

@implementation CDMyPlayButton

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
    UIBezierPath *bezierPath = [[UIBezierPath alloc] init];
    CGFloat centerX = rect.size.width / 2.0;
    CGFloat centerY = rect.size.height / 2.0;
    CGFloat radius = centerX;
    [bezierPath addArcWithCenter:CGPointMake(centerX, centerY) radius:radius * 0.8 startAngle:-M_PI_2 endAngle:M_PI * 2 * self.value - M_PI_2 clockwise:YES];

    [[UIColor cyanColor] setStroke];
    bezierPath.lineWidth = 2;
    [bezierPath stroke];
}

@end

UIImage简介

  UIImage是用来显示图像的对象。我们可以通过文件、接收到原始的数据或者Quartz图像对象来创建UIImage对象。

创建UIImage对象的方式

  • +imageNamed:类方法:根据指定的文件名返回UIImage对象
  • +imageWithData:类方法:根据指定的NSData对象创建UIImage对象
  • -imageWithContentOfFile:方法:通过文件加载指定路径下的内容获得UIImage对象
  • -imageWithCGImage:方法:通过Quartz 2D对象创建UIImage对象
  • -imageWithCIImage:方法:通过Core Image对象创建UIImage对象
    // 此种方式会对加载的图片进行单例处理,不适合动态加载大量图片,因为单例对象会一直存在于内存中
    UIImage *image1 = [UIImage imageNamed:@"abc"];

    NSString * strPath = [[NSBundle mainBundle]  pathForResource:@"abc" ofType:@"png"];
    // 此方式适合本地动态加载大量图片,而且即使加载很大的图片也不会使程序崩溃,前一种方式加载大图片可能会出现问题
    UIImage *image2 = [UIImage imageWithContentsOfFile:strPath];

    // 通过制定URL得到的数据创建图片对象
    UIImage *image3 =[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://www.baidu.com/img/bdlogo.png"]]];

  此外,还可以通过一组图片和一个持续时间来创建一个动态UIImage对象。

UIImage对象的属性

  • size属性:图像的大小,得到一个CGSize结构体,其中包括了宽度(width)和高度(height)。

绘制图像

  • -drawAtPoint:方法:从指定的左上角坐标处绘制图像。
  • -drawInRect:方法:在指定的矩形区域内绘制整个图像。

UIViewController入门

概念和作用

  UIViewController可以管理一屏的内容,如果说UIWindow是一副画的画框,那么UIViewController就是画框中植入的一张画布。我们并不建议将所有的视图对象或子视图都直接置于UIWindow对象中,因为UIWindow对象是唯一的,如果要想改变用户界面就会非常的麻烦。如果使用UIViewController来管理用户界面的话,在切换用户界面时只需要更换一个视图控制器就可以了。

  它定义了一系列和生命周期相关的方法。下面的图展示了UIViewController的生命周期,详细的内容我们在后续的课程中跟大家分享。

  视图控制器加载:

  视图控制器收到内存警告:

如何将UIViewController和UIWindow关联

  我们可以创建一个视图控制器并将第一个例子中在UIWindow上放置的按钮和标签放到视图控制器中,再通过UIWindow对象的rootViewController属性将视图控制器设置为窗体对象的根视图控制器,代码如下所示:

  自定义视图控制器的代码如下所示。

#import "CDRootViewController.h"

@interface CDRootViewController () {
    NSArray *infos;
}

@end

@implementation CDRootViewController

- (instancetype)init {
    if(self = [super init]) {
        infos = @[@"Hello, world!", @"How are you?", @"Nice to meet you!", @"See you!", @"Good night!"];
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    // 将直接放在AppDelegate中的代码转移到视图控制器中
    // 将原来直接放到UIWindow上的视图添加到视图控制器的视图中
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGPoint centerPoint = CGPointMake(screenRect.size.width / 2.0, screenRect.size.height / 2.0);

    UILabel *infoLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
    centerPoint.y -= 50;
    infoLabel.center = centerPoint;
    infoLabel.textAlignment = NSTextAlignmentCenter;
    infoLabel.font = [UIFont systemFontOfSize:36];
    infoLabel.text = infos[0];
    infoLabel.textColor = [UIColor redColor];
    infoLabel.tag = 101;
    infoLabel.adjustsFontSizeToFitWidth = YES;

    UIButton *okButton = [UIButton buttonWithType:UIButtonTypeSystem];
    okButton.frame = CGRectMake(0, 0, 80, 40);
    centerPoint.y += 100;
    okButton.center = centerPoint;
    [okButton setTitle:@"OK" forState:UIControlStateNormal];
    okButton.layer.borderColor = [UIColor blackColor].CGColor;
    okButton.layer.borderWidth = 1;
    okButton.layer.cornerRadius = 5;
    okButton.layer.shadowColor = [UIColor yellowColor].CGColor;
    okButton.layer.shadowRadius = 10;

    [okButton addTarget:self action:@selector(okButtonClicked) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:infoLabel];
    [self.view addSubview:okButton];
}

- (void) okButtonClicked {
    UILabel *infoLabel = (id)[self.view viewWithTag:101];
    int randomIndex = arc4random() % [infos count];
    infoLabel.text = infos[randomIndex];

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.5];
    [UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.view cache:YES];
    [UIView commitAnimations];
}

@end

  AppDelegate的代码如下所示。

#import "AppDelegate.h"
#import "CDRootViewController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor whiteColor];

    // 创建视图控制器对象
    CDRootViewController *rvc = [[CDRootViewController alloc] init];
    // 将视图控制器设置为窗口的根视图控制器
    self.window.rootViewController = rvc;

    [self.window makeKeyAndVisible];


    return YES;
}
@end
1
0
查看评论

sql语法练习(二)

--1、查询"01"课程比"02"课程成绩高的学生的信息及课程分数  --1.1、查询同时存在"01"课程和"02"课程的情况  select a.* , b.score ...
  • jiaxiaokai
  • jiaxiaokai
  • 2015-10-20 17:24
  • 651

iOS开发系列课程(01) --- iOS编程入门

如果你已经有了C和Objective-C的基础并且想了解iOS开发,就从这里开始吧。
  • jackfrued
  • jackfrued
  • 2015-07-04 00:53
  • 3462

iOS开发系列课程(10) --- 表格视图

UITableView(表格视图)是iOS应用程序开发中应用最广泛的一个控件,几乎十有八九的应用程序中都会用到它,它是基于滚动视图的列表互动类。使用UITableView可以在屏幕上显示单元格的列表,每个单元格中还可以包含多项信息,iPhone上很多自带的程序其导航方式都是以表格为中心,最经典的就是...
  • jackfrued
  • jackfrued
  • 2015-10-07 17:38
  • 6312

【B类】BI商业智能、大数据、Mysql、等系列课程集

一.天善智能BI课程系列 1.1  天善智能 BIEE课程                              ...
  • snowfoxmonitor
  • snowfoxmonitor
  • 2016-03-06 17:04
  • 2606

当前视图 可交互与不可交互

当前视图设为view=bigimgView.userInteractionEnabled=NO 时,当前视图不可交互, 该视图上面的子视图也不可交互(不可响应),响应事件传递到下面的父视图。 当前视图设为view=bigimgView.userInteractionEnabled...
  • sqc3375177
  • sqc3375177
  • 2014-04-01 16:26
  • 2010

IOS开发系列——UIView专题之四:事件分发机制篇【整理,部分原创】

4事件分发机制 iOS中的事件大概分为三种,分别是Milti-Touch Events, Motion Events和Remote Control Events(events for controlling multimedia)。 4.1hitTest iOS事件分发机制(一)hit-Te...
  • junbaozi
  • junbaozi
  • 2016-01-09 16:59
  • 633

iOS开发系列课程预告

基于Swift的iOS开发入门指南,包括了对函数式编程和面向对象编程的思考以及对Objective-C和Swift两种语言的探讨。
  • jackfrued
  • jackfrued
  • 2014-09-18 00:58
  • 2780

ie事件机制和火狐事件机制

事件机制 事件冒泡:事件从当前元素对象触发,然后向上层元素搜索相同对象事件并触发(直搜到document节点)。IE事件默认都只这种类型的事件。 事件捕获:从document节点开始搜索事件,然后向下层搜索相同对象事件并触发,直到当前元素节点 阻止事件冒泡的方法 ie支持事件冒泡 火狐支持...
  • sinat_32067081
  • sinat_32067081
  • 2017-03-28 10:27
  • 1520

WPF基础到企业应用系列1——开篇有益

2010-07-05 07:05 by 圣殿骑士 1.开篇前言 关于本人——圣殿骑士刚入住博客园和51CTO写技术博客,目前主要在一家外资企业从事项目管理、技术架构及企业技术培训工作。由于工作和项目需要,所以对一些技术进行了较为深入的研究,之前在整个公司做过一些技术专场的培训,由于每次时间较短...
  • bigpudding24
  • bigpudding24
  • 2015-11-01 22:10
  • 877

《VC++专题研究》系列之-1- 本系列课程综述

<br />内容简介:<br />《VC++专题研究》系列视频综述,希望通过本系列视频的讲解,让大家得到实实在在的VC开发技巧和必备知识。这里没有多余的语言讲解,只有真正实用、好用、高效的开发实例和技巧展现给大家。你可以是VC的初学者,你可以是一名在职的开发者,在这里都能找到...
  • jhkdiy
  • jhkdiy
  • 2011-04-15 21:08
  • 749
    个人资料
    • 访问:2127722次
    • 积分:9133
    • 等级:
    • 排名:第2426名
    • 原创:116篇
    • 转载:0篇
    • 译文:0篇
    • 评论:806条
    文章分类
    最新评论