日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

仿链家地图找房_iOS地图找房(类似链家、安居客等地图找房)

發布時間:2023/12/14 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 仿链家地图找房_iOS地图找房(类似链家、安居客等地图找房) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題外話:在百度搜索鍵入:iOS地圖找房。你會發現搜索到很多關于這方面的帖子,但是幾乎都是詢問如何實現的,找不到一個可以研究借鑒的博客。于是我決定補上這個空缺,寫的可能不全面,大家體諒。

更新PS:原本我是沒打算寫Demo出來的,但博客發出來后很多人要,因為網絡請求不能發出來,請理解。我把Demo中的網絡請求全部干掉了,真正做這個項目的可以加入網絡請求,或者花點功夫模擬請求。最后如果覺得有用給個關注或喜歡,謝謝。

先看下美工出的效果圖。

地圖找房_PxCook.png

下面說說實現的步驟,仍然以代碼加注解的方式說明。我盡量說的詳盡,其實這個模塊難度一般,應該很好理解的,如果有看不懂的給我留言就行了。

分析:第一次進地圖要添加很多圓形的大區標識,這時候比例尺應該是整個市區的大小。當點擊這個圓形,可以進去小區的房源,這個房源是一個消息框形式的標識,當比例尺在大區,地圖移動的時候應該是不允許在更新房源的,當小區的時候,需要更新,而且我們猜測這個更新不能太頻繁,可能我們需要設定一個移動距離。同時,大小區的切換,地圖放大到某個比例尺切換至小區,地圖縮小,切換到大區。

需要做的事情:定義兩種標識。添加大區、小區標識。放大縮小后,大小區的判斷顯示。移動地圖大小區的更新。點擊大小區不同的響應。

文末我會放上效果GIF。

首先,創建地圖,設置比例尺,定位個人位置。比例尺的設定說明下,我這里給了一個自己定義的范圍,因為我不希望用戶無限放大地圖或者無限縮小。最小我希望他看到小區的大小即可,最大差不多展示整個南京市即可。

self.mapView = [[BMKMapView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight)];

[self.view addSubview:self.mapView];

self.locService = [[BMKLocationService alloc] init];

self.mapView.delegate = self;

self.locService.delegate = self;

self.mapView.showsUserLocation = YES;

self.mapView.showMapScaleBar = YES;//顯示比例尺

self.mapView.mapScaleBarPosition = CGPointMake(10, 75);//比例尺位置

self.mapView.minZoomLevel = 11;

self.mapView.maxZoomLevel = 17;

self.mapView.userTrackingMode = BMKUserTrackingModeNone;

[self.locService startUserLocationService];

從效果圖中大家能夠看出,一共兩個大頭針樣式,一個圓形的,一個是對話框形式。你可以理解為這就是一個大頭針,只不過是換了圖片而已,那么如何定義自己想要的樣式呢?

首先定義一個圓形的大頭針,可能需要主標題和副標題

image.png

#import

@interface YLRoundAnnotationView : BMKAnnotationView

@property(nonatomic, strong) NSString *title;

@property(nonatomic, strong) NSString *subTitle;

@end

.m中去實現外觀的定義

@interface YLRoundAnnotationView ()

@property(nonatomic, strong) UILabel *titleLabel;

@property(nonatomic, strong) UILabel *subTitleLabel;

@end

@implementation YLRoundAnnotationView

- (id)initWithAnnotation:(id)annotation reuseIdentifier:(NSString *)reuseIdentifier {

if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]) {

[self setBounds:CGRectMake(0.f, 0.f, 80, 80)];

[self setContentView];

}

return self;

}

- (void)setContentView {

UIColor *color = [UIColor colorWithRed:234/255. green:130/255. blue:80/255. alpha:1];

self.layer.cornerRadius = 40;

self.layer.borderColor = color.CGColor;

self.layer.borderWidth = 1;

self.layer.masksToBounds = YES;

self.backgroundColor = color;

self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 5, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame)/2.5)];

self.titleLabel.textAlignment = NSTextAlignmentCenter;

self.titleLabel.font = font(15);

self.titleLabel.textColor = [UIColor whiteColor];

self.titleLabel.layer.masksToBounds = YES;

[self addSubview:self.titleLabel];

self.subTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.titleLabel.frame), CGRectGetWidth(self.frame), CGRectGetHeight(self.frame)/3)];

self.subTitleLabel.textAlignment = NSTextAlignmentCenter;

self.subTitleLabel.font = font(13);

self.subTitleLabel.textColor = [UIColor whiteColor];

self.subTitleLabel.layer.masksToBounds = YES;

[self addSubview:self.subTitleLabel];

}

- (void)setTitle:(NSString *)title {

_title = title;

self.titleLabel.text = title;

}

- (void)setSubTitle:(NSString *)subTitle {

_subTitle = subTitle;

self.subTitleLabel.text = subTitle;

}

上面我們重寫了大頭針的bound設置了圓角,然后在里面添加了兩個標題。

下面我們定義第二個大頭針,消息框模式的。仍舊仿造上面代碼...

image.png

.h

#import

