วิธีกำหนดแอคชันสำหรับวัตถุ UIImageView ใน Swift


186

ฉันพยายามที่จะกำหนดให้UIImageViewกับการกระทำเมื่อผู้ใช้แตะมัน

ฉันรู้วิธีการสร้างการดำเนินการหนึ่งUIButtonแต่วิธีการที่ฉันสามารถเลียนแบบพฤติกรรมเดียวกันของUIButtonแต่ใช้UIImageView?

คำตอบ:


421

UITapGestureRecognizerคุณจะต้องมี ในการตั้งค่าใช้สิ่งนี้:

override func viewDidLoad()
{
    super.viewDidLoad()

    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
    imageView.isUserInteractionEnabled = true
    imageView.addGestureRecognizer(tapGestureRecognizer)
}

@objc func imageTapped(tapGestureRecognizer: UITapGestureRecognizer)
{
    let tappedImage = tapGestureRecognizer.view as! UIImageView

    // Your action
}

(คุณยังสามารถใช้UIButtonและกำหนดภาพให้โดยไม่ต้องมีข้อความและทำได้ง่ายกว่าการเชื่อมต่อIBAction)


3
Nitpick: var tgr = UITapGestureRecognizer (เป้าหมาย: การกระทำของตนเอง: ตัวเลือก ("imageTapped:")) จำเป็นต้องใช้เครื่องหมายจุลภาคระหว่างพารามิเตอร์ทั้งสอง
sysuser

3
ตามที่ระบุไว้ด้านล่างโดย MidHun MP ตรวจสอบให้แน่ใจว่าคุณมี userInteractionEnabled = true
Sheraz

2
ใน Swift 3.0 ไวยากรณ์ของการกระทำ: Selector ("imageTapped:") เปลี่ยนเป็นการกระทำ: #selector (imageTapped))
emily

2
นอกจากนี้ใน Swift 3.0 คุณสมบัติ userInteractionEnabled ถูกเปลี่ยนชื่อเป็น isUserInteractionEnabled
Doug Amos

2
เมื่อใช้ Swift 4 สิ่งนี้ได้ผลสำหรับฉัน แต่ฉันต้องเพิ่ม@objcตัวแก้ไขในฟังก์ชัน
Mark Lyons

68

คุณต้องเพิ่ม AA จดจำท่าทาง (สำหรับประปาใช้UITapGestureRecognizerสำหรับประปาและการใช้งานถือUILongPressGestureRecognizer ) UIImageViewเพื่อคุณ

