ฉันจะตรวจจับเหตุการณ์การสัมผัสของ UIImageView ได้อย่างไร


97

ฉันวางภาพ (UIImageView) บนแถบนำทาง ตอนนี้ฉันต้องการตรวจจับเหตุการณ์การสัมผัสและต้องการจัดการเหตุการณ์ ฉันจะทำเช่นนั้นได้อย่างไร?


ในสถานการณ์นี้ฉันจะ (และคิดว่าคุณควร) ใช้ UIButton ที่กำหนดเองแทน
titaniumdecoy

ตรวจสอบ คำตอบเวอร์ชัน Swift http://stackoverflow.com/a/41328885/3177007
Mohamed Jaleel Nazir

คำตอบ:


138

ในทางปฏิบัติอย่าทำอย่างนั้น

เพิ่มปุ่มที่มีสไตล์แบบกำหนดเองแทน (ไม่มีกราฟิกของปุ่มเว้นแต่คุณจะระบุรูปภาพ) บน UIImageView จากนั้นแนบวิธีการใด ๆ ที่คุณต้องการเรียกใช้

คุณสามารถใช้เทคนิคนี้กับหลาย ๆ กรณีที่คุณต้องการให้พื้นที่บางส่วนของหน้าจอทำหน้าที่เป็นปุ่มแทนที่จะไปยุ่งกับสิ่งที่ Touch


ฉันได้เพิ่มปุ่มที่แถบนำทางและยังสามารถจัดการกับเหตุการณ์การสัมผัสได้ อย่างไรก็ตามฉันต้องการเพิ่มภาพกลมบนปุ่มนี้ คุณช่วยแจ้งให้ฉันทราบได้อย่างไรว่าฉันจะทำแบบเป็นโปรแกรมได้อย่างไร นอกจากนี้โปรดแจ้งให้ฉันทราบว่าฉันจะตั้งค่าคุณสมบัติของปุ่มเป็น "กำหนดเอง" แบบเป็นโปรแกรมได้อย่างไร
ebaccount

ดูเอกสารสำหรับ UIButton - คุณต้องตั้งค่าภาพพื้นหลังสำหรับสถานะการควบคุมคุณจะต้องการภาพที่แตกต่างกันสำหรับ Normal กับ Selected / Highlighted สไตล์ปุ่มคือสิ่งที่คุณตั้งค่าเป็น UIButtonStyleCustom ฉันเชื่ออีกครั้งดูเอกสารสำหรับคุณสมบัติสไตล์บน UIButton
Kendall Helmstetter Gelner

1
ไม่ได้เพิ่ม UIButton ที่ด้านบนของ UIImageView เล็กน้อยหรือไม่? คุณกำลังเพิ่มวัตถุพิเศษในขณะที่คุณสามารถใช้วิธีการสัมผัสของวัตถุ UIImageView ที่มีอยู่แล้วได้ ไม่?
samvermette

32
หากคุณดูขนาดของ UIButton ในหน่วยความจำแทบจะไม่มีอะไรเลยและคุณมีเพียงไม่กี่หน้าจอเท่านั้น สิ่งที่คุณได้รับฟรีคือการเดินสายแอ็คชั่นเป้าหมายทั้งหมดสำหรับสถานะต่างๆ (เช่นการสัมผัสภายใน) และพฤติกรรมที่ดีเช่นไม่เรียกเมื่อคุณกดลง แต่เลื่อนนิ้วไปด้านข้าง โดยทั่วไปแล้วปุ่มเป็นหนึ่งในวัตถุที่สร้างขึ้นอย่างประณีตที่สุดในระบบทั้งหมดและการคิดว่าคุณกำลังจะสร้างรหัสสัมผัสที่กำหนดเองซึ่งทำงานได้ดีขึ้นนั้นเป็นความบ้าคลั่ง ใช้สิ่งที่ราคาถูกและใช้งานได้ดีบันทึกงานที่กำหนดเองสำหรับสิ่งที่กรอบงานไม่ได้จัดการให้คุณ
Kendall Helmstetter Gelner

6
คุณยังสามารถซ้อนทับ UIControl ได้หากสิ่งที่คุณต้องการคือเหตุการณ์การสัมผัส (ผ่าน addTaget: action: forControlEvents :) ราคาถูกกว่า UIButton เล็กน้อยซึ่งมีรูปภาพและหลายสถานะ นอกจากนี้ฉันใช้เงื่อนไขของตัวประมวลผลล่วงหน้าเพื่อเปลี่ยนสีพื้นหลังของตัวควบคุมที่ซ้อนทับเป็นสีชมพูเพื่อที่ฉันจะได้เห็นว่ามันอยู่ที่ไหน (และจำไว้ว่ามันมีอยู่ :-)
Jeff

