2012-07-16 21 views
5

Tôi đang hiển thị tài liệu trong giao diện người dùng UIWebView. Tôi muốn đặt một điểm nóng trên tài liệu để kích hoạt một hành động khi nó được khai thác, nhưng tôi cũng muốn duy trì hành vi UIWebView mặc định của tự động phóng to tài liệu khi nó được khai thác hai lần. Tôi không thể tìm ra cách để phản ứng với các lần chạm đơn lẻ trong khi cho phép UIWebView phản hồi với các thao tác nhấn đúp.Làm cách nào để chỉ phản hồi cử chỉ chạm một lần trong khi để các đối tượng phía sau phản ứng với các thao tác nhấn đúp?

Lần đầu tiên tôi thiết lập điểm phát sóng là UIButton trong suốt với hành động, nhưng nhấn đúp vào điểm phát sóng dẫn đến hành động điểm phát sóng được gọi hai lần. Vì vậy, tôi đã xóa hành động khỏi nút và đã đính kèm một cử chỉ nhấn một lần để thay thế:

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapAction:)]; 
singleTap.numberOfTapsRequired = 1; 
singleTap.delegate = self; 
[self.hotspot addGestureRecognizer:singleTap]; 
[singleTap release]; 

Điều này hoạt động giống như thao tác nút thông thường. Nhưng sau đó tôi đã tạo ra một cử chỉ nhấn đúp, và cấu hình nó để chặn các cử chỉ đơn-tap với requireGestureRecognizerToFail:

UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(zoomWebView:)]; 
doubleTap.numberOfTapsRequired = 2; 
doubleTap.delegate = self; 
[self.hotspot addGestureRecognizer:doubleTap]; 
[doubleTap release]; 

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapAction:)]; 
singleTap.numberOfTapsRequired = 1; 
[singleTap requireGestureRecognizerToFail:doubleTap]; 
singleTap.delegate = self; 
[self.hotspot addGestureRecognizer:singleTap]; 
[singleTap release]; 

- (void)zoomWebView:(UITapGestureRecognizer *)gesture { 
    NSLog(@"double tap"); 
} 

Với thiết lập này, một đơn-tap trên hotspot gọi singleTapAction và nhấp đúp vào hotspot gọi zoomWebView (một phương thức tùy chỉnh). Điều này là tốt bởi vì singleTapAction không còn được gọi hai lần nữa, nhưng không tốt vì UIWebView không còn đáp ứng với việc nhấn đúp nữa.

Tôi đã thử chuyển tiếp sự kiện nhấn đúp từ cử chỉ doubleTap của tôi tới UIWebView bằng cách phân lớp UITapGestureRecognizer, ghi đè chạm vàoBegan và chạm vào Phương thức được gửi và gửi đối số của chúng đến phương thức tương ứng của UIWebView. Khi tôi đã làm điều đó, tôi có thể thấy rằng lớp con của tôi đã nhận được các sự kiện, nhưng UIWebView không trả lời các sự kiện được chuyển tiếp. Điều này được mong đợi bởi vì Event Handling Guide for iOS nói rằng chúng ta chỉ có thể chuyển tiếp các sự kiện tới các lớp con tùy chỉnh của UIView, chứ không phải các đối tượng khung công tác UIKit.

Có cách nào để ngăn cử chỉ chạm một lần của tôi khỏi phản hồi các lần nhấn đúp không chuyển hướng các sự kiện nhấn đúp không? Điều này có vẻ như một yêu cầu cơ bản, nhưng tôi không thể nhìn thấy một cách đơn giản để làm điều đó. Tôi đã đọc và thử nghiệm với số touch delivery properties của UIGestureRecognizer, nhưng không có sự kết hợp nào giữa các giá trị đã dừng cử chỉ chạm một lần từ việc sử dụng cử chỉ nhấn đúp.

Nhân tiện, mối quan hệ giữa điểm phát sóng và UIWebView trong cấu trúc phân cấp của tôi là "anh em họ" - chúng là các bản xem trước của hai chế độ xem anh chị em. Nếu tôi thêm công cụ nhận dạng cử chỉ vào chế độ xem điểm phát sóng, chế độ xem web hoặc chế độ xem "ông bà" của họ, tôi sẽ nhận được kết quả tương tự.

+0

không chắc về vấn đề này (vì thế nó trở thành một bình luận), nhưng bạn không thể thêm một vòi cử chỉ duy nhất để UIWebView? –

+0

@DeanPucsek Tôi đã làm điều đó một lúc và nó hoạt động khi hiển thị tài liệu PDF. Nhưng nếu nội dung được hiển thị trong UIWebView là HTML hoặc JPG, UIWebView sẽ chụp một lần cho các hành động của riêng nó và Trình nhận dạng UIGestureRecognizer không nhận được sự kiện. Sẽ thuận tiện hơn khi xử lý việc này với chế độ xem điểm phát sóng, nhưng tôi có thể quay lại phương pháp này nếu tôi có thể làm cho nó hoạt động với tất cả các loại nội dung UIWebView. – arlomedia

Trả lời

15

Được rồi, tôi đã tìm thấy giải pháp trong hai phần:

1) Tôi phải thêm cử chỉ của mình vào chế độ xem gốc của UIWebView. Các sự kiện chưa từng có không di chuyển qua các đối tượng chồng chéo trong một khung nhìn từ lớp này sang lớp khác như tôi đã tưởng tượng. Thay vào đó, chúng di chuyển qua hệ thống phân cấp các khung nhìn từ trẻ sang cha mẹ.Vì vậy, miễn là tôi đã thêm cử chỉ nhấn đúp của tôi vào chế độ xem anh chị em hoặc "anh em họ" của UIWebView, nó sẽ không bao giờ tiếp tục với chế độ xem web. Điều này có nghĩa là tôi không thể sử dụng các nút hoặc khung nhìn được trình bày trong Trình tạo giao diện để xác định nhiều vùng điểm phát sóng. Thay vào đó, tôi phải chuyển hướng tất cả các sự kiện một chạm vào một phương pháp và sau đó xem xét các vị trí cảm ứng để xác định hành động nào sẽ kích hoạt.