let tap = UITapGestureRecognizer(target: self, action: #selector(YourClass.tappedMe))
imageView.addGestureRecognizer(tap)
imageView.isUserInteractionEnabled = true

และใช้วิธีเลือกเช่น:

@objc func tappedMe()
{
    println("Tapped on Image")
}

13
userInteractionEnabled เป็นกุญแจสำคัญ
kennydust

@ Whatim: ปัญหาที่คุณเผชิญอยู่คืออะไร? หากคุณมีปัญหาใหม่โปรดโพสต์เป็นคำถามใหม่
Midhun MP

@ MidhunMP ฉันกำลังสร้างมุมมองภาพแบบไดนามิกและได้ทำสิ่งที่เขียนในคำตอบนี้ แต่ฟังก์ชั่น tappedMe () ไม่ได้รับการเรียก
Hatim

1
มันทำงานสำหรับฉันด้วยการเปลี่ยนแปลงต่อไปนี้: ให้แตะ = UITapGestureRecognizer (เป้าหมาย: ตนเองการกระทำ: #selector (ViewController.tappedMe)) // บรรทัดถัดไป -> successIndicatorImg.addGestureRecognizer (แตะ) // บรรทัดถัดไป -> successIndicatorImg.isUserInteractionEnabled จริง
Almir Campos

@ คุณกำลังใช้ท่าทางแบบเดียวกันกับหลายมุมมอง UI หรือไม่ ฉันเพิ่งแก้ไขปัญหานี้เนื่องจากฉันใช้รูปแบบลายเส้นเดียวกันสำหรับมุมมองหลายมุมมอง เมื่อฉันสร้างท่าทางหลายท่าทางมันใช้งานได้สำหรับฉัน
nadafafif

36

คุณสามารถเพิ่มUITapGestureRecognizerการ IMAGE ดูเพียงแค่ลากเข้าไปใน Storyboard / Xib, กด Ctrl และลากของคุณจาก IMAGE ดูไป gestureRecognizer และกด Ctrl และลากจาก gestureRecognizer IBActionกับสวิฟท์ไฟล์ที่จะทำให้

คุณจะต้องเปิดใช้งานการโต้ตอบกับผู้ใช้ในUIImageView, ดังที่แสดงในภาพนี้: ป้อนคำอธิบายรูปภาพที่นี่


4
UIImageViewไม่ตอบสนองต่อการสัมผัสโดยค่าเริ่มต้น คุณต้องเปิดใช้งานการโต้ตอบของผู้ใช้
rmaddy

@rmaddy โอ๊ะนั่นเป็นเรื่องจริง แก้ไข
Emil

1
ฉันชอบวิธีที่คุณสามารถตั้งค่านี้โดยใช้ IB การลาก / วางมีประสิทธิภาพและไม่คาดหวังว่าจะเป็นไปได้ +1 สำหรับสิ่งนั้น ในฐานะที่เป็น noob มันจะง่ายที่จะไม่รู้ว่ามันเชื่อมต่อกันอย่างไร ขึ้นอยู่กับความชอบของคุณ แต่ฉันชอบที่จะ "เห็นมันเป็นรหัส"
angryITguy

14

สำหรับ swift 2.0 ขึ้นไปทำเช่นนี้

@IBOutlet weak var imageView: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let tap = UITapGestureRecognizer(target: self, action: #selector(ViewController.tappedMe))
        imageView.addGestureRecognizer(tap)
        imageView.userInteractionEnabled = true
    }
    func tappedMe()
    {
        print("Tapped on Image")
    }

userInteractionEnabled ได้เปลี่ยนชื่อเป็น isUserInteractionEnabled แล้ว
Chaim Friedman

11

รหัส Swift4

ลองใช้วิธีส่วนขยายใหม่นี้:

import UIKit

extension UIView {

    fileprivate struct AssociatedObjectKeys {
        static var tapGestureRecognizer = "MediaViewerAssociatedObjectKey_mediaViewer"
    }

    fileprivate typealias Action = (() -> Void)?


    fileprivate var tapGestureRecognizerAction: Action? {
        set {
            if let newValue = newValue {
                // Computed properties get stored as associated objects
                objc_setAssociatedObject(self, &AssociatedObjectKeys.tapGestureRecognizer, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
            }
        }
        get {
            let tapGestureRecognizerActionInstance = objc_getAssociatedObject(self, &AssociatedObjectKeys.tapGestureRecognizer) as? Action
            return tapGestureRecognizerActionInstance
        }
    }


    public func addTapGestureRecognizer(action: (() -> Void)?) {
        self.isUserInteractionEnabled = true
        self.tapGestureRecognizerAction = action
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture))
        self.addGestureRecognizer(tapGestureRecognizer)
    }


    @objc fileprivate func handleTapGesture(sender: UITapGestureRecognizer) {
        if let action = self.tapGestureRecognizerAction {
            action?()
        } else {
            print("no action")
        }
    }

}

ตอนนี้เมื่อใดก็ตามที่เราต้องการที่จะเพิ่มUITapGestureRecognizerไปUIViewหรือUIViewsubclass เช่นUIImageViewเราสามารถทำได้โดยไม่ต้องสร้างฟังก์ชั่นที่เกี่ยวข้องสำหรับเตอร์!

การใช้งาน:

 profile_ImageView.addTapGestureRecognizer {
        print("image tapped")
    }

2
ใช้งานได้ดี และมันก็ทำให้การดำเนินงานง่ายขึ้นมาก
Nick N

ทำให้ฉันกลัวนิดหน่อยเมื่อใช้ฟังก์ชั่นการสะท้อนภาพ - มีโอกาสที่จะเกิดอะไรขึ้นในเวอร์ชั่นที่รวดเร็วในอนาคตหรือไม่?
BananaAcid

1
นี่คือความสง่างามและเป็นประโยชน์ ใช้งานได้สำหรับฉัน
Taylor Maxwell

2
love ฉันรักส่วนขยาย
ริคาร์โด้

8

คุณสามารถจริงเพียงแค่ตั้งค่าภาพของสิ่งที่คุณจะใส่ตามปกติในUIButton UIImageViewตัวอย่างเช่นคุณจะทำสิ่งใด:

myImageView.image = myUIImage

คุณสามารถใช้แทน:

myButton.setImage(myUIImage, forState: UIControlState.Normal)

ดังนั้นนี่คือสิ่งที่รหัสของคุณอาจมีลักษณะ:

override func viewDidLoad(){
  super.viewDidLoad()

  var myUIImage: UIImage //set the UIImage here
  myButton.setImage(myUIImage, forState: UIControlState.Normal)
}

@IBOutlet var myButton: UIButton!
@IBAction func buttonTap(sender: UIButton!){
  //handle the image tap
}

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

myButton.setTitle("Loading Image...", forState: UIControlState.Normal)

เพื่อบอกผู้ใช้ของคุณว่าคุณกำลังโหลดภาพ


2

จำเป็นต้องเพิ่มความขี้เกียจสำหรับ TapGestureRecognizer เพื่อลงทะเบียน
ตั้งแต่ 'ตัวเอง' ใน UITapGestureRecognizer (เป้าหมาย: ตัวเอง ... ) จะเป็นศูนย์หากไม่มี var ที่ขี้เกียจ แม้ว่าคุณจะตั้งค่า isUserInteractionEnable = true มันจะไม่ลงทะเบียนโดยไม่ต้องแจ้งให้ทราบ

lazy var imageSelector : UIImageView = {
    let image = UIImageView(image: "imageName.png")
    //now add tap gesture
    image.isUserInteractionEnabled = true
    image.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleImageSelector)))
    return image
}()
@objc private func handleImageSelector() {
    print("Pressed image selector")
}

