làm cách nào để phát hiện sự kiện chạm của UIImageView


98

Tôi đã đặt một hình ảnh (UIImageView) trên thanh điều hướng. Bây giờ tôi muốn phát hiện sự kiện chạm và muốn xử lý sự kiện. Bạn có thể cho tôi biết làm thế nào tôi có thể làm điều đó?

Cảm ơn.


Trong tình huống này, tôi sẽ (và nghĩ rằng bạn nên) sử dụng UIButton tùy chỉnh để thay thế.
titaniumdecoy

Kiểm tra Swift phiên bản trả lời http://stackoverflow.com/a/41328885/3177007
Mohamed Jaleel Nazir

Câu trả lời:


137

Về mặt thực tế, đừng làm vậy.

Thay vào đó, hãy thêm một nút có kiểu Tùy chỉnh (không có đồ họa nút trừ khi bạn chỉ định hình ảnh) trên UIImageView. Sau đó đính kèm bất kỳ phương thức nào bạn muốn được gọi vào đó.

Bạn có thể sử dụng kỹ thuật đó cho nhiều trường hợp mà bạn thực sự muốn một số khu vực trên màn hình hoạt động như một nút thay vì làm rối tung nội dung Touch.


Tôi đã thêm một nút trên thanh điều hướng và tôi cũng có thể xử lý các sự kiện chạm. Tuy nhiên, tôi muốn thêm một hình tròn trên nút này. Bạn có thể cho tôi biết làm thế nào tôi có thể làm điều đó theo chương trình? Ngoài ra, bạn có thể cho tôi biết cách đặt thuộc tính nút thành "tùy chỉnh" theo chương trình không?
ebaccount

Xem tài liệu cho UIButton - bạn cần đặt hình nền cho trạng thái điều khiển, bạn sẽ muốn các hình ảnh khác nhau cho Bình thường so với Đã chọn / Đánh dấu. Kiểu nút là những gì bạn đặt thành UIButtonStyleCustom, tôi tin - một lần nữa, hãy xem tài liệu cho thuộc tính kiểu trên UIButton.
Kendall Helmstetter Gelner

1
Việc thêm một UIButton trên đầu UIImageView không phải là một chút trên đầu sao? Bạn đang thêm một đối tượng bổ sung, trong khi bạn chỉ có thể triển khai các phương thức cảm ứng của đối tượng UIImageView đã có. Không?
samvermette

32
Nếu bạn nhìn vào kích thước của UIButton trong bộ nhớ, nó hầu như không có gì và bạn chỉ có một vài cái trên mỗi màn hình. Những gì bạn nhận được miễn phí là toàn bộ dây hành động mục tiêu cho các trạng thái khác nhau (như chạm vào bên trong) và hành vi cũng tốt đẹp như không kích hoạt khi bạn nhấn xuống nhưng trượt ngón tay sang một bên. Về cơ bản, các nút là một trong những đối tượng được chế tạo tinh xảo nhất trong toàn bộ hệ thống và việc nghĩ rằng bạn sẽ làm mã cảm ứng tùy chỉnh hoạt động tốt hơn là một sự điên rồ. Sử dụng cái giá rẻ và hoạt động tốt, lưu công việc tùy chỉnh cho những thứ mà các khung công tác chưa xử lý cho bạn.
Kendall Helmstetter Gelner

6
Bạn cũng có thể phủ một UIControl nếu tất cả những gì bạn cần là các sự kiện chạm (thông qua addTaget: action: forControlEvents :). Nó rẻ hơn một chút so với UIButton có hình ảnh và một số trạng thái. Ngoài ra, tôi sử dụng các điều kiện tiền xử lý để thay đổi màu nền của điều khiển lớp phủ thành màu hồng để tôi có thể thấy chính xác vị trí của chúng (và hãy nhớ rằng chúng tồn tại :-).
Jeff

115

A UIImageViewcó nguồn gốc từ a UIViewcó nguồn gốc từ UIResponderđó để nó sẵn sàng xử lý các sự kiện chạm. Bạn sẽ muốn cung cấp touchesBegan, touchesMovedtouchesEndedcác phương pháp và họ sẽ được gọi nếu người dùng chạm vào hình ảnh. Nếu tất cả những gì bạn muốn là một sự kiện nhấn, sẽ dễ dàng hơn chỉ cần sử dụng một nút tùy chỉnh với hình ảnh được đặt làm hình ảnh nút. Nhưng nếu bạn muốn kiểm soát chi tiết hơn đối với các lần nhấn, di chuyển, v.v. thì đây là cách để thực hiện.

