自定义注释,带按钮的自定义标注,带动作

时间:2015-02-20 22:09:51

标签: ios objective-c mapkit mkannotation mkannotationview

这是我第一次处理注释和标注。我大部分时间都在工作(尽管可能不是正确的方法)

所以,我有我的mapView:

@interface MapViewController : BaseUIViewController 

<MKMapViewDelegate, CLLocationManagerDelegate>
@property (strong, nonatomic) IBOutlet MKMapView *mapView;
@property (strong, nonatomic) NSMutableArray *friendsAnnotations;
@property (strong, nonatomic) NSMutableArray *friendsResults;

@property (strong, nonatomic) NSTimer *reloadTimer;

- (IBAction)zoomButtonPressed:(id)sender;

@property (strong, nonatomic) IBOutlet UIButton *zoomButton;
@end

计时器,我已经设置了在你屏幕上每分钟重新加载地图。它称这些函数为:

#pragma mark - Update Map Annotations

- (void) getFriendsForAnnotations {
    [User syncUserWithCompletionHandler:^{
        [ServerComm listCollection:UsersCollection withValues:[DEFAULTS objectForKey:userActiveFriendsKey] forKey:mongoIDKey withCompletionHandler:^(NSDictionary *response) {
            [self.mapView removeAnnotations:self.friendsAnnotations];
            [self.friendsAnnotations removeAllObjects];
            self.friendsResults = [[response objectForKey:@"results"] mutableCopy];

            dispatch_group_t group = dispatch_group_create();
            for (id userDic in self.friendsResults) {
                User *theUser = [User userFromDictionary:userDic];

                dispatch_group_enter(group);
                if ([[userDic objectForKey:userPrivacyLevelKey] integerValue] == 0 ||
                    [[userDic objectForKey:userPrivacyLevelKey] integerValue] == 1
                    ){
                    NSDictionary *locationDic = [userDic objectForKey: userLastLocationKey];
                    BOOL checkedIn = FALSE;
                    if(![theUser.checkedInLocationName isEqualToString:EMPTYSTRING]) {

                        checkedIn = TRUE;
                    }
                    CustomAnnotation *CA = [[CustomAnnotation alloc] initWithTitle:[userDic objectForKey:userUsernameKey] Location:CLLocationCoordinate2DMake([[locationDic objectForKey:@"latitude"] doubleValue], [[locationDic objectForKey:@"longitude"] doubleValue]) UserImage:[userDic objectForKey:userProfilePictureURLKey] isCheckedIn:checkedIn];

                    [CA setCalloutUser:theUser];
                    [self.friendsAnnotations addObject: CA];
                }

                dispatch_group_leave(group);
            }
            dispatch_group_notify(group, dispatch_get_main_queue(), ^{
                [self plotAnnotationsOnMap:self.friendsAnnotations];
            });
        }];
    }];
}

- (void) plotAnnotationsOnMap: (NSArray *) arrayOfLocations {
    [self.mapView addAnnotations: self.friendsAnnotations];
}

关键是,设置初始注释以与标准initWithAnnotation方法一起使用。

