2017-05-24 76 views
2

因此,我在我的應用程序中顯示了一個圖像,我使用Xcode快速創建了該圖像,並且我希望例如在圖像被點擊時打印「圖像點擊」。下面是我的了:Swift 3檢查用戶點擊圖像

這是假設得到調用的函數,只要用戶點按圖片:

func imageViewTapped(imageView: UIImageView) { 
    print("Image Clicked") 
} 

我有這個功能,增加了與圖像的用戶互動:

func tapRecognition(image: UIImageView) { 
    image.isUserInteractionEnabled = true 
    let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector(("imageViewTapped:"))) 
    image.addGestureRecognizer(tapRecognizer) 
} 

最後但並非最不重要的,我創建類型的UIImageView的形象在我的viewDidLoad()函數,我叫:

tapRecognition(image: imageView) 

當我運行它並單擊圖像時,出現一個錯誤,指出:「終止於類型爲NSException的未捕獲異常」。 任何幫助將是偉大的!非常感謝。

+0

凡'imageView'被初始化? –

+1

除非您使用舊的Swift,否則您需要使用正確的選擇器語法並在選擇器中指定正確的方法名稱。 – rmaddy

+1

你有IBOutlet中連接正確,這可能會導致NSException –

回答

5

下面是一些代碼,將工作用斯威夫特3:

override func viewDidLoad() { 
    super.viewDidLoad() 

    // #1 
    let myImage = UIImage(named: "myImage") 
    let imageView = UIImageView() 
    imageView.image = myImage 

    // #2 
    imageView.isUserInteractionEnabled = true 
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped)) 
    imageView.addGestureRecognizer(tapRecognizer) 

    // #3 
    imageView.translatesAutoresizingMaskIntoConstraints = false 
    view.addSubview(imageView) 
    // set imageView contraints 

} 

// #4 
func imageTapped(recognizer: UITapGestureRecognizer) { 
    print("Image was tapped") 
    let thePoint = recognizer.location(in: view) 
    let theView = recognizer.view 
} 
  • 1當你的代碼是有點不同的,有些缺失,我相信這基本上是一樣的。除非您需要在其他地方訪問imageimageView,否則請在viewDidLoad的本地聲明。 (我建議不要像命名UIImageView那樣命名(image),因爲這可能會讓其他人讀到您的代碼時感到困惑。)

  • 2這裏是我認爲@rmaddy正確的地方。如果你使用的是Swift 3,選擇器的正確語法是我所擁有的。這可能是我們的代碼唯一的問題 - 記住UIImageView的默認值爲isUserInteractioEnabled = true

  • 3您沒有任何實際佈局的代碼。但是如果您使用自動佈局(而不是幀),則基本語法將關閉自動調整,確保將視圖添加到視圖層次結構中,並設置約束。很多時候(大部分甚至是)您可以將它們設置爲viewDidLoad,但如果您需要需要幀信息,請使用viewWillLayoutSubviewsviewDidLayoutSubviews

  • 4起初我以爲你的水龍頭功能沒問題,但經過進一步的檢查,事實並非如此。發件人不是被點擊的視圖,而是識別器。我在print語句後添加了兩行代碼。第一個將水龍頭的CGPoint放入一個變量中。第二個將UIView附加到識別器(在這種情況下,imageView)到一個變量。此外,如果您需要知道imageView的子視圖位於水龍頭的區域中,請使用hitTest()方法。

編輯:

有人問我如何使用在水龍頭執行功能的觀點(在我的例子,imageView)。