1

คุณสามารถใส่UIButtonกับพื้นหลังโปร่งใสด้านบนของUIImageViewและฟังการแตะที่ปุ่มก่อนที่จะโหลดภาพ


1
มันเป็นวิธีที่รวดเร็วในการอธิบายตัวเลือก ฉันคิดว่าทุกคนรู้ว่า!
depsch ali

3
ไม่ใช่ความคิดที่ดีที่จะเพิ่มส่วนประกอบ UI ที่ไม่จำเป็นโดยไม่มีเหตุผลจริง มันจะเพิ่มความซับซ้อนของ UI และคุณต้องจัดการกับข้อ จำกัด เค้าโครงอัตโนมัติเดียวกัน เป็นการดีกว่าที่จะเพิ่ม TapGestureRecognizer
Gunhan

1

Swift 4 Code


ขั้นตอนที่ 1 ใน ViewdidLoad ()

   let pictureTap = UITapGestureRecognizer(target: self, action: #selector(MyInfoTableViewController.imageTapped))
       userImageView.addGestureRecognizer(pictureTap)
       userImageView.isUserInteractionEnabled = true

ขั้นตอนที่ 2 เพิ่มฟังก์ชั่นการติดตาม

@objc func imageTapped() {

        let imageView = userImageView
        let newImageView = UIImageView(image: imageView?.image)
        newImageView.frame = UIScreen.main.bounds
        newImageView.backgroundColor = UIColor.black
        newImageView.contentMode = .scaleAspectFit
        newImageView.isUserInteractionEnabled = true
        let tap = UITapGestureRecognizer(target: self, action: #selector(dismissFullscreenImage))
        newImageView.addGestureRecognizer(tap)
        self.view.addSubview(newImageView)

        self.navigationController?.isNavigationBarHidden = true
        self.tabBarController?.tabBar.isHidden = true

    }

มันผ่านการทดสอบและทำงานอย่างถูกต้อง


0

ฉันขอแนะนำให้วางปุ่มที่มองไม่เห็น (opacity = 0) ในมุมมองภาพของคุณแล้วจัดการกับปุ่มโต้ตอบ

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