Bạn cũng sẽ muốn xem xét một số điều khác:

  • Ghi đè canBecomeFirstRespondervà trả về CÓ để chỉ ra rằng chế độ xem có thể trở thành tâm điểm của các sự kiện chạm (mặc định là KHÔNG).

  • Đặt thuộc userInteractionEnabledtính thành CÓ. Mặc định cho UIViewslà CÓ, nhưng cho UIImageViewslà KHÔNG nên bạn phải bật rõ ràng.

  • Nếu bạn muốn phản hồi các sự kiện đa chạm (tức là chụm, thu phóng, v.v.), bạn sẽ muốn đặt multipleTouchEnabledthành CÓ.


Tôi đã thử điều đó nhưng không bao giờ tôi càng không nhận được các sự kiện chạm vàoBegan ... tại sao vậy?
Markus

5
@Markus: Tôi cũng gặp vấn đề tương tự, nhưng đã khắc phục bằng cách đặt userInteractionEnabledthành CÓ trên chế độ xem của cha mẹ tôi. Xem stackoverflow.com/questions/5887305/…
Saxon Druce,

51

Để thêm sự kiện cảm ứng vào UIImageView, hãy sử dụng phần sau trong tệp .m của bạn

UITapGestureRecognizer *newTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(myTapMethod)];

[myImageView setUserInteractionEnabled:YES];

[myImageView addGestureRecognizer:newTap];


-(void)myTapMethod{
    // treat image tap
}

hy vọng rằng sẽ giúp.


userInteractionEnabled = true là phần rất dễ quên, cảm ơn.
Michael Peterson

23

Bạn cũng có thể thêm một UIGestureRecognizer. Nó không yêu cầu bạn thêm một phần tử bổ sung trong hệ thống phân cấp chế độ xem của mình, nhưng vẫn cung cấp cho bạn tất cả mã được viết độc đáo để xử lý các sự kiện chạm với một giao diện khá đơn giản:

    UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]
                                            initWithTarget:self action:@selector(handleSwipe:)];
    swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
    [imgView_ addGestureRecognizer:swipeRight];        
    [swipeRight release];
    UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]
                                            initWithTarget:self action:@selector(handleSwipe:)];
    swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
    [imgView_ addGestureRecognizer:swipeLeft];
    [swipeLeft release];

10
ĐỪNG quên đặt UserInteractionEnabled cho imgView_
Anonymous White,

13

Tôi đã tham gia các chủ đề khác nhau trong vài giờ qua để cố gắng tìm giải pháp cho vấn đề của mình, nhưng vô ích. Tôi thấy rằng nhiều nhà phát triển chia sẻ vấn đề này và tôi nghĩ mọi người ở đây đều biết về điều này. Tôi có nhiều hình ảnh bên trong a UIScrollView, đang cố gắng lấy các sự kiện nhấn vào chúng.

không nhận được bất kỳ sự kiện nào từ một UIImangeView, nhưng tôi nhận được một sự kiện từ một sự kiện tương tự UILablevới các thông số rất giống tôi đang đặt cho nó. dưới IOS 5.1.

