我目前正忙着在Swift下熟悉UIKit,并找出以编程方式添加UI元素的最佳方法。但是,我发现触摸可以在按钮之外结束,但仍然会在其中注册为TouchUpInside事件。下面的ViewController来自单个视图应用程序,可以直接开始触摸,例如,按钮17,结束按钮18,仍然有buttonAction()声明"按钮点击:17"。
知道我在这里失踪的是什么吗? (编辑:这是在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
}
}
答案 0 :(得分:6)
好的,我们花了很多时间来深入研究这个问题,但是有一些有用的Obj-C链接......
UIControlEventTouchDragExit triggers when 100 pixels away from UIButton
How to correctly subclass UIControl?
http://www.bytearray.org/?p=5336(特别是第89行)
......似乎行为是标准的,因为触摸界面(个人我本能地发现默认区域过多,但我确信Apple做了功课)并且可以通过子类化UIControl来覆盖或询问控制事件的位置。
我选择了后者,这是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
}
}