@interface YLMessageAnnotationView : BMKAnnotationView

@property(nonatomic, strong) NSString *title;

@end

.m

@interface YLMessageAnnotationView ()

@property(nonatomic, strong) UIButton *contentView;

@end

@implementation YLMessageAnnotationView

- (id)initWithAnnotation:(id)annotation reuseIdentifier:(NSString *)reuseIdentifier {

if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]) {

[self setBounds:CGRectMake(0.f, 0.f, 80, 30)];

[self setContentView];

}

return self;

}

- (void)setContentView {

self.contentView = [UIButton buttonWithType:UIButtonTypeCustom];

self.contentView.frame = self.bounds;

self.contentView.userInteractionEnabled = NO;

self.contentView.titleLabel.textAlignment = NSTextAlignmentCenter;

[self.contentView setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];

[self.contentView setBackgroundImage:[UIImage imageNamed:@"community"] forState:UIControlStateNormal];

self.contentView.titleEdgeInsets = UIEdgeInsetsMake(-5, 0, 0, 0);

self.contentView.titleLabel.font = font(10);

[self addSubview:self.contentView];

}

- (void)setTitle:(NSString *)title {

_title = title;

[self.contentView setTitle:title forState:UIControlStateNormal];

}

為什么放一個Button,因為方便標題和背景設置...

ok 定義完成。我們就可以去網絡請求添加大頭針了。

如何添加,兩種情況:當比例尺很大的時候請求一種大頭針,小的時候另一種大頭針

