第五講: 設計模式,手勢識别器
本講内容
一. Target/action設計模式
耦合: 耦合是衡量子產品與子產品之間關聯程度的名額, 它是衡量一個程式寫的好壞的标準之一
“高内聚,低耦合”是面向對象程式設計的核心思想
// 試想 系統點選方法touches實作點選事件的劣(lie, 四聲)勢
每個視圖的點選事件都不一樣,如何處理?
我們無法預先知道這個視圖點選之後都要實作什麼效果
是以我們在類内部提前寫好點選事件不科學也不全面
// 使用Target/action實作解耦
二. 代理設計模式
Delegate模式: 當一個類的某些功能需要被别人來實作,但是既不明确是些什麼功能,又不明确誰來實作這些功能的時候,委托模式就可以派上用場, 其目的是為了降低類之間的耦合性
//如何用Delegate實作解耦
delegate也是用來解耦的,它不再簡簡單單讓目标去執行一個動
作了, 而是delegate去處理一系列事件、就像UITextFieldDelegate一樣,能監測将要開始編輯,已經開始編輯、return按鈕點選等等
Delegate使用場景
控件有一系列時間點,控制器可以實作這個代理方法,以便在适當
的時機做适當的事
三. UIImageView
UIImageView是iOS中用于顯示圖檔的類,iOS中幾乎所有看到的 圖檔,都是由這個類來顯示的
四. 手勢識别器
手勢識别器是對觸摸事件做了封裝,我們無需自己去判斷某個手勢是否觸發,手勢識别器本身起到了識别作用,我們把重心放在識别之後要做什麼操作上面, 它是iOS中比較抽象的一個類,共有七個子類
一旦指定的手勢被識别, 我們可以執行我們自己定義好的操作
如何使用識别器
我們不會直接使用手勢識别器這個抽象父類,而是根據需要使用特定的手勢識别器建立對象
1、建立UIxxxGestureRecognizer對象,使用initWithTarget:action:方法
2、配置要識别的手勢的相關資訊
3、将手勢添加到某個視圖上
4、實作手勢識别器裡定義的方法
view的transform屬性
transform是view的一個重要屬性,它在矩陣層面上改變view的顯示狀态,能實作view的縮放、旋轉、平移等等功能
#import "MainViewController.h"
@interface MainViewController ()
@property(nonatomic, retain)UIImageView *imageView;
@property(nonatomic, retain)UIAlertView *alertView;
@end
@implementation MainViewController
- (void)dealloc
{
// [self.view release]; self.view作為系統給出視圖 不需要我們釋放 我們隻需要管我們建立的東西 即程式中看得見的retain || alloc
[self.imageView release];
[self.alertView release];
[super dealloc];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor brownColor];
// UIImageView
// UIImage *image1 = [[UIImage alloc] initWithContentsOfFile:@"scratch.png"]; // 這方法怎麼用?
UIImage *image = [UIImage imageNamed:@"scratch.png"];
self.imageView = [[UIImageView alloc] initWithImage:image];
self.imageView.frame = CGRectMake(, , , );
self.imageView.backgroundColor = [UIColor yellowColor];
[self.view addSubview:self.imageView];
[self.imageView release];
// 把圖檔的使用者互動打開,它預設是關閉的,此外還有一個控件是label
self.imageView.userInteractionEnabled = YES;
// 圖檔大小适應imageView.frame的大小
UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"28.jpg"]];
[self.view addSubview:iv];
[iv release];
// 調用initWithImage:方法,它建立出來的imageview的寬高和圖檔的寬高一樣
UIImageView *im = [[UIImageView alloc] initWithFrame:self.view.bounds];
im.image = [UIImage imageNamed:@"28.jpg"];
[self.view addSubview:im];
[im release];
// 這種初始化方法怎麼用?
UIImageView *iw = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"13.jpg"] highlightedImage:[UIImage imageNamed:@"28.jpg"]];
[scrollView addSubview:iw];
scrollView.contentSize = [UIImage imageNamed:@"13.jpg"].size;
[iw release];
iw.tag = ;
// 取網絡圖檔的方法
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://fdfs.xmcdn.com/group16/M00/66/92/wKgDbFXgRVHx7qhRAAGp5e22Sas297_ios_large.jpg"]]];
iw.image = image;
// UIImageView 高亮圖
UIImageView *headshotImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"image1.jpg"] highlightedImage:[UIImage imageNamed:@"image2.jpg"]];
headshotImageView.frame = CGRectMake(, , , );
headshotImageView.userInteractionEnabled = YES; // 打開這個
headshotImageView.tag = ;
[self.view addSubview:headshotImageView];
[headshotImageView release];
// UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
// [headshotImageView addGestureRecognizer:singleTap];
// [singleTap release];
//讓一個UIImageView響應點選事件
UIImageView *imgView =[[UIImageView alloc] initWithFrame:CGRectMake(, ,, )];
imgView.userInteractionEnabled=YES;
UITapGestureRecognizer *singleTap =[[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(onClickImage)];
[imgView addGestureRecognizer:singleTap];
[singleTap release];
// 手勢的使用
// 1.點選
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
// 設定點選幾次才會觸發方法
tap.numberOfTapsRequired = ;
// 設定幾個手指進行點選
tap.numberOfTouchesRequired = ;
// 将手勢添加到對應的圖檔上
[self.imageView addGestureRecognizer:tap];
[tap release];
// 2.長按
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressAction:)];
// 設定長按按鈕觸發的最短時間
longPress.minimumPressDuration = ;
// 使用者手指在長按過程中允許移動的距離
longPress.allowableMovement = ; // 指的是點按中方法實作之前的那段時間,看移動距離是否超出範圍,是則不執行方法,否則繼續執行
// 把手勢添加到圖檔上
[self.view addGestureRecognizer:longPress];
[longPress release];
// 3.旋轉
// 建立一個旋轉的手勢
UIRotationGestureRecognizer *Rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationAction:)];
// 把手勢放到對應的圖檔上
[self.imageView addGestureRecognizer:Rotation];
[Rotation release];
// 4.捏合
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchAction:)];
[self.imageView addGestureRecognizer:pinch];
[pinch release];
// 5.拖拽
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
[self.imageView addGestureRecognizer:pan];
[pan release];
// 6.輕掃 // 怎麼觸摸 很難按出來.
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeAction:)];
[self.imageView addGestureRecognizer:swipe];
[swipe release];
// 輕掃方向
swipe.direction = UISwipeGestureRecognizerDirectionRight;
// 7.螢幕邊際方法
// UIScreenEdgePanGestureRecognizer // 自行查找
//
UIStepper *stepper = [[UIStepper alloc] initWithFrame:CGRectMake(, , , )];
stepper.backgroundColor = [UIColor whiteColor];
[stepper addTarget:self action:@selector(stepperAction:) forControlEvents:UIControlEventValueChanged];
[stepper setMinimumValue:]; //</span>
[stepper setMaximumValue:];
stepper.stepValue = ; //每次遞增</span>
[stepper setWraps:YES];
[stepper setContinuous:YES];
[self.imageView addSubview:stepper];
// autorepeat: 控制是否在按住時自動持續遞增或遞減,預設YES;
[stepper release];
}
// 自定義的點選方法
//- (void)handleSingleTap:(UITapGestureRecognizer *)tap
//{
// UIImageView *headshotImageView = (UIImageView *)[self.view viewWithTag:888];
// headshotImageView.highlighted = !headshotImageView.highlighted;
// NSLog(@"單手點選方法");
//}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UIImageView *headshotImageView = (UIImageView *)[self.view viewWithTag:];
headshotImageView.highlighted = YES;
NSLog(@"點選開始");
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
UIImageView *headshotImageView = (UIImageView *)[self.view viewWithTag:];
headshotImageView.highlighted = NO;
NSLog(@"點選結束");
}
-(void)onClickImage{
// here, do whatever you wantto do
NSLog(@"imageview is clicked!");
}
- (void)stepperAction:(UIStepper *)stepper
{
// 此控件這麼使用對于imageView沒什麼用? 因為點選該控件隻能修改一次視圖大小
int temp = stepper.value;
self.imageView.bounds = CGRectMake(temp, temp, temp, temp);
}
#pragma mark 清掃的方法:
- (void)swipeAction:(UISwipeGestureRecognizer *)swipe
{
if (swipe.direction == UISwipeGestureRecognizerDirectionRight) {
NSLog(@"向右");
}
self.imageView = (UIImageView *)swipe.view;
}
#pragma mark 拖拽的方法:通過拖拽手勢,讓視圖随着手勢的移動而移動
- (void)panAction:(UIPanGestureRecognizer *)pan
{
// 通過手勢找視圖
self.imageView = (UIImageView *)pan.view;
// 通過手勢獲得經過的店
CGPoint p = [pan translationInView:self.imageView];
// 設定移動的位置
self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform, p.x, p.y);
// 為了防止手勢在操作的時候視圖消失
[pan setTranslation:CGPointZero inView:self.imageView];
// self.imageView.transform =
}
#pragma mark 捏合的方法:通過捏合手勢,縮放圖檔
- (void)pinchAction:(UIPinchGestureRecognizer *)pinch
{
// 通過手勢找視圖
self.imageView = (UIImageView *)pinch.view;
// 通過transform改變圖檔的尺寸
self.imageView.transform = CGAffineTransformScale(self.imageView.transform, pinch.scale, pinch.scale);
pinch.scale = ;
}
#pragma mark 旋轉的方法:通過圖檔的旋轉手勢,讓圖檔發生旋轉
- (void)rotationAction:(UIRotationGestureRecognizer *)Rotation
{
// 可以通過手勢擷取手勢添加的視圖是哪一個
self.imageView = (UIImageView *)Rotation.view;
// 進行旋轉的操作
// 通過視圖的transform屬性,讓視圖進行旋轉
// self.imageView.transform = CGAffineTransformMakeRotation(Rotation.rotation);
self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, Rotation.rotation);
Rotation.rotation = ;
NSLog(@"測試旋轉");
}
#pragma mark 長按的方法
- (void)longPressAction:(UILongPressGestureRecognizer *)longPress
{
// 長按的狀态
// longPress.state
// 長按之後彈出一個alertView
if (self.alertView == nil) { // 與!self.alertView同樣
self.alertView = [[UIAlertView alloc] initWithTitle:@"老婆" message:@"讓我親一個吧!" delegate:self cancelButtonTitle:@"拒絕" otherButtonTitles:@"木馬~", nil];
[self.alertView release];
}
NSLog(@"pia"); // 隻要長按每次都列印兩遍
[self.alertView show];
}
#pragma mark 點選的方法
- (void)tapAction:(UITapGestureRecognizer *)tap
{
NSLog(@"測試一下點選手勢");
self.imageView.image = [UIImage imageNamed:@"image1.jpg"];
}