在地图上绘制注释的最后一步是viewForAnnotation方法:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
    if ([annotation isKindOfClass:[CustomAnnotation class]]) {
        CustomAnnotation *myAnnotation = ((CustomAnnotation *)annotation);
        CustomAnnotation *annotationView = (CustomAnnotation *) [self.mapView dequeueReusableAnnotationViewWithIdentifier:@"customAnnotation"];
        if (annotationView == nil) {
            annotationView = [[CustomAnnotation alloc] initWithAnnotation:myAnnotation.annotation reuseIdentifier:@"customAnnotation"];
        }

        [annotationView setAnnotation:annotation];
        [annotationView.userImage sd_setImageWithURL:[NSURL URLWithString:myAnnotation.userImageString]];
        [annotationView setUserImageString:myAnnotation.userImageString];
        [annotationView setCalloutUser:myAnnotation.calloutUser];
        if (myAnnotation.isCheckedIn) {

            annotationView.markerImage.image = [annotationView.markerImage.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
            [annotationView.markerImage setTintColor:COLOR_BLUE_MUTED];
        } else {
            annotationView.markerImage.image = [annotationView.markerImage.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
            [annotationView.markerImage setTintColor:COLOR_GREY_LIGHT];
        }
        annotationView.centerOffset = CGPointMake(0, -39);
        annotationView.rightCalloutAccessoryView = [UIButton buttonWithType: UIButtonTypeDetailDisclosure];
        annotationView.canShowCallout = NO;

        return annotationView;
    } else {
        return nil;
    }
}

Here, we have what my annotations look like at the end of this series of steps.

此注释使用您通常期望的CustomAnnotation.h / m文件定义,并从xib中提取。

#import <Foundation/Foundation.h>
#import "CustomAnnotationCallout.h"
#import <MapKit/MapKit.h>
@interface CustomAnnotation : MKAnnotationView <MKAnnotation>

@property (nonatomic, assign) IBOutlet UIView* loadedView;
@property (nonatomic, strong) User *calloutUser;

@property (nonatomic, strong) UIView *calloutView;
@property (retain, nonatomic) IBOutlet UIImageView *markerImage;
@property (retain, nonatomic) IBOutlet UIImageView *userImage;
@property (retain, nonatomic) NSString *userImageString;
@property (copy, nonatomic) NSString *title;
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@property (assign, nonatomic) BOOL isCheckedIn;
@property (assign, nonatomic) BOOL showCustomCallout;
@property (assign, nonatomic) CGRect endFrame;
- (id) initWithTitle:(NSString *)newTitle Location:(CLLocationCoordinate2D)location UserImage:(NSString *)userImageString isCheckedIn:(BOOL)checkedIn;
- (void) setShowCustomCallout:(BOOL)showCustomCallout;
- (void) setShowCustomCallout:(BOOL)showCustomCallout animated:(BOOL)animated;

@end

和.m文件:

#import "CustomAnnotation.h"
#import "CustomAnnotationCallout.h"
#import "Utilities.h"
#import "UIImageView+WebCache.h"
@implementation CustomAnnotation
- (id) initWithTitle:(NSString *)newTitle Location:(CLLocationCoordinate2D)location UserImage:(NSString *)userImageString isCheckedIn:(BOOL)checkedIn{
    self = [super init];
    [[NSBundle mainBundle] loadNibNamed:@"AnnotationView" owner:self options:nil];
    if (self) {

        if (_loadedView) {
            _loadedView.frame = CGRectMake(_loadedView.frame.origin.x, _loadedView.frame.origin.y, 80, 80);
            [self addSubview:_loadedView];
            self.userImageString = userImageString;
        }
        self.userImageString = userImageString;
        _title = newTitle;
        _coordinate = location;
        self.isCheckedIn = checkedIn;
        self.enabled = YES;
        self.canShowCallout = NO;
        self.image = [UIImage imageNamed:@"icon_clear"];
        self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, 80, 80);
        self.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

    }
    return self;
}

- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString*)reuseIdentifier
{
    self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
    if (self != nil)
    {
        [[NSBundle mainBundle] loadNibNamed:@"AnnotationView" owner:self options:nil];
        if (_loadedView){

            _loadedView.frame = CGRectMake(_loadedView.frame.origin.x, _loadedView.frame.origin.y, 80, 80);
            [self addSubview:_loadedView];
        }
        self.enabled = YES;
        self.canShowCallout = NO;
        self.image = [UIImage imageNamed:@"icon_clear"];
        self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, 80, 80);
        self.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    }

    return self;
}

- (void) setShowCustomCallout:(BOOL)showCustomCallout {
    [self setShowCustomCallout:showCustomCallout animated:NO];
}

- (void) setShowCustomCallout:(BOOL)showCustomCallout animated:(BOOL)animated {
    if (_showCustomCallout == showCustomCallout) return;
    _showCustomCallout = showCustomCallout;
    void (^animationBlock)(void) = nil;
    void(^completionBlock)(BOOL finished) = nil;
    if (_showCustomCallout) {
        self.calloutView.alpha = 0.0f;
        animationBlock = ^ {
            self.calloutView.alpha = 1.0f;
            [self addSubview:self.calloutView];
        };
    } else {
        animationBlock = ^{ self.calloutView.alpha = 0.0f; };
        completionBlock = ^(BOOL finished) { [self.calloutView removeFromSuperview]; };
    }

    if (animated) {
        [UIView animateWithDuration:0.2f animations:animationBlock completion:completionBlock];

    } else {
        animationBlock();
        completionBlock(YES);
    }
}