首先,你的一件事不能做的就是把它作爲參數傳遞。 iOS和macOS都無法通過他們的操作以這種方式工作。但是你有(至少)三種選擇可供選擇。 (他們沒有使用標籤屬性,它在某些情況下是另一種選擇。)

  • 1還有你的代碼說你已經知道圖像視圖被竊聽。這是一種可能的情況,因爲您創建的每個手勢只能附加到單個視圖。如果這是你的場景,考慮在視圖控制器級別聲明你的圖像視圖,並在你的函數內編寫你需要的代碼。

  • 2但是,如果你有兩個圖像視圖查看器,都附有敲擊手勢,並且希望他們能夠根據哪個做一些被竊聽?在這種情況下,您可以使用手勢的view屬性進行投射。骨架代碼:

    let imageView1 = UIImageView() 
    let imageView2 = UIImageView() 
    let tapRecognizer1 = UITapGestureRecognizer(target: self, action: #selector(imageTapped)) 
    imageView1.addGestureRecognizer(tapRecognizer1) 
    let tapRecognizer2 = UITapGestureRecognizer(target: self, action: #selector(imageTapped)) 
    imageView2.addGestureRecognizer(tapRecognizer2) 
    
    
    func imageTapped(recognizer: UITapGestureRecognizer) { 
        print("Image was tapped") 
        let imageView = recognizer.view as? UIImageView 
        if imageView != nil { 
         //do something here 
        } 
    } 
    

    請注意,骨架在轉換中可能有語法錯誤。邏輯是堅實的,我在網上寫這篇文章,而不是Xcode。基本上將附加的UIView作爲圖像視圖並檢查nil。

  • 3,如果你有幾個子視圖,你想知道哪一個被竊聽我通常使用的情況。在你的情況下,假設你有兩個像上面那樣的UIImageViews,但是你有連接到主視圖的輕敲識別器?在這種情況下,您可以使用hitTest()方法。骨架代碼:

    let imageView1 = UIImageView() 
    let imageView2 = UIImageView() 
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped)) 
    imageView1.addGestureRecognizer(self.view) 
    
    func imageTapped(recognizer: UITapGestureRecognizer) { 
        print("Image was tapped") 
        let p = recognizer.location(in: view) 
        if imageView1.layer.hitTest(p) != nil { 
         // do something here to imageView1 
        } else if imageView2.layer.hitTest(p) != nil { 
         // do something here to imageView2 
        } 
    } 
    

    我更喜歡使用圖層,但觀點有hitTest()法也。這個值是一個包含7個子視圖的視圖,可以用一個手勢進行編碼,如果你忽略了其中3個子視圖的點擊(並且點擊主視圖),你可以。

    關於最後一個,我已經有一段一個小例子項目。它包含一個帶有兩個彩色標籤作爲子視圖的圖像視圖。當任一標籤被輕敲時,計數器遞增。我在我的答案中使用了1-2,我想我會把它放在GitHub存儲庫中。隨意看看它:Image with Labels

+0

如果我想imageTapped,因爲它的參數,因爲我想要做一些事情,當它被點擊的圖像拍攝圖像的功能......我得到的這個問題,只是說,如果要打印的東西當圖像被竊聽,但我想要對圖像做點什麼。 – tee

+1

你不能傳遞這樣的參數。但是,在這裏你可以做什麼 - (1)如果你需要查看它是否被點擊,使用'hitTest()'方法。我會爲此添加更多代碼。 (2)如果你已經*知道'UIImageView'被挖掘了 - 你可以用你已經顯示的代碼 - 然後在全局和更多的地方聲明'UIImageView'函數做你需要的。 – dfd

+0

花了我30分鐘來編輯編輯,對不起。但我有三個選項解釋,兩個與骨架代碼。我還將一個小的Swift 3 Xcode項目添加到GitHub存儲庫。希望這可以幫助你! – dfd

0

更改參數類型如下:

func imageViewTapped(imageView:UITapGestureRecognizer? = nil) { 
    print("Image Clicked") 
} 
+0

您的簽名不容易瞭解。如果函數被執行,它是**,因爲**發件人 - 一個UITapGestureRecognizer - **不是**零!然而你聲明「手勢」是一個名爲'imageView'的變量?再次,不容易理解。 – dfd