- (void)mapView:(BMKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {

NSLog(@"更改了區域");

NSLog(@"當前比例尺%f,過去比例尺:%f",mapView.zoomLevel,self.zoomValue);

// NSLog(@"中心點經緯度 :%f,%f",mapView.centerCoordinate.latitude,mapView.centerCoordinate.longitude);

if (mapView.zoomLevel > self.zoomValue) {

NSLog(@"地圖放大了");

}else if (mapView.zoomLevel < self.zoomValue){

NSLog(@"地圖縮小了");

}

if (mapView.zoomLevel > 14) {

//請求小區

//當沒有放大縮小 計算平移的距離。當距離小于2千米。不再進行計算 避免過度消耗

float distance = [self distanceBetweenFromCoor:self.oldCoor toCoor:mapView.centerCoordinate];

if (distance <= 1000 && mapView.zoomLevel == self.zoomValue) {

return;

}

[self loadCityAreaHouseWithScale:@"1000" andLatitude:[NSString stringWithFormat:@"%f",mapView.centerCoordinate.latitude] andLongitude:[NSString stringWithFormat:@"%f",mapView.centerCoordinate.longitude] andHouseType:self.houseType andRentType:self.rentType andHouseSize:self.houseSize andMinPrice:self.minPrice andMaxPrice:self.maxPrice];

}else if(mapView.zoomLevel <= 14) {

if (mapView.zoomLevel == self.zoomValue) {//當平移地圖。大區不再重復請求

return;

}

//請求大區

[self loadCityAreaHouseWithScale:@"3000" andLatitude:@"" andLongitude:@"" andHouseType:self.houseType andRentType:self.rentType andHouseSize:self.houseSize andMinPrice:self.minPrice andMaxPrice:self.maxPrice];

}

}

在上面這個代理方法中,當比例尺大于14我請求小區的房源。而且我做了個判斷,當沒有放大縮小 計算平移的距離。當距離小于2千米。不再進行計算 避免過度消耗。當比例尺小于等于14我請求大區的房源。而且當地圖平移的時候,不再請求。如何判斷地圖是否平移和平移后的距離?根據上面if再看下面代碼就明白了

- (void)mapView:(BMKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {

self.zoomValue = mapView.zoomLevel;

self.oldCoor = mapView.centerCoordinate;

NSLog(@"之前的比例尺:%f",mapView.zoomLevel);

}

如上,通過地圖移動前的中心點經緯度和比例尺去與移動后的做比較即可。

下面看下網絡請求的代碼

//請求城市區域內的房源組

- (void)loadCityAreaHouseWithScale:(NSString *)scale andLatitude:(NSString *)latitude andLongitude:(NSString *)longitude andHouseType:(NSString *)houseType andRentType:(NSString *)rentType andHouseSize:(NSString *)houseSize andMinPrice:(NSString *)minPrice andMaxPrice:(NSString *)maxPrice {

WeakSelf

[SVProgressHUD show];

[MapFindHouseViewModel mapFindHouseWithLatitude:latitude andLongitude:longitude andScale:scale andHouseType:houseType andRentType:rentType andHouseSize:houseSize andMinPrice:minPrice andMaxPrice:maxPrice andBlock:^(id result) {

NSArray *data = result;

if (data.count > 0) {

[weakSelf.mapView removeAnnotations:weakSelf.mapView.annotations];

if ([scale isEqualToString:@"3000"]) {//請求大區

for (NSDictionary *dic in data) {

YLAnnotationView *an = [[YLAnnotationView alloc] init];

CLLocationCoordinate2D coor;

coor.latitude = [dic[@"lat"] floatValue];

coor.longitude = [dic[@"lng"] floatValue];

an.type = 1;

an.coordinate = coor;

an.title = dic[@"description"];

an.subtitle = [NSString stringWithFormat:@"%@套",dic[@"houses"]];

an.Id = dic[@"id"];

[weakSelf.mapView addAnnotation:an];

}

}else if([scale isEqualToString:@"1000"]) {//請求小區

for (NSDictionary *dic in data) {

YLAnnotationView *an = [[YLAnnotationView alloc] init];

CLLocationCoordinate2D coor;

coor.latitude = [dic[@"lat"] floatValue];

coor.longitude = [dic[@"lng"] floatValue];

an.type = 2;

an.coordinate = coor;

an.title = [NSString stringWithFormat:@"%@ | %@套",dic[@"description"],dic[@"houses"]];

an.Id = dic[@"id"];

[weakSelf.mapView addAnnotation:an];

}

}

}else {

[SVProgressHUD showInfoWithStatus:@"無房源!請更改條件~"];

}

}];

}

前面我傳進來一個scale來標明到底是大區還是小區。3000代表大區,反之小區。然后解析數據用一個大頭針模型YLAnnotationView 來接收。最終把大頭針模型加入地圖。這時候就會走大頭針的數據源方法了。如下:

- (BMKAnnotationView *)mapView:(BMKMapView *)view viewForAnnotation:(id )annotation {

// 生成重用標示identifier

YLAnnotationView *anno = (YLAnnotationView *)annotation;

if (anno.type == 1) {

NSString *AnnotationViewID = @"round";

// 檢查是否有重用的緩存

YLRoundAnnotationView *annotationView = (YLRoundAnnotationView *)[view dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];

// 緩存沒有命中,自己構造一個,一般首次添加annotation代碼會運行到此處

if (annotationView == nil) {

annotationView = [[YLRoundAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID];

annotationView.paopaoView = nil;

}

// 設置偏移位置

annotationView.centerOffset = CGPointMake(0, -(annotationView.frame.size.height * 0.5));

annotationView.title = anno.title;

annotationView.subTitle = anno.subtitle;

annotationView.annotation = anno;

annotationView.canShowCallout = NO;

return annotationView;

}else {

NSString *AnnotationViewID = @"message";

// 檢查是否有重用的緩存

YLMessageAnnotationView *annotationView = (YLMessageAnnotationView *)[view dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];

// 緩存沒有命中,自己構造一個,一般首次添加annotation代碼會運行到此處

if (annotationView == nil) {

annotationView = [[YLMessageAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID];

annotationView.paopaoView = nil;

}

// 設置偏移位置

annotationView.centerOffset = CGPointMake(0, -(annotationView.frame.size.height * 0.5));

annotationView.title = anno.title;

annotationView.annotation = anno;

annotationView.canShowCallout = NO;

return annotationView;

}

}

在網絡請求哪里我給不同區域請求設置了type。這里正好用來判斷大頭針的顯示。這樣就做好了區別

最后你可能需要為這個大頭針添加點擊事件,那么只需要實現這個代理方法

//點擊了大頭針

- (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view {

if (view.annotation.coordinate.latitude == self.locService.userLocation.location.coordinate.latitude) {//個人位置特殊處理,否則類型不匹配崩潰

NSLog(@"點擊了個人位置");

return;

}

YLAnnotationView *annotationView = (YLAnnotationView *)view.annotation;

if (annotationView.type == 2) {

self.areaTitle = annotationView.title;

//取消大頭針的選中狀態,否則下次再點擊同一個則無法響應事件

[mapView deselectAnnotation:annotationView animated:NO];

//計算距離 --> 請求列表數據 --> 完成 --> 展示表格

self.communityId = annotationView.Id;

//計算小區到個人位置的距離

self.distanceText = [NSString stringWithFormat:@"離我:%.1fkm",[self distanceBetweenFromCoor:annotationView.coordinate toCoor:self.locService.userLocation.location.coordinate] / 1000];

[self loadNewListData];

}else {

//點擊了區域--->進入小區

//拿到大頭針經緯度,放大地圖。然后重新計算小區

[mapView setCenterCoordinate:annotationView.coordinate animated:NO];

[mapView setZoomLevel:16];

}

}

在上面我做了一個特殊判斷,點擊個人位置直接return了。如果不這樣可能會程序crash。點擊小區我彈出一個房源列表,點擊大區,我先移動地圖中心點到點擊的位置,再把地圖放大。注意這個順序,而且必須不能使用動畫。

基本上核心代碼就這些了,當然我還做了很多別的功能,例如搜索和檢索等...附加功能不再說明。

結語:其實這個功能本身應該是使用百度地圖的 高聚合 功能,有興趣的同學可以去了解這個功能,但是就實際而言,這樣重寫大頭針更好一些。

最后上個效果圖吧!

iOS技術交流群:511860085 歡迎加入!

.jpg

Untitled,,d jjj.gif

總結

以上是生活随笔為你收集整理的仿链家地图找房_iOS地图找房(类似链家、安居客等地图找房)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。