2016-04-14 47 views
1

我試圖創建一個UIControl的子類和跟蹤觸摸來改變控制外觀。
自定義UIControl,動作調用兩次

我不知道爲什麼,但如果我從IB或代碼中添加動作(對於.TouchUpInside),當我觸摸控件時,register動作方法會被調用兩次。
堆棧跟蹤告訴我,第一個電話來自_sendActionsForEvents:withEvent:,第二個不清楚。
這裏有我如何重寫跟蹤方法:

override func continueTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool { 
     let touchPoint = touch.locationInView(self) 
     if CGRectContainsPoint(bounds, touchPoint) { 
      sendActionsForControlEvents(.TouchDragInside) 
     } 
     else { 
      sendActionsForControlEvents(.TouchDragOutside) 
     } 
     return true 
    } 


override func beginTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool { 
    sendActionsForControlEvents(.TouchDown) 
    return true 
} 

override func endTrackingWithTouch(touch: UITouch?, withEvent event: UIEvent?) { 
    guard let tou = touch else { return } 
    let touchPoint = tou.locationInView(self) 
    if CGRectContainsPoint(bounds, touchPoint) { 
     sendActionsForControlEvents(.TouchUpInside) 
    } 
    else { 
     sendActionsForControlEvents(.TouchUpOutside) 
    } 
} 

override func cancelTrackingWithEvent(event: UIEvent?) { 
    sendActionsForControlEvents(.TouchCancel) 
} 

我還發現這answer,但它似乎並不適合我的問題,因爲當我添加了目標.TouchUpInside事件我不如該答案中所述,不會從事件調度程序自動執行任何操作。

+0

您是否在每個sendActionsForControlEvents上放置了斷點並查看是否有超過1個命中?您是否觸發touchDown事件一次,觸發TouchUpInside事件一次? – fsb

+0

當然,我想我已經找到了答案。我會在稍後發佈。基本上看來,動作已經由超類發送了,但是我想追蹤所有事件或者僅僅幾個。所以我發送了一些已發送的內容 – Andrea

回答

1

我發現我誤解了文檔,可能有很多人在那裏(看到互聯網上的一些樣本)。
覆蓋上述方法並不能讓你管理事件分派,這樣做應該可以更好地使用sendAction:to:forEvent:
這些考慮來後,我做了一個UIControl子一個小項目,並添加了一些行動最流行控制事件:

  • 觸地降落
  • 觸摸的內心
  • 潤色外
  • 拖到外面
  • 拖入裏面
  • 更改值

成績
除了值改變,所有的其他事件已經調用,即使跟蹤方法覆蓋。如果我們想發送一個改變的值,我們必須自己調用它,這是有道理的,因爲根據它的名字與觸摸無關。我發現有趣的
一件事是跟蹤外時被調用,它似乎當用戶拖動手指更多的控制範圍之外的約50%,我原以爲會被稱爲合格的界限之後

class TestControl: UIControl { 
    override func beginTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool { 
     let touchPoint = touch.locationInView(self) 
     print(touchPoint) 
     return true 
    } 
    override func continueTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool { 
     let touchPoint = touch.locationInView(self) 
     print(touchPoint) 

     return true 
    } 

    override func endTrackingWithTouch(touch: UITouch?, withEvent event: UIEvent?) { 
     guard let touch = touch else { return } 
     let touchPoint = touch.locationInView(self) 
     print(touchPoint) 

    } 
} 

class ViewController: UIViewController { 

    @IBOutlet weak var tezst: TestControl! 


    @IBAction func touchDown(sender: AnyObject){ 
     print("Touch Down") 
    } 
    @IBAction func touchUpInside(sender: AnyObject){ 
     print("Touch up inside") 
    } 

    @IBAction func touchUpOutside(sender: AnyObject){ 
     print("Touch up outside") 
    } 
    @IBAction func touchDragOutside(sender: AnyObject){ 
     print("Touch drag outside") 
    } 
    @IBAction func touchDragInside(sender: AnyObject){ 
     print("Touch drag inside") 
    } 
    @IBAction func valueChanged(sender: AnyObject){ 
     print("Value changed") 
    } 
}