2015-08-16 57 views
4

我想了解爲什麼我的子視圖沒有收到觸動。UIView子視圖沒有收到觸動

以下是顯示我遇到的行爲的gif:當我單擊右側的青色按鈕時,沒有任何反應(左側視圖的背景應該改變顏色)。當我點擊左側的綠色按鈕時,它正確地接收到觸摸事件,觸發附加的TouchDown動作並且視圖的顏色改變。

enter image description here

這個「應用程序」顯然不是一個真正的應用程序,只是爲了說明我遇到的行爲。真的,我正在學習如何實現在許多應用程序中看到的常見「滑出菜單」模式;通常配有漢堡按鈕。

在許多這些應用程序中,它看起來像主要的應用程序內容被移到一邊來揭示菜單,「隱藏」在應用程序下面,就像它一樣。我試圖在這裏複製同樣的行爲。

我在這裏粘貼我的ViewController代碼。你在下面看到的代碼就是我擁有的一切。

import UIKit 

class ViewController: UIViewController { 

    var originalX : CGFloat! 
    var originalY : CGFloat! 

    var containerView = UIView() 

    var button : UIButton! 
    var button2 : UIButton! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     originalX  = self.view.frame.origin.x 
     originalY  = self.view.frame.origin.y 

     button = UIButton(frame: CGRectMake(200, 25, 100, 100)) 
     button.backgroundColor = UIColor.greenColor() 
     button.addTarget(self, action: "foo", forControlEvents: .TouchDown) 

     view.addSubview(button) 

     containerView.frame = CGRectMake(self.view.frame.width, originalY, 150, self.view.frame.height) 
     containerView.userInteractionEnabled = true 
     containerView.backgroundColor = UIColor.magentaColor() 
     containerView.clipsToBounds = false 

     button2 = UIButton(frame: CGRectMake(25, 25, 100, 100)) 
     button2.backgroundColor = UIColor.cyanColor() 
     button2.addTarget(self, action: "bar", forControlEvents: .TouchDown) 

     view.addSubview(containerView) 
     containerView.addSubview(button2) 
    } 

    @IBAction func left() { 
     UIView.animateWithDuration(0.3) { 
      self.view.frame = CGRectMake(self.originalX - 150, self.originalY, self.view.frame.width, self.view.frame.height) 
     } 
    } 

    @IBAction func right() { 
     UIView.animateWithDuration(0.3) { 
      self.view.frame = CGRectMake(self.originalX, self.originalY, self.view.frame.width, self.view.frame.height) 
     } 
    } 

    func foo() { 
     UIView.animateWithDuration(1.0) { 
      self.view.backgroundColor = UIColor.redColor() 
     } 
    } 

    func bar() { 
     UIView.animateWithDuration(1.0) { 
      self.view.backgroundColor = UIColor.blueColor() 
     } 
    } 

} 
+0

我沒有一個具體的答案給你,但我會看到的一件事就是你用「框架」動畫對象的方式,它是可能更好地動畫約束或變換。一個框架的動畫可以做到古怪的東西,而且不需要動畫變換。 – Loxx

回答

10

containerViewview一個子視圖,但containerView的原點是因爲該行的右其父視圖(view)的右邊緣的,:

containerView.frame = CGRectMake(self.view.frame.width, originalY, 150, self.view.frame.height) 

子視圖的任何部分,其在superview的邊界之外不會接收觸摸事件。觸摸事件將僅被傳遞並被子視圖的範圍內的範圍內的子視圖所識別。這就是爲什麼當您點按它時,青色按鈕不會「觸發」。

解決此問題的一種方法是,不要操作view的框架,而要使用輔助子視圖(稱爲overlayView)來覆蓋和覆蓋containerView,並操縱其框架。確保至少有一部分兩個視圖都在主視圖的範圍內,以便它們可以接收觸摸事件。

+0

感謝您的文章@gschandler - 您的回答並不完全清楚。爲了清晰起見你會介意編輯嗎? – bitops

+0

我想我明白你的意思overlayView - 你有任何代碼片段,你可以分享?目前我很難想象。 – bitops

+0

此外,萬一它有助於他人 - 這個鏈接與我分享一個相關的問題:https://developer.apple.com/library/ios/qa/qa2013/qa1812.html – bitops

0

您需要保持主view大到足以接收事件。使用self.view.frame.width + 150作爲CGRectMake的第三個參數left()

但是,對於你想要做的事情,這是一個奇怪而脆弱的解決方案。你不應該改變主視圖的框架。那必須繼續覆蓋整個UIWindow,沒有什麼比這更重要的了。您只想動畫子視圖,並考慮您是否真的使用了PageViewController idiomCollectionView慣用語,UIScrollView慣用語或SpriteKit慣用語。想想爲什麼你想要移動你的中央控制按鈕和你的中央標籤,使得一個不可用的「跳動」界面。

viewDidLoad()中執行佈局計算存在一個脆弱性,這在ViewController生命週期中還爲時尚早。請參閱:wrong frame size in viewDidLoad

正確的方法是更好的工作:約束自定義UIView子類以填充主視圖,然後如果必須執行非Storyboard代碼佈局計算,請在覆蓋的layoutSubviews()方法內執行此操作的定製子類 - 在這一點上,正確的幾何形狀可用。 (但是添加子視圖代碼自定義UIView子類應該在layoutSubviews(完成)',而是在施工或筆尖甦醒時間。)

事情變得很多容易,如果你的主要觀點needn」移動。如果您在Objective-C中閱讀流利,請嘗試:http://www.teehanlax.com/blog/custom-uiviewcontroller-transitions/

然後,您將得到真正的問題分離,其中您的滑動設置實際上是自包含的。引用:

這是我們要創建的交互。沒什麼特別的 - 只是一個從屏幕右邊出現的視圖。什麼是 特別是,我們實際上呈現一個視圖控制器,即使 雖然呈現視圖控制器保持可見。

+0

嘿,謝謝你的回答。我同意修改寬度不是一個好的解決方案。也許我錯過了一個不同的觀點。真的這個問題是關於複製在很多應用程序中看到的常見的「滑出」菜單模式。在這些應用程序的許多(並非全部)應用程序中,主應用程序窗口被移動以顯示側邊欄。這就是我要去的地方。 – bitops

+0

上面的「應用程序」顯然不是真正的應用程序,它是我試圖解決的問題的一個非常簡化的版本。 – bitops

+0

然後,答案的核心只是動畫子視圖幀。另外,你不應該依賴'viewDidLoad()'中的'frame'和'bounds'值。 – BaseZen

0

爲您的代碼,你必須添加containerView到self.view,但是它的框架不self.view.bounds,所以containerView無法接收任何聯繫,所以你應該做的是

  • 只要確保self.view足夠大,可以容納containerView,至少包含button2

  • 只是動畫containerView框架使其在self.view
相關問題