@end

现在,如果我们点击注释,我们就会获得自定义标注:

MapViewController代码:

- (void) mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
    if ([view isKindOfClass:CustomAnnotation.class]) {
        CustomAnnotation *annotationView = (CustomAnnotation *)view;
        CustomAnnotationCallout *callout = [CustomAnnotationCallout new];
        callout.userImageString = annotationView.userImageString;
        [callout.userImage sd_setImageWithURL:[NSURL URLWithString:callout.userImageString]];
        [callout.nameLabel setText:[NSString stringWithFormat:@"%@ @%@", annotationView.calloutUser.name, annotationView.calloutUser.username]];
        [callout setUserID:annotationView.calloutUser.userID];

        annotationView.calloutView = callout.loadedView;
        annotationView.calloutView.center = CGPointMake(annotationView.bounds.size.width*0.5f, -annotationView.calloutView.bounds.size.height*0.5f);
        [annotationView setShowCustomCallout:YES animated:YES];
        CGRect annotationViewWithCalloutViewFrame = annotationView.frame;
        annotationViewWithCalloutViewFrame.size.width += annotationView.calloutView.frame.size.width;
        annotationViewWithCalloutViewFrame.size.height += annotationView.calloutView.frame.size.height;

        CGRect mapRect = [self.mapView convertRegion:self.mapView.region toRectToView:self.mapView];
        mapRect.origin.y = annotationView.frame.origin.y-annotationView.calloutView.frame.size.height;
        mapRect.origin.x = annotationView.frame.origin.x+annotationView.calloutView.frame.origin.x;

        MKCoordinateRegion finalRegion = [self.mapView convertRect:mapRect toRegionFromView:self.mapView];
        [self.mapView setRegion:finalRegion animated:YES];

        [self.mapView setScrollEnabled:NO];
        [self.mapView setZoomEnabled:NO];
        [self.reloadTimer invalidate];
    }
}

CustomAnnotationCallout也从xib中拉入。

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface CustomAnnotationCallout : UIView

@property (strong, nonatomic) IBOutlet UIView *loadedView;
@property (strong, nonatomic) IBOutlet UIImageView *userImage;
@property (assign, nonatomic) NSString *userImageString;
@property (strong, nonatomic) IBOutlet UILabel *nameLabel;
@property (strong, nonatomic) NSString *userID;

- (IBAction)profilePressed:(id)sender;
- (IBAction)button1:(id)sender;
- (IBAction)button2:(id)sender;

@end

和.m:

#import "CustomAnnotationCallout.h"
@implementation CustomAnnotationCallout

- (instancetype)init {
    [[NSBundle mainBundle] loadNibNamed:@"CustomAnnotationCallout" owner:self options:nil];
    _loadedView.frame = CGRectMake(_loadedView.frame.origin.x, _loadedView.frame.origin.y, [[UIScreen mainScreen] bounds].size.width, 178.0);
    return self;
}

- (IBAction)profilePressed:(id)sender {
}

- (IBAction)button1:(id)sender {
}

- (IBAction)button2:(id)sender {
}
@end

现在,当我们选择注释时,我们的自定义标注会更改,并且地图会将自身重新定位到我选择的位置。我们得到了这个观点:

Selected Annotation to show Custom Callout

现在您已经看到我所拥有的功能,以及我的目标。我遇到的问题是如何在点击时获取标注上的按钮以执行特定任务。

我已经用Google搜索并阅读了有关hitTest的信息,但是无法正确地弄清楚如何正确实现它,特别是在寻求使用特定元素时。

我整个星期都从头到尾都在这里,这就是我被困的地方。请注意我已经进行了大约4个月的iOS开发,所以我还是比较新的。

0 个答案:

没有答案