gpt4 book ai didi

ios - 防止 MKMapView 更改选择(干净地)

转载 作者:可可西里 更新时间:2023-11-01 04:51:49 25 4
gpt4 key购买 nike

我有一个显示自定义标注的 MKPinAnnotationView 的自定义子类。我想处理该注释内的触摸事件。

我有一个可行的解决方案(如下),但感觉不对。我有一个经验法则,每当我使用 performSelector: .. withDelay: 时,我都是在与系统作斗争,而不是在使用它。

对于 MKMapView 的积极事件处理和注释选择处理,有没有人有一个好的、干净的解决方法?

我目前的解决方案:

(我的注释选择类中的所有代码)

我自己进行 HitTest (如果没有这个,我的手势识别器不会在 map View 使用事件时触发:

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event; {
// To enable our gesture recogniser to fire. we have to hit test and return the correct view for events inside the callout.

UIView* hitView = nil;

if (self.selected) {
// check if we tpped inside the custom view
if (CGRectContainsPoint(self.customView.frame, point))
hitView = self.customView;
}

if(hitView) {
// If we are performing a gesture recogniser (and hence want to consume the action)
// we need to turn off selections for the annotation temporarily
// the are re-enabled in the gesture recogniser.
self.selectionEnabled = NO;

// *1* The re-enable selection a moment later
[self performSelector:@selector(enableAnnotationSelection) withObject:nil afterDelay:kAnnotationSelectionDelay];

} else {
// We didn't hit test so pass up the chain.
hitView = [super hitTest:point withEvent:event];
}

return hitView;
}

请注意,我还关闭了选择,以便在我覆盖的 setSelected 中我可以忽略取消选择。

- (void)setSelected:(BOOL)selected animated:(BOOL)animated; {
// If we have hit tested positive for one of our views with a gesture recogniser, temporarily
// disable selections through _selectionEnabled
if(!_selectionEnabled){
// Note that from here one, we are out of sync with the enclosing map view
// we're just displaying out callout even though it thinks we've been deselected
return;
}

if(selected) {
// deleted code to set up view here
[self addSubview:_customView];

_mainTapGestureRecogniser = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(calloutTapped:)];
[_customView addGestureRecognizer: _mainTapGestureRecogniser];

} else {
self.selected = NO;
[_customView removeFromSuperview];
}


}

这是我不喜欢的评论 1 行,但在 theta 延迟开火结束时它也很毛茸茸。我必须沿着 super View 链返回到 mapView,这样我才能说服它选择仍然存在。

// Locate the mapview so that we can ensure it has the correct annotation selection state after we have ignored selections.
- (void)enableAnnotationSelection {
// This reenables the seelction state and resets the parent map view's idea of the
// correct selection i.e. us.
MKMapView* map = [self findMapView];
[map selectAnnotation:self.annotation animated:NO];
_selectionEnabled = YES;

}

-(MKMapView*)findMapView; {
UIView* view = [self superview];
while(!_mapView) {
if([view isKindOfClass:[MKMapView class]]) {
_mapView = (MKMapView*)view;
} else if ([view isKindOfClass:[UIWindow class]]){
return nil;
} else{
view = [view superview];
if(!view)
return nil;
}
}

return _mapView;
}

这一切似乎都没有缺点(就像我从其他解决方案中看到的闪烁一样。它相对简单,但感觉不对。

谁有更好的解决方案?

最佳答案

我认为您不需要对 map View 的选择跟踪进行操作。如果我正确地解释了你想要的,你应该能够通过 hitTest:withEvent: 覆盖和 canShowCallout 设置为 NO。在 setSelected: 中相应地执行标注出现/消失动画。您还应该覆盖 setHighlighted: 并调整自定义标注的显示(如果可见)。

关于ios - 防止 MKMapView 更改选择(干净地),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24185465/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com