欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

UIScrollView与地图页面嵌套效果的实现。

程序员文章站 2022-06-15 12:46:01
经常使用美团或饿了的朋友都会在订单页看到一个效果,上面是个地图,下面是订单的详情。向上滑动的时候地图被覆盖掉,滑下来地图出现,而且滑动地图时只有地图的mapview在动。这种效果怎么实现呢?今天来做一下这个demo。先放效果图,两种实现方式,两种效果:1:地图随着scroll的滑动而滑动“gif有点大,CSDN不让传,请点击查看原图链接”2,地图不动。scroll自己滑动“这个gif也有点大,CSDN不让传,请点击查看原图链接”先说下第一种实现,上代码@interf.....

经常使用美团或饿了的朋友都会在订单页看到一个效果,上面是个地图,下面是订单的详情。向上滑动的时候地图被覆盖掉,滑下来地图出现,而且滑动地图时只有地图的mapview在动。这种效果怎么实现呢?今天来做一下这个demo。

先放效果图,两种实现方式,两种效果:

1:地图随着scroll的滑动而滑动

“gif有点大,CSDN不让传,请点击查看原图链接”

 

2,地图不动。scroll自己滑动

 

“这个gif也有点大,CSDN不让传,请点击查看原图链接”

先说下第一种实现,上代码

@interface MapScrollViewController ()<MKMapViewDelegate,UIGestureRecognizerDelegate>

@property (nonatomic, strong) UIScrollView *mapScv;

@end

@implementation MapScrollViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    _mapScv = [[UIScrollView alloc] init];
    _mapScv.alwaysBounceVertical = YES;
    _mapScv.scrollEnabled = YES;
    _mapScv.contentInset = UIEdgeInsetsMake(300, 0, 0, 0);
    [self.view addSubview:_mapScv];
    
    [_mapScv mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.view);
    }];
    
    UIGestureRecognizer *mainScrollVTap = [[UIGestureRecognizer alloc]init];
    mainScrollVTap.delegate=self;
    [_mapScv addGestureRecognizer:mainScrollVTap];
    
    UIView *contentView = [UIView new];
    [_mapScv addSubview:contentView];
    
    [contentView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.width.mas_equalTo(_mapScv);
    }];
    
    UIView *view = [UIView new];
    view.backgroundColor = [UIColor redColor];
    [contentView addSubview:view];
    
    [view mas_makeConstraints:^(MASConstraintMaker *make) {
        make.size.mas_equalTo(CGSizeMake(kScreenWidth, 2000));
        make.left.top.equalTo(contentView);
    }];
    
    [contentView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.bottom.mas_equalTo(view);
    }];
    
    MKMapView *map1 = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 300)];
    map1.delegate = self;
    map1.mapType = MKMapTypeStandard;
    [contentView addSubview:map1];
}

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
    //判断如果是百度地图的view 既可以实现手势拖动 scrollview 的滚动关闭
    if ([gestureRecognizer.view isKindOfClass:[MKMapView class]] ){
        _mapScv.scrollEnabled = NO;
        return YES;
    }else{
        _mapScv.scrollEnabled = YES;
        return NO;
    }
}

这样就能实现图1的效果,实现的手段主要是在self.view上添加一个全屏的UIScrollView,把地图的view作为它的子视图,然后给scroll添加一个手势,在滑动的时候去手势的代理里面判断让scroll可不可以滚动即可,当scroll滚动时。会推着地图view向上走,当滑动地图时,scroll就会不可滚动,很简单的一个实现。

第二种比较通用,看起来也比较好看,实现起来比第一种还要简单,代码:

@interface MapScrollView : UIScrollView

@end

@implementation MapScrollView

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    UIView *hitView = [super hitTest:point withEvent:event];
    if ([hitView isKindOfClass:[self class]]) {
        return nil;
    }
    return hitView;
}

@end

@interface MapScrollViewController ()<MKMapViewDelegate,UIGestureRecognizerDelegate>

@property (nonatomic, strong) MapScrollView *mapScv;

@end

@implementation MapScrollViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    MKMapView *map1 = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 300)];
    map1.delegate = self;
    map1.mapType = MKMapTypeStandard;
    [self.view addSubview:map1];
    
    _mapScv = [[MapScrollView alloc] init];
    _mapScv.alwaysBounceVertical = YES;
    _mapScv.scrollEnabled = YES;
    _mapScv.contentInset = UIEdgeInsetsMake(300, 0, 0, 0);
    [self.view addSubview:_mapScv];
    
    [_mapScv mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.view);
    }];

    UIView *contentView = [UIView new];
    [_mapScv addSubview:contentView];
    
    [contentView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.width.mas_equalTo(_mapScv);
    }];
    
    UIView *view = [UIView new];
    view.backgroundColor = [UIColor redColor];
    [contentView addSubview:view];
    
    [view mas_makeConstraints:^(MASConstraintMaker *make) {
        make.size.mas_equalTo(CGSizeMake(kScreenWidth, 2000));
        make.left.top.equalTo(contentView);
    }];
    
    [contentView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.bottom.mas_equalTo(view);
    }];
}


@end

首先我们写一个继承UIScrollView父类的MapScrollView,实现hitTest方法。

这个hitTest方法的意思就是当滑动和点击时需要处理的事件的响应链,该处理哪个view。比如我在Aview点击时,系统需要知道该处理Aview了,这时你说不要去处理A,系统就说那你告诉我该处理谁,然后然你用这个方法告诉系统该去处理Bview。就是这么个意思。默认的就是哪个view发生的事件就会处理哪个view。

UIView *hitView = [super hitTest:point withEvent:event];
if ([hitView isKindOfClass:[self class]]) {
return nil;
}
return hitView;

这段代码就是说如果当前滑动点击的视图是scroll的话,那么就不要处理了。只滑动即可,这样就不会触发地图的事件。地图也就不会跟着滑动。

在这个例子里,mapview在视图的最底部,scroll在它上面,然后scroll滑动范围是全屏的,但是展示的范围不能全屏,需要设置contentinset。

这样就实现了这个简单的需求,怎么样,一点也不复杂吧。

 

原文链接:http://zhangqq166.cn/archives/ios/scroll-map/,希望大家多多关注

本文地址:https://blog.csdn.net/qq_27633421/article/details/107207036