2014-07-14 17 views
5

Attualmente mi sto legando per familiarizzare con UIKit con Swift e definisco il modo migliore di aggiungere elementi dell'interfaccia utente a livello di codice. Tuttavia, sto scoprendo che un tocco può terminare al di fuori del pulsante in cui è iniziato, ma ancora registrati come evento TouchUpInside. Il ViewController di seguito è da un'applicazione a vista singola ed è semplice iniziare un tocco, diciamo, sul pulsante 17, terminarlo sul pulsante 18 e avere ancora il pulsante Action() dichiarare "Button toccato: 17".TouchUpInside boundaries outside UIButton

Qualche idea di cosa mi manca qui? (Edit: Questo è in fase di Xcode 6 beta 3 BTW.)

// ViewController.swift 

import UIKit 

class ViewController: UIViewController { 
    let scrollView:UIScrollView = UIScrollView() 

    var GWIDTH:Float = 0.0 
    var GHEIGHT:Float = 0.0 


    override func viewDidLoad() { 
     super.viewDidLoad() 

     GWIDTH = self.view.bounds.size.width 
     GHEIGHT = self.view.bounds.size.height 

     scrollView.frame = CGRectMake(10, 10, GWIDTH-10, GHEIGHT-20) 
     scrollView.contentSize = CGSize(width:GWIDTH-20, height: 0) 
     self.view.addSubview(scrollView) 

     for currentTag in 1...30{ 
      var currentButton = UIButton.buttonWithType(UIButtonType.System) as UIButton 
      currentButton.frame = CGRectMake(100, scrollView.contentSize.height, 100, 50) 
      currentButton.backgroundColor = UIColor.greenColor() 
      currentButton.setTitle("Test Button \(currentTag)", forState: UIControlState.Normal) 
      currentButton.tag = currentTag 
      currentButton.addTarget(self, action: "buttonAction:", forControlEvents: UIControlEvents.TouchUpInside) 

      scrollView.addSubview(currentButton) 
      scrollView.contentSize = CGSize(width:GWIDTH-20,height:2.0+currentButton.frame.size.height+currentButton.frame.origin.y) 
     }//next 
    }// end viewDidLoad() 


    func buttonAction(sender:UIButton!){ 
     println("Button tapped: \(sender.tag)") 
    } 


    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 


    override func prefersStatusBarHidden() -> Bool { 
     return true 
    } 
} 

risposta

6

Va bene c'è voluto un bel po 'di scavare per andare a fondo di questo, ma un paio di link utili Obj-C ...

UIControlEventTouchDragExit triggers when 100 pixels away from UIButton

How to correctly subclass UIControl?

http://www.bytearray.org/?p=5336 (specialmente linea 89)

... e sembra che il comportamento sia standard a causa dell'interfaccia touch (personalmente trovo istintivamente la zona di default eccessiva ma sono sicuro che Apple ha fatto i compiti) e può essere sostituita da UIControl in sottoclasse o che interroga la posizione dell'evento di controllo.

ho optato per quest'ultimo ed ecco un'implementazione specificatamente a Swift:

// ViewController.swift 

import UIKit 

class ViewController: UIViewController { 
    let buttonCount = 3 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     for currentTag:Int in 1...buttonCount{ 
      var currentButton = UIButton.buttonWithType(UIButtonType.System) as UIButton 
      currentButton.frame = CGRectMake(50, Float(currentTag*50), 120, 50) 
      currentButton.backgroundColor = UIColor.greenColor() 
      currentButton.setTitle("Test Button \(currentTag)", forState: UIControlState.Normal) 
      currentButton.contentEdgeInsets = UIEdgeInsets(top:3,left:6,bottom:3,right:6) 
      currentButton.tag = currentTag 
      currentButton.addTarget(self, 
       action: "btn_TouchDown:", 
       forControlEvents: UIControlEvents.TouchDown) 
      currentButton.addTarget(self, 
       action: "btn_TouchDragExit:", 
       forControlEvents: UIControlEvents.TouchDragExit) 
      currentButton.addTarget(self, 
       action: "btn_TouchUpInside:event:", 
       forControlEvents: UIControlEvents.TouchUpInside) 
      currentButton.sizeToFit() 

      self.view.addSubview(currentButton) 
     }//next 
    }// end viewDidLoad() 


    func btn_TouchDown(sender:UIButton!){ 
     println("TouchDown event: \(sender.tag)\n") 
    } 

    func btn_TouchDragExit(sender:UIButton!){ 
     println("TouchDragExit event: \(sender.tag)\n") 
    } 

    func btn_TouchUpInside(sender:UIButton!,event:UIEvent!){ 
     println("TouchUpInside event: \(sender.tag)") 

     var currentTouch:CGPoint = event.allTouches().anyObject().locationInView(sender) 
     println("Point: \(currentTouch.x), \(currentTouch.y)\n") 
     if currentTouch.x > sender.frame.width{return} 
     if currentTouch.x < 0 {return} 
     if currentTouch.y > sender.frame.height{return} 
     if currentTouch.y < 0 {return} 

     println("Event ended within frame!") 
    } 


    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 


    override func prefersStatusBarHidden() -> Bool { 
     return true 
    } 
}