经常使用美团或饿了的朋友都会在订单页看到一个效果,上面是个地图,下面是订单的详情。向上滑动的时候地图被覆盖掉,滑下来地图出现,而且滑动地图时只有地图的mapview在动。这种效果怎么实现呢?今天来做一下这个demo。
先放效果图,两种实现方式,两种效果:
1:地图随着scroll的滑动而滑动
“gif有点大,CSDN不让传,请点击查看原图链接”
2,地图不动。scroll自己滑动
“这个gif也有点大,CSDN不让传,请点击查看原图链接”
先说下第一种实现,上代码
@interface MapScrollViewController ()
@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 ()
@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/,希望大家多多关注
本人创建了一个公众号,里面每天发一些教程进阶知识,有的是本人总结所得,有的是转载大神的文章,大家一起分享看。