如何处理自定义标注视图上的点击?
How to handle taps on a custom callout view?
我正在添加这样的标注视图:
func mapView(mapView: MKMapView!,
didSelectAnnotationView view: MKAnnotationView!) {
let calloutView = UIView(frame:
CGRect(x: 0, y: 0, width: 300, height: 120))
calloutView.backgroundColor = UIColor.purpleColor()
calloutView.center = CGPointMake(CGRectGetWidth(view.bounds) / 2.0, 0.0)
calloutView.layer.anchorPoint = CGPointMake(0.5, 1.0)
calloutView.layer.masksToBounds = false
calloutView.userInteractionEnabled = true
let calloutViewTapRecognizer = UITapGestureRecognizer(target: self,
action: "onCalloutViewTap")
calloutView.addGestureRecognizer(calloutViewTapRecognizer)
view.addSubview(calloutView)
}
虽然我的 onCalloutViewTap
函数从未被调用过...我很想知道为什么,并想得到一些可以处理与我的标注视图交互的东西。
这是因为您的注释视图仅检测其边界内的触摸。由于您的标注视图超出范围,因此子视图无法识别水龙头。您需要覆盖注释视图中的 pointInside:withEvent:
方法,这样您的标注才能真正检测到触摸。
这是 Objective-C 中的示例:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event
{
CGRect rect = self.bounds;
BOOL isInside = CGRectContainsPoint(rect, point);
if (!isInside)
{
for (UIView *view in self.subviews)
{
isInside = CGRectContainsPoint(view.frame, point);
if (isInside)
{
break;
}
}
}
return isInside;
}
编辑:
Swift版本:
override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
let rect = self.bounds
var isInside = CGRectContainsPoint(rect, point)
if (!isInside) {
for subview in subviews {
isInside = CGRectContainsPoint(subview.frame, point)
if (isInside) {
break
}
}
}
println(isInside)
return isInside;
}
Swift 4.0
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let rect = self.bounds;
var isInside: Bool = rect.contains(point);
if(!isInside)
{
for view in self.subviews
{
isInside = view.frame.contains(point);
if isInside
{
break;
}
}
}
return isInside;
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let hitView = super.hitTest(point, with: event)
if (hitView != nil)
{
self.superview?.bringSubview(toFront: self)
}
return hitView
}
正在从注释视图中删除 swift 5
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let hitView = super.hitTest(point, with: event)
if (hitView != nil)
{
self.superview?.bringSubviewToFront(self)
}
return hitView
}
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let rect = self.bounds;
var isInside: Bool = rect.contains(point);
if(!isInside)
{
for view in self.subviews
{
isInside = view.frame.contains(point);
if isInside
{
break;
}
}
}
return isInside;
}
我正在添加这样的标注视图:
func mapView(mapView: MKMapView!,
didSelectAnnotationView view: MKAnnotationView!) {
let calloutView = UIView(frame:
CGRect(x: 0, y: 0, width: 300, height: 120))
calloutView.backgroundColor = UIColor.purpleColor()
calloutView.center = CGPointMake(CGRectGetWidth(view.bounds) / 2.0, 0.0)
calloutView.layer.anchorPoint = CGPointMake(0.5, 1.0)
calloutView.layer.masksToBounds = false
calloutView.userInteractionEnabled = true
let calloutViewTapRecognizer = UITapGestureRecognizer(target: self,
action: "onCalloutViewTap")
calloutView.addGestureRecognizer(calloutViewTapRecognizer)
view.addSubview(calloutView)
}
虽然我的 onCalloutViewTap
函数从未被调用过...我很想知道为什么,并想得到一些可以处理与我的标注视图交互的东西。
这是因为您的注释视图仅检测其边界内的触摸。由于您的标注视图超出范围,因此子视图无法识别水龙头。您需要覆盖注释视图中的 pointInside:withEvent:
方法,这样您的标注才能真正检测到触摸。
这是 Objective-C 中的示例:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event
{
CGRect rect = self.bounds;
BOOL isInside = CGRectContainsPoint(rect, point);
if (!isInside)
{
for (UIView *view in self.subviews)
{
isInside = CGRectContainsPoint(view.frame, point);
if (isInside)
{
break;
}
}
}
return isInside;
}
编辑:
Swift版本:
override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
let rect = self.bounds
var isInside = CGRectContainsPoint(rect, point)
if (!isInside) {
for subview in subviews {
isInside = CGRectContainsPoint(subview.frame, point)
if (isInside) {
break
}
}
}
println(isInside)
return isInside;
}
Swift 4.0
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let rect = self.bounds;
var isInside: Bool = rect.contains(point);
if(!isInside)
{
for view in self.subviews
{
isInside = view.frame.contains(point);
if isInside
{
break;
}
}
}
return isInside;
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let hitView = super.hitTest(point, with: event)
if (hitView != nil)
{
self.superview?.bringSubview(toFront: self)
}
return hitView
}
正在从注释视图中删除 swift 5
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let hitView = super.hitTest(point, with: event)
if (hitView != nil)
{
self.superview?.bringSubviewToFront(self)
}
return hitView
}
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let rect = self.bounds;
var isInside: Bool = rect.contains(point);
if(!isInside)
{
for view in self.subviews
{
isInside = view.frame.contains(point);
if isInside
{
break;
}
}
}
return isInside;
}