115

A UIImageViewมาจากUIViewที่มาจากUIResponderดังนั้นจึงพร้อมที่จะจัดการกับเหตุการณ์สัมผัส คุณจะต้องการที่จะให้touchesBegan, touchesMovedและtouchesEndedวิธีการและพวกเขาจะได้รับการเรียกหากผู้ใช้แตะภาพ หากสิ่งที่คุณต้องการคือเหตุการณ์การแตะมันง่ายกว่าเพียงแค่ใช้ปุ่มที่กำหนดเองกับภาพที่กำหนดเป็นภาพปุ่ม แต่ถ้าคุณต้องการการควบคุมที่ละเอียดกว่าการแตะการเคลื่อนไหว ฯลฯ นี่คือวิธีที่จะไป

คุณจะต้องดูสิ่งต่างๆเพิ่มเติม:

  • แทนที่canBecomeFirstResponderและส่งคืนใช่เพื่อระบุว่ามุมมองสามารถกลายเป็นจุดสำคัญของเหตุการณ์การสัมผัสได้ (ค่าเริ่มต้นคือ NO)

  • ตั้งค่าuserInteractionEnabledคุณสมบัติเป็นใช่ ค่าเริ่มต้นUIViewsคือใช่ แต่สำหรับUIImageViewsไม่ใช่ดังนั้นคุณต้องเปิดใช้อย่างชัดเจน

  • หากคุณต้องการตอบสนองต่อเหตุการณ์แบบมัลติทัช (เช่นการบีบนิ้วการซูม ฯลฯ ) คุณจะต้องตั้งค่า multipleTouchEnabledเป็นใช่


ฉันพยายามแล้ว แต่ก็ไม่น้อยกว่าที่ฉันจะไม่ได้รับการสัมผัส Began events ... ทำไมถึงเป็นอย่างนั้น?
Markus

5
@Markus: ฉันมีปัญหาเดียวกัน แต่แก้ไขได้โดยตั้งค่าuserInteractionEnabledเป็นใช่ในมุมมองผู้ปกครองของฉัน ดูstackoverflow.com/questions/5887305/…
Saxon Druce

51

หากต้องการเพิ่มเหตุการณ์การสัมผัสลงใน UIImageView ให้ใช้สิ่งต่อไปนี้ในไฟล์. m ของคุณ:

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

[myImageView setUserInteractionEnabled:YES];

[myImageView addGestureRecognizer:newTap];


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

userInteractionEnabled = true เป็นส่วนที่ลืมง่ายขอบคุณ
Michael Peterson

23

คุณยังสามารถเพิ่ม UIGestureRecognizer ไม่จำเป็นต้องให้คุณเพิ่มองค์ประกอบเพิ่มเติมในลำดับชั้นมุมมองของคุณ แต่ยังให้โค้ดที่เขียนขึ้นอย่างดีทั้งหมดสำหรับจัดการเหตุการณ์การสัมผัสด้วยอินเทอร์เฟซที่ค่อนข้างเรียบง่าย:

    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
อย่าลืมตั้งค่า UserInteractionEnabled สำหรับ imgView_
Anonymous White

13

ฉันอยู่ในหัวข้อต่างๆในช่วงไม่กี่ชั่วโมงที่ผ่านมาเพื่อพยายามหาวิธีแก้ปัญหาของฉัน แต่ก็ไม่มีประโยชน์ ฉันเห็นว่านักพัฒนาหลายคนแบ่งปันปัญหานี้และฉันคิดว่าคนที่นี่รู้เรื่องนี้ ฉันมีหลายภาพใน a UIScrollViewพยายามรับเหตุการณ์การแตะ

ฉันไม่ได้รับเหตุการณ์ใด ๆ จาก an UIImangeViewแต่ฉันได้รับเหตุการณ์จากUILableพารามิเตอร์ที่คล้ายกันที่ฉันตั้งค่าไว้ ภายใต้ iOS 5.1