2) Tôi phải thêm phương thức gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer: cho trình điều khiển chế độ xem của tôi (ủy nhiệm cử chỉ của tôi) và trả về CÓ. Điều này cho phép cử chỉ chạm một lần của tôi phản hồi ngay cả khi tôi hiển thị nội dung HTML, văn bản hoặc hình ảnh trong UIWebView, thao tác này thực hiện cử chỉ riêng cho các loại nội dung này. Tôi đã học được phần này từ this answer.

Với những thay đổi này, tôi hiểu được hệ thống các sự kiện là:

  • Độc-tap xem web: single-tap cử chỉ của tôi vào xem cha mẹ xem web của phản ứng; cử chỉ chạm một lần của trang web cũng phản hồi nếu có thể vì các cử chỉ đồng thời được bật

  • Nhấn đúp vào lần xem web: cử chỉ nhấn đúp của tôi trên chế độ xem gốc của chế độ xem web phản hồi (nhưng không làm gì cả); cử chỉ chạm một lần của tôi không phản hồi vì nó được định cấu hình để chỉ phản hồi nếu nhấn đúp không thành công; sự kiện nhấn đúp của chế độ xem web cũng phản hồi vì nó là một phần của cấu trúc phân cấp chế độ xem (có vẻ như chức năng nhấn đúp của chế độ xem web không sử dụng cử chỉ vì nếu không nó sẽ được ưu tiên hơn cử chỉ của riêng tôi trong thiết lập ban đầu của tôi)

với điều đó giải thích ra khỏi con đường, đây là một số mã làm việc:

- (void)viewDidLoad { 
    UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapWebView:)]; 
    doubleTap.numberOfTapsRequired = 2; 
    doubleTap.delegate = self; 
    [self.webViewParent addGestureRecognizer:doubleTap]; 
    [doubleTap release]; 

    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapWebView:)]; 
    singleTap.numberOfTapsRequired = 1; 
    [singleTap requireGestureRecognizerToFail:doubleTap]; 
    singleTap.delegate = self; 
    [self.webViewParent addGestureRecognizer:singleTap]; 
    [singleTap release]; 
} 

- (void)doubleTapWebView:(UITapGestureRecognizer *)gesture { 
    NSLog(@"double-tap"); 
    // nothing to do here 
} 

- (void)singleTapWebView:(UITapGestureRecognizer *)gesture { 
    NSLog(@"single-tap"); 
    CGPoint touchLocation = [gesture locationInView:self.webViewParent]; 
    float x = touchLocation.x; 
    float y = touchLocation.y; 
    CGRect frame = self.webViewParent.frame; 
    if (y < frame.size.height * .33) { 
     NSLog(@"top"); 
    } else if (y > frame.size.height * .67) { 
     NSLog(@"bottom"); 
    } else if (x < frame.size.width * .33) { 
     NSLog(@"left"); 
    } else if (x > frame.size.width * .67) { 
     NSLog(@"right"); 
    } else { 
     NSLog(@"center"); 
    } 
} 

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { 
    return YES; 
} 
+0

Cảm ơn bạn đã trả lời câu hỏi này. Nó nhắm mục tiêu chặt chẽ nhất tình huống của tôi và cung cấp giải pháp, sau hàng chục bài báo đã đọc. Great hòa bình của công việc. – vedrano

+0

Chắc chắn +1. Giải thích tuyệt vời và mã tốt, thử nghiệm và làm việc với Swift 2.1 –

-2

Luôn luôn là một vấn đề với các nhấp chuột khi xử lý sự kiện bắt đầu.

Không thể chỉ trong một lần nhấp, cho bất kỳ phần mềm nào để xác định rằng nhấp đúp sẽ sắp xảy ra.

Vì vậy, nếu bạn muốn xử lý nhấp chuột đơn và nhấp đúp, bạn sẽ phải thực hiện xử lý nhấp đúp của riêng bạn.

Thời gian diễn ra một lần nhấp và tạo sự kiện nhấp đúp của riêng bạn.

Hy vọng rằng có thể chuyển sang khai thác trong ngữ cảnh của bạn.

+0

Trên thực tế, iOS UIGestureRecognizer có chức năng tích hợp sẵn để đợi thời lượng nhấn đúp trước khi kích hoạt sự kiện nhấn một lần. Đó là lý do tại sao tôi có thể chụp chính xác hai sự kiện bằng cách sử dụng hai trình nhận dạng cử chỉ khác nhau. Tôi chỉ không biết cách bỏ qua cử chỉ nhấn đúp để nó đạt đến UIWebView hoặc chuyển hướng đến đó, để giữ lại hành vi thu phóng được tích hợp sẵn của chế độ xem web. – arlomedia

+0

@arlomedia [Chuyển tiếp sự kiện iOS] (https://www.google.com/search?btnG=1&pws=0&q=iOS+event+forwarding) –

+0

Tôi đã xem xét các kết quả tìm kiếm đó, nhưng không thấy bất kỳ điều gì giúp tôi tình hình. Tôi thấy một số gợi ý rằng tôi không nên cố gắng chuyển tiếp các sự kiện đến các đối tượng UIKit, điều này đưa tôi trở lại phần "Có lẽ có một cách dễ dàng hơn" trong câu hỏi của tôi. – arlomedia