Tôi đã làm như sau:

  1. đặt setUserInteractionEnabled thành CÓ cho cả `UIImageView và chế độ xem gốc.
  2. đặt setMultipleTouchEnabled thành CÓ cho UIImageView.
  3. Đã thử phân lớp UIImageView, không giúp được gì.

Đính kèm một số mã bên dưới, trong mã này, tôi khởi tạo cả a UIImageViewUILabel, nhãn hoạt động tốt về mặt các sự kiện kích hoạt. Tôi đã cố gắng giữ mã không liên quan. Cảm ơn các bạn, Ilan

UIImageView *single_view = [[UIImageView alloc]initWithFrame:CGRectMake(200, 200, 100, 100)];
single_view.image=img;
single_view.layer.zPosition=4;

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGestureCaptured:)];
[single_view addGestureRecognizer:singleTap];
[single_view setMultipleTouchEnabled:YES];
[single_view setUserInteractionEnabled:YES];
[self.myScrollView addSubview:single_view];    
self.myScrollView.userInteractionEnabled=YES;

UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
testLabel.backgroundColor=[UIColor redColor];
[self.myScrollView addSubview:testLabel];
[testLabel addGestureRecognizer:singleTap];  
[testLabel setMultipleTouchEnabled:YES];
[testLabel setUserInteractionEnabled:YES];
testLabel.layer.zPosition=4;

Và phương thức xử lý sự kiện:

- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture
{ 
    UIView *tappedView = [gesture.view hitTest:[gesture locationInView:gesture.view] withEvent:nil];
    NSLog(@"Touch event on view: %@",[tappedView class]);
}

Như đã nói, vòi nhãn được nhận.


6

Thay vì tạo một UIImageView có thể chạm vào sau đó đặt nó trên thanh điều hướng, bạn chỉ nên tạo một UIBarButtonItem, cái mà bạn tạo ra từ UIImageView.

Đầu tiên hãy xem hình ảnh:

UIImageView *yourImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"nameOfYourImage.png"]];

Sau đó, đặt mục nút ra khỏi chế độ xem hình ảnh của bạn:

UIBarButtonItem *yourBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:yourImageView];

Sau đó, thêm mục nút thanh vào thanh điều hướng của bạn:

self.navigationItem.rightBarButtonItem = yourBarButtonItem;

Hãy nhớ rằng mã này đi vào bộ điều khiển chế độ xem nằm bên trong mảng bộ điều khiển chế độ xem bộ điều khiển điều hướng. Vì vậy, về cơ bản, "mục nút thanh có hình ảnh có thể chạm vào" này sẽ chỉ xuất hiện trong thanh điều hướng khi bộ điều khiển chế độ xem này khi nó được hiển thị. Khi bạn ấn một bộ điều khiển chế độ xem khác, mục nút thanh điều hướng này sẽ biến mất ~


3

Những gì bạn có thể muốn làm là ghi đè touchesBegan:withEvent:phương thức của UIView(hoặc lớp con) chứa chế độ xem phụ của bạn UIImageView.

Trong phương pháp này, hãy kiểm tra xem có bất kỳ UITouchchạm nào nằm trong giới hạn của UIImageViewphiên bản không (giả sử nó được gọi imageView).

Tức là CGPointphần tử có [touch locationInView]giao nhau với CGRectphần tử [imageView bounds]không? Nhìn vào chức năng CGRectContainsPointđể chạy thử nghiệm này.


Cảm ơn vì đã trả lời. Tôi đã thêm chế độ xem như sau: [navBar addSubview: self.pImage]; // được thêm vào như một chế độ xem phụ của thanh điều hướng. Tôi đã ghi đè hàm nhưng hàm không bao giờ được gọi. Mặc dù vậy, tôi đã đặt thuộc tính userInteractionEnabled của UIImageView thành CÓ. Tôi có thiếu gì không?
ebaccount

Kiểm tra phương thức touchBegan: withEvent:. Có rất nhiều ví dụ trên các công cụ tìm kiếm về cách hoạt động của điều này.
Alex Reynolds

1

Đầu tiên, bạn nên đặt một UIButton, sau đó bạn vcan thêm hình nền cho nút này hoặc bạn cần đặt UIImageView trên nút.

hoặc là

Bạn có thể thêm cử chỉ chạm vào UIImageView để thực hiện thao tác nhấp khi chạm vào UIImageView.


0

Đối với những người bạn đang tìm kiếm một giải pháp Swift 4 cho câu trả lời này. Bạn có thể sử dụng cách sau để phát hiện sự kiện chạm trên UIImageView.

let gestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageViewTapped))
imageView.addGestureRecognizer(gestureRecognizer)
imageView.isUserInteractionEnabled = true

Sau đó, bạn sẽ cần xác định bộ chọn của mình như sau:

@objc func imageViewTapped() {
    // Image has been tapped
}

-2

Thêm cử chỉ trên chế độ xem đó. Thêm hình ảnh vào chế độ xem đó thì nó cũng sẽ phát hiện cử chỉ trên hình ảnh. Bạn có thể thử với phương pháp ủy quyền của sự kiện cảm ứng rồi trong trường hợp đó nó cũng có thể phát hiện được không. Cảm ơn

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.