ฉันได้ทำสิ่งต่อไปนี้แล้ว:

  1. ตั้งค่า setUserInteractionEnabled เป็น YES สำหรับทั้งมุมมองʻUIImageView และพาเรนต์
  2. ตั้ง setMultipleTouchEnabled UIImageViewใช่สำหรับ
  3. พยายามคลาสย่อยUIImageViewไม่ได้ช่วยอะไรเลย

การแนบโค้ดบางส่วนด้านล่างในรหัสนี้ฉันเริ่มต้นทั้ง a UIImageViewและUILabelฉลากทำงานได้ดีในแง่ของการเริ่มทำงาน ฉันพยายามเก็บรหัสที่ไม่เกี่ยวข้อง

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;

และวิธีการจัดการเหตุการณ์:

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

ดังที่กล่าวว่าได้รับการแตะฉลากแล้ว


6

แทนที่จะสร้าง UIImageView ที่สัมผัสได้จากนั้นวางไว้บนแถบนำทางคุณควรสร้าง UIBarButtonItem ซึ่งคุณสร้างขึ้นจาก UIImageView

ขั้นแรกให้ดูภาพ:

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

จากนั้นทำให้รายการ barbutton ออกจากมุมมองภาพของคุณ:

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

จากนั้นเพิ่มรายการปุ่มแถบลงในแถบนำทางของคุณ:

self.navigationItem.rightBarButtonItem = yourBarButtonItem;

โปรดจำไว้ว่ารหัสนี้จะเข้าไปในตัวควบคุมมุมมองซึ่งอยู่ภายในอาร์เรย์วิวคอนโทรลเลอร์ของตัวควบคุมการนำทาง โดยพื้นฐานแล้ว "รายการปุ่มแถบที่ดูรูปภาพที่สัมผัสได้" นี้จะปรากฏในแถบนำทางเมื่อตัวควบคุมมุมมองนี้แสดงขึ้นเท่านั้น เมื่อคุณดันตัวควบคุมมุมมองอื่นรายการปุ่มแถบนำทางนี้จะหายไป


3

คุณอาจต้องการที่จะแทนที่touchesBegan:withEvent:วิธีการUIView(หรือ subclass) ที่มีคุณUIImageViewsubview

ภายในวิธีนี้ให้ทดสอบว่าUITouchสัมผัสใดที่อยู่ในขอบเขตของUIImageViewอินสแตนซ์ (สมมติว่ามีการเรียกimageView)

นั่นคือCGPointองค์ประกอบ[touch locationInView]ตัดกับCGRectองค์ประกอบ[imageView bounds]หรือไม่? ดูฟังก์ชันCGRectContainsPointเพื่อเรียกใช้การทดสอบนี้


ขอบคุณสำหรับการตอบกลับของคุณ. ฉันได้เพิ่มมุมมองดังนี้: [navBar addSubview: self.pImage]; // เพิ่มเป็นมุมมองย่อยของแถบนำทาง ฉันได้ลบล้างฟังก์ชัน แต่ไม่เคยเรียกฟังก์ชัน ฉันได้ตั้งค่าคุณสมบัติ userInteractionEnabled ของ UIImageView เป็น YES แล้ว ฉันขาดอะไรไปหรือเปล่า?
ebaccount

ลองดูวิธีการ TouchBegan: withEvent: มีตัวอย่างมากมายในเครื่องมือค้นหาเกี่ยวกับวิธีการทำงานนี้
Alex Reynolds

1

ขั้นแรกคุณควรวาง UIButton จากนั้นคุณสามารถเพิ่มภาพพื้นหลังสำหรับปุ่มนี้หรือคุณต้องวาง UIImageView ไว้เหนือปุ่ม

หรือ:

คุณสามารถเพิ่มท่าทางการแตะลงใน UIImageView เพื่อให้ได้รับการคลิกเมื่อแตะที่ UIImageView


0

สำหรับผู้ที่กำลังมองหาโซลูชัน Swift 4 สำหรับคำตอบนี้คุณสามารถใช้สิ่งต่อไปนี้เพื่อตรวจจับเหตุการณ์การสัมผัสบน UIImageView

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

จากนั้นคุณจะต้องกำหนดตัวเลือกของคุณดังนี้:

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

-2

เพิ่มท่าทางในมุมมองนั้น เพิ่มรูปภาพลงในมุมมองนั้นจากนั้นก็จะตรวจพบท่าทางสัมผัสบนรูปภาพด้วย คุณสามารถลองใช้วิธีการมอบหมายของเหตุการณ์สัมผัส จากนั้นในกรณีนั้นก็อาจตรวจพบ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.