38 Commits

Author SHA1 Message Date
384de27f2c Merge branch 'dev' 2026-03-13 17:18:43 +08:00
84b174c4a5 协议通知后注册推送 2026-03-13 17:09:30 +08:00
02e1946319 文字边界 2026-03-05 11:20:14 +08:00
d5083c1939 Merge branch 'dev'
v1.2.4
2026-03-04 14:58:45 +08:00
fe44848529 号码 2026-03-04 14:50:21 +08:00
572c416827 枪号回填,v1.2.4 2026-03-04 13:38:26 +08:00
8df16f0787 pdf查看 2026-03-03 17:51:06 +08:00
ce6bd3edd2 bugfix 2026-03-03 13:09:10 +08:00
6997b4ac9e 调整权限和库 2026-03-02 11:28:44 +08:00
a26d2478f3 样式 2026-02-28 17:31:28 +08:00
0dded3b928 ocr识别,历史新增类型 2026-02-28 17:15:42 +08:00
b7caf58adf 加氢站-查看证件 2026-02-28 15:00:56 +08:00
0df1902df2 无预约 2026-02-28 11:59:07 +08:00
a8314d8a7a 关闭弹窗 2026-02-27 10:55:55 +08:00
39cae906e9 加氢站-预约 2026-02-27 10:54:55 +08:00
14fd6c75d0 fix 2026-02-25 15:35:33 +08:00
1724852a39 司机-可上传证件 2026-02-25 15:35:02 +08:00
a05d4ebb9b 调整 2026-02-12 18:01:56 +08:00
600cea4379 进度条 2026-02-12 17:34:06 +08:00
3dfc1dfc2c 样式调整 2026-02-12 16:54:50 +08:00
909dc95771 增加 提示 2026-02-11 17:41:30 +08:00
cf0896453b 样式 2026-02-11 11:28:49 +08:00
dce9718320 显示周边加氢站 2026-02-11 09:35:42 +08:00
4491aa9b91 ui调整 2026-02-10 16:35:02 +08:00
5364612a6f 更新样式 2026-02-10 13:37:24 +08:00
10867178fa 筛选框样式 2026-02-10 13:35:22 +08:00
a5e2a89e4f 预约列表样式 2026-02-10 11:51:47 +08:00
26c5f9d67a 消息样式修改 2026-02-09 17:57:00 +08:00
9cd87b0535 规则和历史 2026-02-09 17:28:12 +08:00
45e45d8160 积分兑换 2026-02-09 15:10:00 +08:00
87e890f97e 积分兑换首页 2026-02-06 17:37:43 +08:00
dcf925b8c1 商场页 2026-02-06 15:13:33 +08:00
c45863eda6 增加商城页面 2026-02-06 15:11:12 +08:00
756bf53cf5 司机预约时间调整 2026-02-06 14:16:26 +08:00
f68c2d0938 未车辆显示 2026-02-05 14:50:03 +08:00
211d0225e4 车辆图片动态 2026-02-05 13:54:10 +08:00
7d9b4d99e8 应用更新 2026-02-05 10:30:31 +08:00
3dd583a278 401增加节流 2026-02-03 10:59:05 +08:00
141 changed files with 4168 additions and 7713 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -1,8 +0,0 @@
{
"permissions": {
"allow": [
"Bash(flutter build apk --debug 2>&1 | tail -15)",
"Bash(flutter build apk --debug 2>&1 | tail -10)"
]
}
}

View File

@@ -37,8 +37,8 @@ android {
// For more information, see: https://flutter.dev/to/review-gradle-config. // For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion targetSdk = flutter.targetSdkVersion
versionCode = 6 versionCode = 7
versionName = "1.2.3" versionName = "1.2.4"
} }
signingConfigs { signingConfigs {
@@ -68,8 +68,3 @@ android {
flutter { flutter {
source = "../.." source = "../.."
} }
dependencies {
implementation("com.amap.api:navi-3dmap-location-search:10.0.700_3dmap10.0.700_loc6.4.5_sea9.7.2")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
}

View File

@@ -1,65 +1,50 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" <uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" /> android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" <uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32" /> android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" <uses-permission
android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
android:maxSdkVersion="32" /> android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<!--定位权限--> <!--定位权限-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!--用于申请调用A-GPS模块--> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!--如果设置了target >= 28 如果需要启动后台定位则必须声明这个权限-->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!--如果您的应用需要后台定位权限且有可能运行在Android Q设备上,并且设置了target>28必须增加这个权限声明-->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application <application
android:label="小羚羚" android:requestLegacyExternalStorage="true"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/logo"> android:icon="@mipmap/logo"
android:label="小羚羚">
<!-- 高德地图Key -->
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="92495660f7bc990cb475426c47c03b65" />
<!-- 高德地图定位服务 -->
<service android:name="com.amap.api.location.APSService" />
<!--高德导航-->
<activity
android:name="com.amap.api.navi.AmapRouteActivity"
android:theme="@android:style/Theme.NoTitleBar"
android:configChanges="orientation|keyboardHidden|screenSize|navigation" />
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:exported="true" android:exported="true"
android:hardwareAccelerated="true"
android:launchMode="singleTop" android:launchMode="singleTop"
android:taskAffinity="" android:taskAffinity=""
android:theme="@style/LaunchTheme" android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as <!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. --> to determine the Window background behind the Flutter UI. -->
<meta-data <meta-data
android:name="io.flutter.embedding.android.NormalTheme" android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" android:resource="@style/NormalTheme" />
/>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<!-- Don't delete the meta-data below. <!-- Don't delete the meta-data below.
@@ -69,31 +54,54 @@
android:value="2" /> android:value="2" />
<!-- 请填写你自己的- appKey --> <!-- 请填写你自己的- appKey -->
<meta-data android:name="com.alibaba.app.appkey" android:value="335642645"/> <meta-data
android:name="com.alibaba.app.appkey"
android:value="335642645" />
<!-- 请填写你自己的appSecret --> <!-- 请填写你自己的appSecret -->
<meta-data android:name="com.alibaba.app.appsecret" android:value="39628204345a4240b5b645b68a5896c7"/> <meta-data
android:name="com.alibaba.app.appsecret"
android:value="39628204345a4240b5b645b68a5896c7" />
<!-- 华为通道的参数appid --> <!-- 华为通道的参数appid -->
<meta-data android:name="com.huawei.hms.client.appid" android:value="" /> <meta-data
android:name="com.huawei.hms.client.appid"
android:value="" />
<!-- vivo通道的参数api_key为appkey --> <!-- vivo通道的参数api_key为appkey -->
<meta-data android:name="com.vivo.push.api_key" android:value="" /> <meta-data
<meta-data android:name="com.vivo.push.app_id" android:value="" /> android:name="com.vivo.push.api_key"
android:value="" />
<meta-data
android:name="com.vivo.push.app_id"
android:value="" />
<!-- honor通道的参数--> <!-- honor通道的参数-->
<meta-data android:name="com.hihonor.push.app_id" android:value="" /> <meta-data
android:name="com.hihonor.push.app_id"
android:value="" />
<!-- oppo --> <!-- oppo -->
<meta-data android:name="com.oppo.push.key" android:value="" /> <meta-data
<meta-data android:name="com.oppo.push.secret" android:value="" /> android:name="com.oppo.push.key"
android:value="" />
<meta-data
android:name="com.oppo.push.secret"
android:value="" />
<!-- 小米--> <!-- 小米-->
<meta-data android:name="com.xiaomi.push.id" android:value="id=2222222222222222222" /> <meta-data
<meta-data android:name="com.xiaomi.push.key" android:value="id=5555555555555" /> android:name="com.xiaomi.push.id"
android:value="id=2222222222222222222" />
<meta-data
android:name="com.xiaomi.push.key"
android:value="id=5555555555555" />
<!-- 魅族--> <!-- 魅族-->
<meta-data android:name="com.meizu.push.id" android:value="" /> <meta-data
<meta-data android:name="com.meizu.push.key" android:value="" /> android:name="com.meizu.push.id"
android:value="" />
<meta-data
android:name="com.meizu.push.key"
android:value="" />
<!-- 接收推送消息 --> <!-- 接收推送消息 -->
@@ -117,6 +125,7 @@
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.BROWSABLE" />
@@ -135,8 +144,8 @@
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. --> In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries> <queries>
<intent> <intent>
<action android:name="android.intent.action.PROCESS_TEXT"/> <action android:name="android.intent.action.PROCESS_TEXT" />
<data android:mimeType="text/plain"/> <data android:mimeType="text/plain" />
</intent> </intent>
</queries> </queries>
</manifest> </manifest>

View File

@@ -1,195 +1,6 @@
package com.lnkj.ln_jq_app; package com.lnkj.ln_jq_app;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.MethodChannel;
public class MainActivity extends FlutterActivity { public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "com.lnkj.ln_jq_app/map";
private static final String TAG = "MainActivity";
// 权限请求码
private static final int PERMISSION_REQUEST_CODE = 1001;
private NativeMapView mapView;
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
// 注册高德地图导航Platform View
flutterEngine
.getPlatformViewsController()
.getRegistry()
.registerViewFactory(
"NativeFirstPage",
new NativeMapFactory(this)
);
// 注册方法通道用于地图控制
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler((call, result) -> {
switch (call.method) {
case "requestPermissions":
requestPermissions();
result.success(null);
break;
case "onResume":
if (mapView != null) {
mapView.onResume();
}
result.success(null);
break;
case "onPause":
if (mapView != null) {
mapView.onPause();
}
result.success(null);
break;
case "onDestroy":
if (mapView != null) {
mapView.dispose();
mapView = null;
}
result.success(null);
break;
default:
result.notImplemented();
break;
}
});
}
/**
* 获取当前系统版本需要申请的权限列表
*/
private String[] getRequiredPermissions() {
List<String> permissions = new ArrayList<>();
// 定位权限是必须的
permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
// 存储权限处理Android 13 (API 33) 以下才需要申请 legacy 存储权限
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
return permissions.toArray(new String[0]);
}
/**
* 检查并申请权限
*/
private void checkAndRequestPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String[] requiredPermissions = getRequiredPermissions();
List<String> deniedPermissions = new ArrayList<>();
for (String permission : requiredPermissions) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
deniedPermissions.add(permission);
}
}
if (!deniedPermissions.isEmpty()) {
ActivityCompat.requestPermissions(
this,
deniedPermissions.toArray(new String[0]),
PERMISSION_REQUEST_CODE
);
} else {
Log.d(TAG, "所有必要权限已授予");
if (mapView != null) {
mapView.startLocation();
}
}
} else {
if (mapView != null) {
mapView.startLocation();
}
}
}
private void requestPermissions() {
checkAndRequestPermissions();
}
public void setMapView(NativeMapView mapView) {
this.mapView = mapView;
}
@Override
protected void onResume() {
super.onResume();
// 注意高德SDK合规检查通过后再进行定位相关操作
// 这里仅保留地图生命周期调用权限建议在Flutter端或按需触发
if (mapView != null) {
mapView.onResume();
}
}
@Override
protected void onPause() {
super.onPause();
if (mapView != null) {
mapView.onPause();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mapView != null) {
mapView.dispose();
mapView = null;
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
if (mapView != null) {
mapView.onSaveInstanceState(outState);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_REQUEST_CODE) {
boolean locationGranted = false;
for (int i = 0; i < permissions.length; i++) {
if (Manifest.permission.ACCESS_FINE_LOCATION.equals(permissions[i])
&& grantResults[i] == PackageManager.PERMISSION_GRANTED) {
locationGranted = true;
break;
}
}
if (locationGranted) {
if (mapView != null) {
mapView.startLocation();
}
} else {
// 只有在定位权限确实被拒绝时才弹出提示
Toast.makeText(this, "请授予应用定位权限以正常使用地图功能", Toast.LENGTH_LONG).show();
}
}
}
} }

View File

@@ -1,37 +0,0 @@
package com.lnkj.ln_jq_app;
import android.content.Context;
import io.flutter.plugin.common.MessageCodec;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;
/**
* 高德地图导航 Platform View Factory
* 对应iOS的NativeViewFactory
*/
public class NativeMapFactory extends PlatformViewFactory {
private static final String VIEW_TYPE_ID = "NativeFirstPage";
private static NativeMapView mapViewInstance = null;
private final Context context;
public NativeMapFactory(Context context) {
super(StandardMessageCodec.INSTANCE);
this.context = context;
}
@Override
public PlatformView create(Context context, int viewId, Object args) {
mapViewInstance = new NativeMapView(context, viewId, args);
return mapViewInstance;
}
/**
* 获取地图实例供MainActivity使用
*/
public static NativeMapView getMapView() {
return mapViewInstance;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 880 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 924 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -25,7 +25,7 @@
display: none !important; display: none !important;
} }
/* 去除高德默认的 label 边框背景 */ /* 去除高德默认的 label 边框 and 背景 */
.amap-marker-label { .amap-marker-label {
border: none !important; border: none !important;
background-color: transparent !important; background-color: transparent !important;
@@ -109,7 +109,7 @@
/* --- 导航结果面板 (底部弹出) --- */ /* --- 导航结果面板 (底部弹出) --- */
#panel { #panel {
position: fixed; position: fixed;
bottom: 75px; bottom: 95px;
left: 0; left: 0;
width: 100%; width: 100%;
height: 35%; height: 35%;
@@ -129,7 +129,7 @@
#location-btn { #location-btn {
position: fixed; position: fixed;
right: 10px; right: 10px;
bottom: 75px; bottom: 105px;
/* 默认位置 */ /* 默认位置 */
width: 44px; width: 44px;
height: 44px; height: 44px;
@@ -159,7 +159,7 @@
/* --- 调整比例尺位置 --- */ /* --- 调整比例尺位置 --- */
.amap-scalecontrol { .amap-scalecontrol {
/* 初始状态:避开底部的定位按钮或留出安全间距 */ /* 初始状态:避开底部的定位按钮或留出安全间距 */
bottom: 80px !important; bottom: 110px !important;
left: 10px !important; left: 10px !important;
transition: bottom 0.3s ease; transition: bottom 0.3s ease;
/* 增加平滑动画 */ /* 增加平滑动画 */
@@ -195,10 +195,10 @@
<div id="search-box"> <div id="search-box">
<div class="input-row"> <div class="input-row">
<input id="startInput" placeholder="起点: 请输入当前地点" /> <input id="startInput" placeholder="起点: 请输入当前地点" onfocus="this.select()" />
</div> </div>
<div class="input-row"> <div class="input-row">
<input id="endInput" placeholder="终点: 请输入目的地" /> <input id="endInput" placeholder="终点: 请输入目的地" onfocus="this.select()" />
<button onclick="startRouteSearch()">路径规划</button> <button onclick="startRouteSearch()">路径规划</button>
</div> </div>
</div> </div>
@@ -221,6 +221,7 @@
var currentLat, currentLng; var currentLat, currentLng;
var isTruckMode = false; var isTruckMode = false;
var isInitialLocationSet = false; var isInitialLocationSet = false;
var stationMarkers = []; // 存储所有站点的标记
function initMap() { function initMap() {
@@ -243,6 +244,11 @@
} }
}); });
// 点击地图空白处重置状态
map.on('click', function() {
resetSearchState();
});
// 添加基础控件 // 添加基础控件
map.addControl(new AMap.Scale()); map.addControl(new AMap.Scale());
map.addControl(new AMap.ToolBar({ map.addControl(new AMap.ToolBar({
@@ -284,6 +290,19 @@
}); });
} }
/**
* 重置搜索状态,隐藏面板和路线
*/
function resetSearchState() {
if (document.body.classList.contains('panel-active')) {
console.log("JS->: 重置地图状态");
document.body.classList.remove('panel-active');
var panel = document.getElementById('panel');
panel.style.display = 'none';
if (driving) driving.clear();
}
}
/** /**
* 核心功能 1: 接收 Flutter 传来的定位数据 * 核心功能 1: 接收 Flutter 传来的定位数据
* Flutter 端调用: webViewController.evaluateJavascript("updateMyLocation(...)") * Flutter 端调用: webViewController.evaluateJavascript("updateMyLocation(...)")
@@ -336,6 +355,8 @@
fetchStationInfo(addressComponent.province, addressComponent.city, fetchStationInfo(addressComponent.province, addressComponent.city,
addressComponent.district, lat, lng); addressComponent.district, lat, lng);
fetchStationInfoList(lat, lng);
// 策略1: 优先使用最近的、类型合适的POI的名称 // 策略1: 优先使用最近的、类型合适的POI的名称
if (pois && pois.length > 0) { if (pois && pois.length > 0) {
// 查找第一个类型不是“商务住宅”或“地名地址信息”的POI这类POI通常是具体的建筑或地点名 // 查找第一个类型不是“商务住宅”或“地名地址信息”的POI这类POI通常是具体的建筑或地点名
@@ -397,7 +418,6 @@
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
// "asoco-token": "e28eada8-4611-4dc2-a942-0122e52f52da"
}, },
body: JSON.stringify({ body: JSON.stringify({
province: province, province: province,
@@ -437,6 +457,79 @@
.catch(err => console.error('JS->:获取站点信息失败:', err)); .catch(err => console.error('JS->:获取站点信息失败:', err));
} }
/**
* 获取站点列表
*/
function fetchStationInfoList(lat, lng) {
fetch('https://beta-esg.api.lnh2e.com/appointment/station/getNearbyHydrogenStationsByLocation', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
longitude: lng,
latitude: lat,
})
})
.then(response => {
if (!response.ok) {
throw new Error('网络响应错误: ' + response.status);
}
return response.json(); // 解析 JSON
})
.then(res => {
console.log("JS->:2 接口完整返回:", JSON.stringify(res));
if (res.code === 0 && res.data && Array.isArray(res.data)) {
// 1. 清除旧的站点标记
stationMarkers.forEach(m => m.setMap(null));
stationMarkers = [];
// 2. 循环标记所有加氢站
res.data.forEach(station => {
var stationIcon = new AMap.Icon({
size: new AMap.Size(32, 32),
image: 'ic_tag.png',
imageSize: new AMap.Size(32, 32)
});
var sMarker = new AMap.Marker({
map: map,
position: [station.longitude, station.latitude],
icon: stationIcon,
offset: new AMap.Pixel(-16, -32),
title: station.name,
label: {
content: '<div class="custom-bubble">' + station.name +
'</div>',
direction: 'top'
}
});
// 3. 绑定点击事件:选中即为目的地,并开始规划
sMarker.on('click', function () {
var stationName = station.name || "目的地";
document.getElementById('endInput').value = station.address ||
stationName;
// 更新当前的 destMarker
if (destMarker && destMarker !== sMarker) destMarker.setMap(null);
destMarker = sMarker;
// 直接传入坐标对象,避免关键字搜索失败
var loc = new AMap.LngLat(station.longitude, station.latitude);
startRouteSearch(loc);
});
stationMarkers.push(sMarker);
});
} else {
console.log("JS->: 业务报错或无数据:", res.message);
}
})
.catch(err => console.error('JS->:获取站点信息失败:', err));
}
/** /**
* 地理编码并在地图标记终点 * 地理编码并在地图标记终点
*/ */
@@ -447,7 +540,6 @@
if (destMarker) destMarker.setMap(null); if (destMarker) destMarker.setMap(null);
// 2. 创建自定义图标 // 2. 创建自定义图标
// 假设图标大小为 32x32你可以根据实际图片尺寸调整 Size
var destIcon = new AMap.Icon({ var destIcon = new AMap.Icon({
size: new AMap.Size(32, 32), // 图标尺寸 size: new AMap.Size(32, 32), // 图标尺寸
image: 'ic_tag.png', // 本地图片路径 image: 'ic_tag.png', // 本地图片路径
@@ -459,8 +551,6 @@
map: map, map: map,
position: [longitude, latitude], position: [longitude, latitude],
icon: destIcon, // 使用自定义图标 icon: destIcon, // 使用自定义图标
// 偏移量如果图标底部中心是尖角offset 设为宽的一半的负数,高度的负数
// 这样能确保图片的底部尖端指向地图上的精确位置
offset: new AMap.Pixel(-16, -32), offset: new AMap.Pixel(-16, -32),
title: name, title: name,
label: { label: {
@@ -469,17 +559,7 @@
} }
}); });
// 4. 打印调试信息 console.log("JS->: 终点标记已添加", address);
console.log("JS->: 终点标记已添加", address, loc.toString());
// 5. 自动调整视野包含起点和终点
// if (marker) {
// // 如果起点标志已存在,缩放地图以展示两者
// map.setFitView([marker, destMarker], false, [60, 60, 60, 60]);
// } else {
// // 如果没有起点,直接跳到终点
// map.setCenter(loc);
// }
} }
/** /**
@@ -498,11 +578,12 @@
} }
} }
/** /**
* 路径规划 * 路径规划
* @param {AMap.LngLat} [destLoc] 可选的终点坐标
*/ */
function startRouteSearch() { function startRouteSearch(destLoc) {
// 获取输入框的文字
var startKw = document.getElementById('startInput').value; var startKw = document.getElementById('startInput').value;
var endKw = document.getElementById('endInput').value; var endKw = document.getElementById('endInput').value;
@@ -510,63 +591,59 @@
alert("请输入起点"); alert("请输入起点");
return; return;
} }
if (!endKw) { if (!endKw) {
alert("请输入终点"); alert("请输入终点");
return; return;
} }
// 清除旧路线
if (driving) driving.clear(); if (driving) driving.clear();
// 收起键盘
document.getElementById('startInput').blur(); document.getElementById('startInput').blur();
document.getElementById('endInput').blur(); document.getElementById('endInput').blur();
// --- 构造路径规划的点 (使用数组方式,更灵活) ---
var points = []; var points = [];
// 1. 处理起点逻辑 // 1. 起点逻辑
// 如果输入框是空的,或者写着 "我的位置",则使用 GPS 坐标 if (!startKw || startKw === '我的位置' || startKw.includes('当前位置')) {
if (!startKw || startKw === '我的位置') {
if (!currentLng || !currentLat) { if (!currentLng || !currentLat) {
// 如果还没获取到定位 if (window.flutter_inappwebview) window.flutter_inappwebview.callHandler('requestLocation');
if (window.flutter_inappwebview) {
window.flutter_inappwebview.callHandler('requestLocation');
}
alert("正在获取定位,请稍后..."); alert("正在获取定位,请稍后...");
return; return;
} }
// 使用精准坐标对象 (避免高德去猜 '我的位置' 关键词)
points.push({ points.push({
keyword: '我的位置', // 用于显示的名字 keyword: '我的位置',
location: new AMap.LngLat(currentLng, currentLat) // 实际导航用的坐标 location: new AMap.LngLat(currentLng, currentLat)
}); });
} else { } else {
// 如果用户手动输入了地点 (例如 "北京南站")
// 直接存入关键词,让高德自己去搜
points.push({ points.push({
keyword: startKw keyword: startKw
}); });
} }
// 2. 处理终点逻辑 (通常是关键词) // 2. 终点逻辑:如果有传入坐标,则直接使用坐标导航,成功率最高
points.push({ if (destLoc) {
keyword: endKw points.push({
}); keyword: endKw,
location: destLoc // 关键:使用精确坐标
});
} else {
points.push({
keyword: endKw
});
}
// 3. 发起搜索 // 3. 发起搜索
// points 数组里现在是一个起点对象和一个终点对象
driving.search(points, function (status, result) { driving.search(points, function (status, result) {
if (status === 'complete') { if (status === 'complete') {
console.log('JS: 规划成功'); console.log('JS: 规划成功');
var panel = document.getElementById('panel'); var panel = document.getElementById('panel');
panel.style.display = 'block'; panel.style.display = 'block';
document.body.classList.add('panel-active'); document.body.classList.add('panel-active');
} else {
console.log('JS: 规划失败', result);
alert("规划失败,请检查起终点名称");
} }
// else {
// console.error('JS: 规划失败', result);
// // 如果坐标规划都失败了,通常是由于起终点距离过近或政策限制(如货车禁行)
// alert("路径规划未成功,请尝试微调起终点");
// }
}); });
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 892 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 573 B

After

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 508 B

After

Width:  |  Height:  |  Size: 594 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 896 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 545 KiB

View File

@@ -1,51 +0,0 @@
#
# Be sure to run `pod lib lint AMapNavIOSSDK.podspec' to ensure this is a
# valid spec before submitting.
#
# Any lines starting with a # are optional, but their use is encouraged
# To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html
#
Pod::Spec.new do |s|
s.name = 'AMapNavIOSSDK'
s.version = '0.1.0'
s.summary = 'A short description of AMapNavIOSSDK.'
# This description is used to generate tags and improve search results.
# * Think: What does it do? Why did you write it? What is the focus?
# * Try to keep it short, snappy and to the point.
# * Write the description between the DESC delimiters below.
# * Finally, don't worry about the indent, CocoaPods strips it!
s.description = <<-DESC
TODO: Add long description of the pod here.
DESC
s.homepage = 'https://github.com/xiaoshuai/AMapNavIOSSDK'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'xiaoshuai' => 'xiaoshuai@net.cn' }
s.source = { :git => 'https://github.com/xiaoshuai/AMapNavIOSSDK.git', :tag => s.version.to_s }
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
s.ios.deployment_target = '12.0'
s.source_files = 'AMapNavIOSSDK/Classes/**/*'
s.resource = 'AMapNavIOSSDK/**/*.bundle'
s.resource_bundles = {
'AMapNavIOSSDKPrivacyInfo' => ['AMapNavIOSSDK/**/PrivacyInfo.xcprivacy']
}
# s.public_header_files = 'Pod/Classes/**/*.h'
# s.frameworks = 'UIKit', 'MapKit'
# s.dependency 'AFNetworking', '~> 2.3'
s.dependency 'Masonry'
s.dependency 'MJExtension'
s.dependency 'AMapNavi-NO-IDFA'
s.dependency 'AMapLocation-NO-IDFA'
s.dependency 'AMapSearch-NO-IDFA'
s.dependency 'MBProgressHUD'
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 966 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 840 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyTrackingDomains</key>
<array/>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>0A2A.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>85F4.1</string>
</array>
</dict>
</array>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
</dict>
</plist>

View File

@@ -1,24 +0,0 @@
//
// ABaseViewController.h
// ANavDemo
//
// Created by admin on 2026/2/5.
//
#import <UIKit/UIKit.h>
#import <Masonry/Masonry.h>
#import "AMapNavCommonUtil.h"
#define kRoutePlanBarHeight (self.navigationController.navigationBar.frame.size.height + UIApplication.sharedApplication.statusBarFrame.size.height + 0)
#define kRoutePlanStatusBarHeight (UIApplication.sharedApplication.statusBarFrame.size.height + 0)
NS_ASSUME_NONNULL_BEGIN
@interface ABaseViewController : UIViewController
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,33 +0,0 @@
//
// ABaseViewController.m
// ANavDemo
//
// Created by admin on 2026/2/5.
//
#import "ABaseViewController.h"
@interface ABaseViewController ()
@end
@implementation ABaseViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor whiteColor];
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end

View File

@@ -1,17 +0,0 @@
//
// ACustomAnnotationView.h
// AMapNavIOSSDK
//
// Created by admin on 2026/3/17.
//
#import <AMapNaviKit/AMapNaviKit.h>
#import "AMapNavCommonUtil.h"
NS_ASSUME_NONNULL_BEGIN
@interface ACustomAnnotationView : MAAnnotationView
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,177 +0,0 @@
//
// ACustomAnnotationView.m
// AMapNavIOSSDK
//
// Created by admin on 2026/3/17.
//
#import "ACustomAnnotationView.h"
//
static const CGFloat kIconSize = 30; //
static const CGFloat kIconTextGap = 6.0; //
static const CGFloat kMaxTextWidth = 100.0; //
static const CGFloat kMaxTextLines = 2; //
static const CGFloat kVPad = 4.0; // centerOffset
@interface ACustomAnnotationView ()
@property (nonatomic, strong) UIImageView *iconView;
@property (nonatomic, strong) UILabel *titleLabel;
/// &
@property (nonatomic, assign) BOOL isAnnotationSelected;
@end
@implementation ACustomAnnotationView
#pragma mark - Init / Reuse
- (instancetype)initWithAnnotation:(id<MAAnnotation>)annotation
reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
if (self) {
self.backgroundColor = [UIColor clearColor];
// MAAnnotationView image
self.image = nil;
[self _buildSubviews];
[self _updateFromAnnotation];
[self setNeedsLayout];
}
return self;
}
- (void)setAnnotation:(id<MAAnnotation>)annotation {
[super setAnnotation:annotation];
[self _updateFromAnnotation];
[self setNeedsLayout];
}
#pragma mark - Build
- (void)_buildSubviews {
//
if (!self.iconView) {
UIImageView *iv = [[UIImageView alloc] init];
iv.contentMode = UIViewContentModeScaleAspectFit;
[self addSubview:iv];
self.iconView = iv;
}
//
if (!self.titleLabel) {
UILabel *lbl = [[UILabel alloc] init];
lbl.numberOfLines = kMaxTextLines;
lbl.lineBreakMode = NSLineBreakByTruncatingTail;
lbl.textAlignment = NSTextAlignmentLeft;
[self addSubview:lbl];
self.titleLabel = lbl;
}
//
[self _applyStyle:NO];
}
/// &
- (void)_applyStyle:(BOOL)selected {
if (selected) {
self.iconView.image = [AMapNavCommonUtil imageWithName3x:@"station_select_icon"];
self.titleLabel.font = [UIFont boldSystemFontOfSize:14];
self.titleLabel.textColor = [UIColor colorWithWhite:0.12 alpha:1.0];
} else {
self.iconView.image = [AMapNavCommonUtil imageWithName3x:@"station_normal_icon"];
self.titleLabel.font = [UIFont systemFontOfSize:13];
self.titleLabel.textColor = [UIColor colorWithWhite:0.25 alpha:1.0];
}
}
#pragma mark - Data
- (void)_updateFromAnnotation {
NSString *text = nil;
id<MAAnnotation> ann = self.annotation;
if ([ann respondsToSelector:@selector(title)]) {
text = ann.title;
}
if (text.length == 0) {
text = @"加氢站";
}
self.titleLabel.text = text;
}
#pragma mark - SelectionMAAnnotationView
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
self.isAnnotationSelected = selected;
[self _applyStyle:selected];
[self setNeedsLayout];
}
#pragma mark - Layout
- (void)layoutSubviews {
[super layoutSubviews];
// 100pt 2
CGSize textConstraint = CGSizeMake(kMaxTextWidth,
CGFLOAT_MAX);
CGSize textFit = [self.titleLabel sizeThatFits:textConstraint];
// 2
CGFloat lineH = self.titleLabel.font.lineHeight;
CGFloat maxTextH = lineH * kMaxTextLines
+ self.titleLabel.font.leading * (kMaxTextLines - 1);
CGFloat textW = MIN(textFit.width, kMaxTextWidth);
CGFloat textH = MIN(textFit.height, maxTextH);
CGFloat totalW = kIconSize + kIconTextGap + textW;
CGFloat totalH = MAX(kIconSize, textH) + kVPad * 2;
// bounds
self.bounds = CGRectMake(0, 0, totalW, totalH);
//
CGFloat iconY = (totalH - kIconSize) * 0.5;
self.iconView.frame = CGRectMake(0, iconY, kIconSize, kIconSize);
//
CGFloat textY = (totalH - textH) * 0.5;
self.titleLabel.frame = CGRectMake(kIconSize + 1, textY, textW, textH);
//
// MAAnnotationView centerOffset (0,0)=
// totalH/2
self.centerOffset = CGPointMake(totalW / 2.0 - kIconSize / 2.0,
-(totalH / 2.0));
}
#pragma mark - Hit Test
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *hit = [super hitTest:point withEvent:event];
if (hit == self || [hit isDescendantOfView:self]) {
return self;
}
return hit;
}
#pragma mark - Touch
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
id<MAAnnotation> annotation = self.annotation;
if (!annotation) return;
UIView *sv = self.superview;
while (sv && ![sv isKindOfClass:[MAMapView class]]) {
sv = sv.superview;
}
MAMapView *mapView = (MAMapView *)sv;
if (!mapView) return;
// [mapView deselectAnnotation:annotation animated:NO];
}
@end

View File

@@ -1,51 +0,0 @@
//
// AMapNavSDKHeader.h
// Pods
//
// Created by admin on 2026/2/10.
//
#ifndef AMapNavSDKHeader_h
#define AMapNavSDKHeader_h
//#define kAMapSDKDebugFlag
// iPhone X
#define AMP_iPhoneX (UIApplication.sharedApplication.keyWindow.safeAreaInsets.bottom > 0 ? YES : NO)
// Status bar height.
#define AMP_StatusBarHeight (AMP_iPhoneX ? 44.f : 20.f)
// Navigation bar height.
#define AMP_NavigationBarHeight 44.f
// Tabbar height.
#define AMP_TabbarHeight (AMP_iPhoneX ? (49.f+34.f + 5) : 49.f)
// Tabbar safe bottom margin.
#define AMP_TabbarSafeBottomMargin (AMP_iPhoneX ? 34.f : 0.f)
#pragma mark - url
///获取站点列表
#define kGetStationListUrl @"https://beta-esg.api.lnh2e.com/appointment/station/getNearbyHydrogenStationsByLocation"
///单个站点详情
#define kGetStationDetailtUrl @"https://beta-esg.api.lnh2e.com/appointment/station/getStationInfoByArea"
///获取途经点
/**
请求方式post 暂时调不通
{
   "longitude":"121.254139",
    "latitude":"31.214628",
    "plateNumber":"浙F32111F",
"hydrogenSiteId":""//加氢站DI }
*/
#define kGetRoutePointtUrl @"https://beta-esg.api.lnh2e.com/appointment/truck/truckRouteAlgorithm"
#import "ANavPointModel.h"
#endif /* AMapNavSDKHeader_h */

View File

@@ -1,29 +0,0 @@
//
// AMapNavSDKManager.h
// Pods
//
// Created by admin on 2026/2/10.
//
#import <Foundation/Foundation.h>
#import "ARoutePlaneController.h"
NS_ASSUME_NONNULL_BEGIN
@interface AMapNavSDKManager : NSObject
@property (strong, nonatomic) UIWindow *window;
@property (nonatomic , strong) NSString * localCity;
@property (nonatomic, copy) NSString * locationAddressDetail;
@property (nonatomic , strong , readonly) UIViewController * targetVC;
+ (instancetype)sharedManager;
- (void)configWithKey:(NSString*)key;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,72 +0,0 @@
//
// AMapNavSDKManager.m
// Pods
//
// Created by admin on 2026/2/10.
//
#import "AMapNavSDKManager.h"
#import "AMapPrivacyUtility.h"
#import <AMapFoundationKit/AMapFoundationKit.h>
@interface AMapNavSDKManager ()
@property (nonatomic , strong , readwrite) UIViewController * targetVC;
@end
@implementation AMapNavSDKManager
+ (instancetype)sharedManager {
static AMapNavSDKManager *manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[AMapNavSDKManager alloc] init];
});
return manager;
}
- (instancetype)init {
self = [super init];
if (self) {
_targetVC = [ARoutePlaneController new];
}
return self;
}
- (void)configWithKey:(NSString*)key {
if (1) {
/*
*
*/
// [AMapPrivacyUtility handlePrivacyAgreeStatusIn:_targetVC];
//
// SDK
[self configureAPIKey:key];
}
}
- (UIViewController *)targetVC {
return _targetVC;
}
#pragma mark - private
- (void)configureAPIKey:(NSString*)key {
if ([key length] == 0)
{
NSString *reason = [NSString stringWithFormat:@"apiKey为空请检查key是否正确设置。"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:reason delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
}
[AMapServices sharedServices].enableHTTPS = YES;
[AMapServices sharedServices].apiKey = (NSString *)key;
}
@end

View File

@@ -1,28 +0,0 @@
//
// ARoutePlaneController.h
// ANavDemo
//
// Created by admin on 2026/2/5.
//
#import <UIKit/UIKit.h>
#import "ABaseViewController.h"
#import "SelectableOverlay.h"
#import "NaviPointAnnotation.h"
#import <AMapNaviKit/AMapNaviKit.h>
#import "ACustomAnnotationView.h"
#import "AMapNavSDKHeader.h"
#import "ACustomPointAnnotation.h"
#import "ATripCalcResponse.h"
#import "AMapNavCommonUtil.h"
NS_ASSUME_NONNULL_BEGIN
@interface ARoutePlaneController : ABaseViewController
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,22 +0,0 @@
//
// ASearchAddressController.h
// ANavDemo
//
// Created by admin on 2026/2/6.
//
#import "ABaseViewController.h"
#import <AMapSearchKit/AMapSearchKit.h>
#import <AMapLocationKit/AMapLocationKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface ASearchAddressController : ABaseViewController
@property (nonatomic , copy) void(^selectAddressBlk)(AMapPOI * poi);
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,235 +0,0 @@
//
// ASearchAddressController.m
// ANavDemo
//
// Created by admin on 2026/2/6.
//
#import "ASearchAddressController.h"
#import "AMapNavSDKManager.h"
#import <AMapFoundationKit/AMapFoundationKit.h>
#import "AMapNavCommonUtil.h"
@interface ASearchAddressController ()<UITextFieldDelegate , AMapSearchDelegate,UITableViewDelegate , UITableViewDataSource>
@property (nonatomic , strong) UITableView *tableView;
@property (nonatomic , strong) UIBarButtonItem *rightItem;
@property (nonatomic ,strong)UIButton * backBtn;
@property (nonatomic , strong) NSArray *dataArr;
@property (nonatomic, strong) UITextField *inputAddressTf;
@property (nonatomic, strong) AMapSearchAPI *search;
@end
@implementation ASearchAddressController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.title = @"选择地点";
[self initSubview];
self.search = [[AMapSearchAPI alloc] init];
self.search.delegate = self;
#ifdef kAMapSDKDebugFlag
self.inputAddressTf.text = @"人民广场";
#endif
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
dispatch_async(dispatch_get_main_queue(), ^{
[self.inputAddressTf becomeFirstResponder];
});
}
-(void)initSubview {
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:self.backBtn];
UITextField * inputAddressTf = [[UITextField alloc] init];
inputAddressTf.borderStyle = UITextBorderStyleRoundedRect;
inputAddressTf.placeholder = @"输入地址";
inputAddressTf.returnKeyType = UIReturnKeySearch;
inputAddressTf.tag = 100;
inputAddressTf.delegate = self;
[self.view addSubview:inputAddressTf];
[inputAddressTf mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self.view).offset(10);
make.top.mas_equalTo(self.view).offset(kRoutePlanBarHeight + 10);
make.height.mas_equalTo(@30);
}];
self.inputAddressTf = inputAddressTf;
UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:@"当前位置" forState:UIControlStateNormal];
btn.backgroundColor = [UIColor whiteColor];
btn.layer.borderColor = [UIColor blueColor].CGColor;
btn.layer.borderWidth = 1;
btn.layer.cornerRadius = 5;
btn.titleLabel.font = [UIFont systemFontOfSize:12];
[btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(searchBtnAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
[btn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(inputAddressTf.mas_right).offset(12);
make.top.mas_equalTo(inputAddressTf);
make.right.mas_equalTo(self.view).offset(-10);
make.height.mas_equalTo(@30);
make.width.mas_equalTo(70);
}];
[self.view addSubview:self.tableView];
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(inputAddressTf.mas_bottom).offset(5);
make.left.equalTo(self.view);
make.bottom.equalTo(self.view);
make.centerX.equalTo(self.view);
}];
[self.tableView reloadData];
}
#pragma mark -
- (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
AMapPOI * m = self.dataArr[indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:@"%@" , m.name ];
return cell;
}
- (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.dataArr.count;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
AMapPOI * m = self.dataArr[indexPath.row];
if (self.selectAddressBlk) {
self.selectAddressBlk(m);
}
[self backBtnAction];
// [self.navigationController popViewControllerAnimated:YES];
}
#pragma mark -
- (UITableView *)tableView {
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
_tableView.delegate = self;
_tableView.dataSource = self;
}
return _tableView;
}
-(UIButton *)backBtn{
if (!_backBtn) {
_backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_backBtn.frame = CGRectMake(0, 0, 40, 30);
_backBtn.imageEdgeInsets = UIEdgeInsetsMake(2, -5, 2, 5);
// _backBtn.backgroundColor = UIColor.redColor;
[_backBtn setImage:[AMapNavCommonUtil imageWithName:@"icon_fanhui"] forState:UIControlStateNormal];
[_backBtn addTarget:self action:@selector(backBtnAction) forControlEvents:UIControlEventTouchUpInside];
}
return _backBtn;
}
-(void)backBtnAction {
[self dismissViewControllerAnimated:YES completion:^{
}];
}
#pragma mark - Action
-(void)searchBtnAction {
AMapNavSDKManager * sdk = [AMapNavSDKManager sharedManager];
self.inputAddressTf.text = sdk.locationAddressDetail;
[self startSearchWithAddress:self.inputAddressTf.text];
}
-(void)startSearchWithAddress:(NSString *)addr {
if (!addr) {
return;
}
AMapPOIKeywordsSearchRequest *request = [[AMapPOIKeywordsSearchRequest alloc] init];
request.keywords = addr;
AMapNavSDKManager * sdk = [AMapNavSDKManager sharedManager];
request.city = sdk.localCity;
// request.types = @"高等院校";
// request.requireExtension = YES;
request.offset =20;
/* SDK 3.2.0 POI*/
request.cityLimit = YES;
// request.requireSubPOIs = YES;
[self.search AMapPOIKeywordsSearch:request];
}
#pragma mark -
/* POI . */
- (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response
{
NSArray * pois = response.pois;
if (pois.count == 0)
{
return;
}
//responsePOI Demo
self.dataArr = [NSArray arrayWithArray:pois];
[self.tableView reloadData];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
[self startSearchWithAddress:textField.text];
return YES;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self.inputAddressTf resignFirstResponder];
}
@end

View File

@@ -1,55 +0,0 @@
//
// AStationDetailPopupController.h
// AMapNavIOSSDK
//
// Created by admin on 2026/3/22.
//
#import <UIKit/UIKit.h>
#import "ANavPointModel.h"
#import "AMapNavSDKHeader.h"
NS_ASSUME_NONNULL_BEGIN
@class AStationDetailPopupController;
@protocol AStationDetailPopupDelegate <NSObject>
@optional
/// 点击"开始导航"
- (void)stationDetailPopupDidTapStartNavi:(AStationDetailPopupController *)popup;
/// 点击关闭
- (void)stationDetailPopupDidTapClose:(AStationDetailPopupController *)popup;
@end
@interface AStationDetailPopupController : UIViewController
@property (nonatomic, strong, nullable) ANavPointModel *pointModel;
/// 预计加氢费用(元),可由外部传入;若 nil 则隐藏
@property (nonatomic, copy, nullable) NSString *estimatedCost;
/// 预计时间,如 @"15分钟";若 nil 则隐藏
@property (nonatomic, copy, nullable) NSString *estimatedTime;
/// 行驶里程,如 @"23.5公里";若 nil 则隐藏
@property (nonatomic, copy, nullable) NSString *driveDistance;
/// 过路费,如 @"30元";若 nil 则隐藏
@property (nonatomic, copy, nullable) NSString *tollFee;
@property (nonatomic, weak, nullable) id<AStationDetailPopupDelegate> delegate;
/// 以半透明蒙层方式弹出在目标控制器上
- (void)presentInViewController:(UIViewController *)parentVC;
/// 关闭弹框
- (void)dismiss;
/// 关闭弹框,动画结束后执行 completion用于关闭后再 present 其他页面)
- (void)dismissWithCompletion:(nullable void(^)(void))completion;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,485 +0,0 @@
//
// AStationDetailPopupController.m
// AMapNavIOSSDK
//
// Created by admin on 2026/3/22.
//
#import "AStationDetailPopupController.h"
#import "ABaseViewController.h"
#import "AMapNavCommonUtil.h"
#import <Masonry/Masonry.h>
// 绿
static inline UIColor *AStationThemeGreen(void) {
return [UIColor colorWithRed:0x1A/255.0 green:0x7C/255.0 blue:0x43/255.0 alpha:1.0];
}
@interface AStationDetailPopupController ()
///
@property (nonatomic, strong) UIControl *maskControl;
///
@property (nonatomic, strong) UIView *cardView;
///
@property (nonatomic, strong) UILabel *stationNameLabel;
///
@property (nonatomic, strong) UIImageView *costIconView;
@property (nonatomic, strong) UILabel *costLabel;
///
@property (nonatomic, strong) UILabel *addressLabel;
/// 线
@property (nonatomic, strong) UIView *separator;
///
@property (nonatomic, strong) UIImageView *timeIconView;
@property (nonatomic, strong) UILabel *timeLabel;
///
@property (nonatomic, strong) UIImageView *distanceIconView;
@property (nonatomic, strong) UILabel *distanceLabel;
///
@property (nonatomic, strong) UIImageView *tollIconView;
@property (nonatomic, strong) UILabel *tollLabel;
///
@property (nonatomic, strong) UIButton *closeButton;
///
@property (nonatomic, strong) UIButton *startNaviButton;
/// bottom constraint
@property (nonatomic, strong) MASConstraint *cardBottomConstraint;
@end
@implementation AStationDetailPopupController
#pragma mark - Life Cycle
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor];
[self _buildUI];
[self _setupMasonryConstraints];
[self _updateUI];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self _playShowAnimation];
}
#pragma mark - Public
- (void)presentInViewController:(UIViewController *)parentVC {
self.modalPresentationStyle = UIModalPresentationOverCurrentContext;
self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[parentVC presentViewController:self animated:NO completion:nil];
}
- (void)dismiss {
[self dismissWithCompletion:nil];
}
- (void)dismissWithCompletion:(void(^)(void))completion {
[self _playDismissAnimationWithCompletion:^{
[self dismissViewControllerAnimated:NO completion:completion];
}];
}
#pragma mark - Setter Override
- (void)setPointModel:(ANavPointModel *)pointModel {
_pointModel = pointModel;
if (self.isViewLoaded) [self _updateUI];
}
- (void)setEstimatedCost:(NSString *)estimatedCost {
_estimatedCost = [estimatedCost copy];
if (self.isViewLoaded) [self _updateUI];
}
- (void)setEstimatedTime:(NSString *)estimatedTime {
_estimatedTime = [estimatedTime copy];
if (self.isViewLoaded) [self _updateUI];
}
- (void)setDriveDistance:(NSString *)driveDistance {
_driveDistance = [driveDistance copy];
if (self.isViewLoaded) [self _updateUI];
}
- (void)setTollFee:(NSString *)tollFee {
_tollFee = [tollFee copy];
if (self.isViewLoaded) [self _updateUI];
}
#pragma mark - Build UI
/**
[]
-- 20pt
[icon] --
[icon] -- [icon] --
(30pt)
*/
- (void)_buildUI {
//
UIControl *mask = [[UIControl alloc] init];
mask.backgroundColor = [UIColor colorWithWhite:0 alpha:0.35];
[mask addTarget:self action:@selector(_onMaskTapped) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:mask];
self.maskControl = mask;
//
UIView *card = [[UIView alloc] init];
card.backgroundColor = [UIColor whiteColor];
card.layer.cornerRadius = 16;
card.layer.masksToBounds = NO;
card.layer.shadowColor = [UIColor blackColor].CGColor;
card.layer.shadowOpacity = 0.15;
card.layer.shadowRadius = 12;
card.layer.shadowOffset = CGSizeMake(0, -4);
[self.view addSubview:card];
self.cardView = card;
//
UIButton *closeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
// [closeBtn setTitle:@"✕" forState:UIControlStateNormal];
[closeBtn setImage: [AMapNavCommonUtil imageWithName:@"icon_close"] forState:UIControlStateNormal];
[closeBtn setTitleColor:[UIColor colorWithWhite:0.5 alpha:1] forState:UIControlStateNormal];
closeBtn.titleLabel.font = [UIFont systemFontOfSize:16];
[closeBtn addTarget:self action:@selector(_onCloseTapped) forControlEvents:UIControlEventTouchUpInside];
[card addSubview:closeBtn];
self.closeButton = closeBtn;
//
UILabel *nameLabel = [[UILabel alloc] init];
nameLabel.font = [UIFont boldSystemFontOfSize:18];
nameLabel.textColor = [UIColor colorWithWhite:0.1 alpha:1];
nameLabel.numberOfLines = 2;
// nameLabel.adjustsFontSizeToFitWidth = YES;
nameLabel.minimumScaleFactor = 0.8;
[card addSubview:nameLabel];
self.stationNameLabel = nameLabel;
// 20pt
UILabel *costLabel = [[UILabel alloc] init];
costLabel.font = [UIFont systemFontOfSize:14];
costLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1];
costLabel.numberOfLines = 1;
costLabel.textAlignment = NSTextAlignmentLeft;
// [costLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
// [costLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[card addSubview:costLabel];
self.costLabel = costLabel;
//
UILabel *addrLabel = [[UILabel alloc] init];
addrLabel.font = [UIFont systemFontOfSize:13];
addrLabel.textColor = [UIColor colorWithWhite:0.5 alpha:1];
addrLabel.numberOfLines = 2;
[card addSubview:addrLabel];
self.addressLabel = addrLabel;
UIImageView *costIcon = [[UIImageView alloc] init];
costIcon.contentMode = UIViewContentModeScaleAspectFit;
costIcon.image = [AMapNavCommonUtil imageWithName3x:@"ic_fuel"];
[card addSubview:costIcon];
self.costIconView = costIcon;
// 线
UIView *sep = [[UIView alloc] init];
sep.backgroundColor = [UIColor colorWithWhite:0.88 alpha:1];
[card addSubview:sep];
self.separator = sep;
//
UIImageView *timeIcon = [[UIImageView alloc] init];
timeIcon.contentMode = UIViewContentModeScaleAspectFit;
timeIcon.image = [AMapNavCommonUtil imageWithName3x:@"pre_time_icon"];
[card addSubview:timeIcon];
self.timeIconView = timeIcon;
//
UILabel *timeLabel = [[UILabel alloc] init];
timeLabel.font = [UIFont systemFontOfSize:14];
timeLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1];
[card addSubview:timeLabel];
self.timeLabel = timeLabel;
//
UIImageView *distIcon = [[UIImageView alloc] init];
distIcon.contentMode = UIViewContentModeScaleAspectFit;
distIcon.image = [AMapNavCommonUtil imageWithName3x:@"pre_distance_icon"];
[card addSubview:distIcon];
self.distanceIconView = distIcon;
//
UILabel *distLabel = [[UILabel alloc] init];
distLabel.font = [UIFont systemFontOfSize:14];
distLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1];
[card addSubview:distLabel];
self.distanceLabel = distLabel;
//
UIImageView *tollIcon = [[UIImageView alloc] init];
tollIcon.contentMode = UIViewContentModeScaleAspectFit;
tollIcon.image = [AMapNavCommonUtil imageWithName3x:@"pre_cost_icon"];
[card addSubview:tollIcon];
self.tollIconView = tollIcon;
//
UILabel *tollLabel = [[UILabel alloc] init];
tollLabel.font = [UIFont systemFontOfSize:14];
tollLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1];
[card addSubview:tollLabel];
self.tollLabel = tollLabel;
//
UIButton *naviBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[naviBtn setTitle:@"开始导航" forState:UIControlStateNormal];
[naviBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
naviBtn.titleLabel.font = [UIFont boldSystemFontOfSize:17];
naviBtn.backgroundColor = AStationThemeGreen();
naviBtn.layer.cornerRadius = 24;
[naviBtn addTarget:self action:@selector(_onStartNaviTapped) forControlEvents:UIControlEventTouchUpInside];
[card addSubview:naviBtn];
self.startNaviButton = naviBtn;
}
#pragma mark - Masonry Constraints
- (void)_setupMasonryConstraints {
UIView *card = self.cardView;
CGFloat iconSize = 16;
//
[self.maskControl mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view);
}];
// 16 safeArea 30pt
// top bottom
[card mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(16);
make.right.equalTo(self.view).offset(-16);
// =
make.top.equalTo(self.view.mas_bottom).offset(0);
}];
//
[self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(card).offset(8);
make.right.equalTo(card).offset(-15);
make.width.height.mas_equalTo(40);
}];
// + nameLabel20pt
// nameLabel55%
[self.stationNameLabel setContentHuggingPriority:UILayoutPriorityDefaultLow
forAxis:UILayoutConstraintAxisHorizontal];
[self.stationNameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(card).offset(25);
make.left.equalTo(card).offset(16);
// make.width.lessThanOrEqualTo(card).multipliedBy(0.45);
make.right.equalTo(self.closeButton.mas_left).offset(-12);
}];
// 6pt
[self.addressLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.stationNameLabel.mas_bottom).offset(10);
make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16);
}];
// 线12pt
[self.separator mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.addressLabel.mas_bottom).offset(15);
make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16);
make.height.mas_equalTo(0.5);
}];
// 线14pt
[self.timeIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.separator.mas_bottom).offset(15);
make.left.equalTo(card).offset(16);
make.width.height.mas_equalTo(iconSize);
}];
[self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.timeIconView);
make.left.equalTo(self.timeIconView.mas_right).offset(6);
// make.right.equalTo(card).offset(-16);
make.height.mas_equalTo(24);
}];
///cost
[self.costIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.timeIconView);
make.left.equalTo(self.timeLabel.mas_right).offset(30);
make.width.height.mas_equalTo(iconSize);
}];
[self.costLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.costIconView);
make.left.equalTo(self.costIconView.mas_right).offset(6);
make.right.lessThanOrEqualTo(card).offset(-10);
}];
// + 12pt
[self.distanceIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.timeIconView.mas_bottom).offset(15);
make.left.equalTo(card).offset(16);
make.width.height.mas_equalTo(iconSize);
}];
[self.distanceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.distanceIconView);
make.left.equalTo(self.distanceIconView.mas_right).offset(6);
//
make.width.mas_lessThanOrEqualTo(130);
make.height.mas_equalTo(24);
}];
[self.tollIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.distanceIconView);
make.left.equalTo(self.costIconView.mas_left);
make.width.height.mas_equalTo(iconSize);
}];
[self.tollLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.distanceIconView);
make.left.equalTo(self.tollIconView.mas_right).offset(6);
// make.right.equalTo(card).offset(-16);
make.height.mas_equalTo(24);
}];
// 18pt30pt
[self.startNaviButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.distanceIconView.mas_bottom).offset(50);
make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16);
make.height.mas_equalTo(48);
make.bottom.equalTo(card).offset(-AMP_TabbarSafeBottomMargin); // 30pt
}];
}
#pragma mark - Data Update
- (void)_updateUI {
self.stationNameLabel.text = (self.pointModel.name.length > 0)
? self.pointModel.name : @"--";
self.costLabel.text = (self.estimatedCost.length > 0)
? [NSString stringWithFormat:@"预计加氢费用:%@元", self.estimatedCost]
: @"预计加氢费用:--元";
self.addressLabel.text = (self.pointModel.address.length > 0)
? self.pointModel.address : @"--";
// "-- 分钟"
self.timeLabel.text = (self.estimatedTime.length > 0)
? [NSString stringWithFormat:@"预计时间:%@分钟", self.estimatedTime]
: @"预计时间:--分钟";
// "-- 公里"
self.distanceLabel.text = (self.driveDistance.length > 0)
? [NSString stringWithFormat:@"行驶里程:%@公里", self.driveDistance]
: @"行驶里程:--公里";
// "-- 元"
self.tollLabel.text = (self.tollFee.length > 0)
? [NSString stringWithFormat:@"过路费:%@元", self.tollFee]
: @"过路费:--元";
}
#pragma mark - Animation
/**
top 30pt safeArea
*/
- (void)_playShowAnimation {
// safeArea 30pt
[self.cardView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(0);
make.right.equalTo(self.view).offset(-0);
make.bottom.equalTo(self.view).offset(0);
}];
self.maskControl.alpha = 0;
[UIView animateWithDuration:0.36
delay:0
usingSpringWithDamping:0.82
initialSpringVelocity:0.5
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.maskControl.alpha = 1;
[self.view layoutIfNeeded];
} completion:nil];
}
- (void)_playDismissAnimationWithCompletion:(void(^)(void))completion {
[self.cardView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(16);
make.right.equalTo(self.view).offset(-16);
make.top.equalTo(self.view.mas_bottom).offset(20);
}];
[UIView animateWithDuration:0.25
delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
self.maskControl.alpha = 0;
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
if (completion) completion();
}];
}
#pragma mark - Actions
- (void)_onMaskTapped {
if ([self.delegate respondsToSelector:@selector(stationDetailPopupDidTapClose:)]) {
[self.delegate stationDetailPopupDidTapClose:self];
}
[self dismiss];
}
- (void)_onCloseTapped {
if ([self.delegate respondsToSelector:@selector(stationDetailPopupDidTapClose:)]) {
[self.delegate stationDetailPopupDidTapClose:self];
}
[self dismiss];
}
- (void)_onStartNaviTapped {
// delegate
// presentViewController
__weak typeof(self) weakSelf = self;
[self dismissWithCompletion:^{
__strong typeof(weakSelf) strongSelf = weakSelf;
if ([strongSelf.delegate respondsToSelector:@selector(stationDetailPopupDidTapStartNavi:)]) {
[strongSelf.delegate stationDetailPopupDidTapStartNavi:strongSelf];
}
}];
}
@end

View File

@@ -1,67 +0,0 @@
//
// AAlgorithmPathModel.h
// AMapNavIOSSDK
//
// Created by admin on 2026/3/25.
//
#import <Foundation/Foundation.h>
#import <MJExtension/MJExtension.h>
NS_ASSUME_NONNULL_BEGIN
@interface AAlgorithmPathModel : NSObject
/// 单程
@property (nonatomic, copy, nullable) NSString *tripRecommendationId;
@property (nonatomic, copy, nullable) NSString *staId;
@property (nonatomic, copy, nullable) NSString *tripOneWayPathId;
@property (nonatomic, copy, nullable) NSString *tripReturnPathId;
/// 里程(公里)
@property (nonatomic, copy, nullable) NSString *oneWayDis;
@property (nonatomic, copy, nullable) NSString *returnDis;
@property (nonatomic, copy, nullable) NSString *roundTripDis;
/// 时长(分钟)
@property (nonatomic, copy, nullable) NSString *oneWayTime;
@property (nonatomic, copy, nullable) NSString *returnTime;
@property (nonatomic, copy, nullable) NSString *roundTripTime;
/// 总成本(元)
@property (nonatomic, copy, nullable) NSString *oneWayCost;
@property (nonatomic, copy, nullable) NSString *returnCost;
@property (nonatomic, copy, nullable) NSString *roundTripCost;
/// 人工成本(元)
@property (nonatomic, copy, nullable) NSString *oneWayLaborCost;
@property (nonatomic, copy, nullable) NSString *returnLaborCost;
@property (nonatomic, copy, nullable) NSString *roundTripLaborCost;
/// 高速成本(元)
@property (nonatomic, copy, nullable) NSString *oneWayChargerouteCost;
@property (nonatomic, copy, nullable) NSString *returnChargerouteCost;
@property (nonatomic, copy, nullable) NSString *roundTripChargerouteCost;
/// 氢耗(公斤)
@property (nonatomic, copy, nullable) NSString *oneWayHydrogenConsumption;
@property (nonatomic, copy, nullable) NSString *returnLaborHydrogenConsumption;
@property (nonatomic, copy, nullable) NSString *roundTripHydrogenConsumption;
/// 氢气成本(元)
@property (nonatomic, copy, nullable) NSString *oneWayHydrogenCost;
@property (nonatomic, copy, nullable) NSString *returnLaborHydrogenCost;
@property (nonatomic, copy, nullable) NSString *roundTripHydrogenCost;
/// 加氢站相关
@property (nonatomic, copy, nullable) NSString *hydrogenCost; // 氢气总成本(元)
@property (nonatomic, copy, nullable) NSString *hydrogenStaServiceTime; // 站服务总时长(分钟)
@property (nonatomic, copy, nullable) NSString *hydrogenStaRefuelingTime;// 实际加油时长(分钟)
@property (nonatomic, copy, nullable) NSString *hydrogenStaQueueTime; // 排队时长(分钟)
@property (nonatomic, copy, nullable) NSString *hydrogenStaServiceTimeCost; // 站服务时间成本(元)
@property (nonatomic, copy, nullable) NSString *hydrogenStaRefuelingTimeCost;// 加油时间成本(元)
@property (nonatomic, copy, nullable) NSString *hydrogenStaQueueTimeCost; // 排队时间成本(元)
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,12 +0,0 @@
//
// AAlgorithmPathModel.m
// AMapNavIOSSDK
//
// Created by admin on 2026/3/25.
//
#import "AAlgorithmPathModel.h"
@implementation AAlgorithmPathModel
@end

View File

@@ -1,17 +0,0 @@
//
// ACustomPointAnnotation.h
// Pods
//
// Created by admin on 2026/3/25.
//
#import <AMapNaviKit/AMapNaviKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface ACustomPointAnnotation : MAPointAnnotation
@property (nonatomic, copy, nullable) NSString *stationID;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,12 +0,0 @@
//
// ACustomPointAnnotation.m
// Pods
//
// Created by admin on 2026/3/25.
//
#import "ACustomPointAnnotation.h"
@implementation ACustomPointAnnotation
@end

View File

@@ -1,81 +0,0 @@
//
// AMapHyStationModel.h
// AMapNavIOSSDK
//
// Created by admin on 2026/2/11.
//
#import <Foundation/Foundation.h>
#import <MJExtension/MJExtension.h>
NS_ASSUME_NONNULL_BEGIN
/**
{
"name": "嘉兴经开站",
"shortName": null,
"siteNo": null,
"city": null,
"address": "嘉兴市秀洲区岗山路272号",
"contact": "龚明伟",
"phone": "18888888888",
"type": null,
"coOpMode": null,
"booking": null,
"siteStatus": 0,
"startBusiness": "06:00:00",
"endBusiness": "22:00:00",
"billingMethod": null,
"term": null,
"remark": null,
"longitude": "120.75972800",
"latitude": "30.79962800"
}
*/
@interface AMapHyStationModel : NSObject
@property (nonatomic, copy, nullable) NSString *ID;
@property (nonatomic, copy, nullable) NSString *hydrogenId;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy, nullable) NSString *shortName;
@property (nonatomic, copy, nullable) NSString *siteNo;
@property (nonatomic, copy, nullable) NSString *city;
@property (nonatomic, copy, nullable) NSString *address;
@property (nonatomic, copy, nullable) NSString *contact;
@property (nonatomic, copy, nullable) NSString *phone;
@property (nonatomic, copy, nullable) NSString *type;
@property (nonatomic, copy, nullable) NSString *coOpMode;
@property (nonatomic, strong, nullable) NSString * booking;
@property (nonatomic, assign) NSInteger siteStatus;
@property (nonatomic, copy, nullable) NSString *startBusiness;
@property (nonatomic, copy, nullable) NSString *endBusiness;
@property (nonatomic, copy, nullable) NSString *billingMethod;
@property (nonatomic, copy, nullable) NSString *term;
@property (nonatomic, copy, nullable) NSString *remark;
@property (nonatomic, copy, nullable) NSString *longitude;
@property (nonatomic, copy, nullable) NSString *latitude;
@end
/**
{
"code": 0,
"status": true,
"message": "success",
"data": [],
"time": "1770800256408",
"error": null
}
*/
@interface AMapHyResponse : NSObject
@property (nonatomic, assign) NSInteger code;
@property (nonatomic, assign) NSInteger status;
@property (nonatomic, copy, nullable) NSString *message;
@property (nonatomic, copy, nullable) NSString *time;
@property (nonatomic, copy, nullable) NSString *error;
@property(nonatomic , strong)NSArray <AMapHyStationModel * > * data;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,25 +0,0 @@
//
// AMapHyStationModel.m
// AMapNavIOSSDK
//
// Created by admin on 2026/2/11.
//
#import "AMapHyStationModel.h"
@implementation AMapHyStationModel
+ (NSDictionary *)mj_replacedKeyFromPropertyName
{
return @{ @"ID" : @"id"};
}
@end
@implementation AMapHyResponse
+ (NSDictionary *)mj_objectClassInArray {
return @{@"data" : AMapHyStationModel.class};
}
@end

View File

@@ -1,26 +0,0 @@
//
// ANavPointModel.h
// AMapNavIOSSDK
//
// Created by admin on 2026/3/25.
//
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
NS_ASSUME_NONNULL_BEGIN
@interface ANavPointModel : NSObject
@property (nonatomic, copy, nullable) NSString *name;
@property (nonatomic, copy, nullable) NSString *address;
@property (nonatomic, copy, nullable) NSString *stationID;
///经纬度
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
///初始化
+ (instancetype)instanceWithCoordinate:(CLLocationCoordinate2D)coordinate name:(NSString *)name address:(NSString *)address;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,22 +0,0 @@
//
// ANavPointModel.m
// AMapNavIOSSDK
//
// Created by admin on 2026/3/25.
//
#import "ANavPointModel.h"
@implementation ANavPointModel
///
+ (instancetype)instanceWithCoordinate:(CLLocationCoordinate2D)coordinate name:(NSString *)name address:(NSString *)address {
ANavPointModel *instance = [[ANavPointModel alloc] init];
if (instance) {
instance.coordinate = coordinate;
instance.name = name;
instance.address = address;
}
return instance;
}
@end

View File

@@ -1,32 +0,0 @@
//
// ANaviPathInfoModel.h
// AMapNavIOSSDK
//
// Created by admin on 2026/3/25.
//
#import <Foundation/Foundation.h>
#import <MJExtension/MJExtension.h>
NS_ASSUME_NONNULL_BEGIN
/**
{
"name": "浙江省嘉兴市平湖市乍浦镇滨海大道中国石化滨海大道加油加气站",
"poiId": "",
"coordinate": {
"longitude": "121.070434",
"latitude": "30.596124"
}
}
*/
@interface ANaviPathInfoModel : NSObject
@property (nonatomic, copy, nullable) NSString *name;
@property (nonatomic, copy, nullable) NSString *poiId;
@property (nonatomic, copy, nullable) NSString *longitude;
@property (nonatomic, copy, nullable) NSString *latitude;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,20 +0,0 @@
//
// ANaviPathInfoModel.m
// AMapNavIOSSDK
//
// Created by admin on 2026/3/25.
//
#import "ANaviPathInfoModel.h"
@implementation ANaviPathInfoModel
+ (NSDictionary *)mj_replacedKeyFromPropertyName {
// JSON coordinate longitude/latitude
return @{
@"longitude": @"coordinate.longitude",
@"latitude": @"coordinate.latitude"
};
}
@end

View File

@@ -1,29 +0,0 @@
//
// APathModel.h
// AMapNavIOSSDK
//
// Created by admin on 2026/3/25.
//
#import <Foundation/Foundation.h>
#import <MJExtension/MJExtension.h>
#import "ANaviPathInfoModel.h"
NS_ASSUME_NONNULL_BEGIN
@class ANaviPathInfoModel;
@interface APathModel : NSObject
@property (nonatomic, assign) CGFloat distance; // 总距离(米)
@property (nonatomic, assign) CGFloat duration; // 总时长(秒)
@property (nonatomic, copy, nullable) NSString *strategy; // 路线策略,如"避免拥堵"
@property (nonatomic, copy, nullable) NSString *tolls; // 高速费(元)
@property (nonatomic, assign) CGFloat toll_distance; // 高速里程(米)
@property (nonatomic, assign) NSInteger restriction; // 限行标志,-1 无
@property (nonatomic, assign) NSInteger traffic_lights; // 红绿灯数量
@property (nonatomic, strong) NSArray<ANaviPathInfoModel *> *naviList; // 途经点列表
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,17 +0,0 @@
//
// APathModel.m
// AMapNavIOSSDK
//
// Created by admin on 2026/3/25.
//
#import "APathModel.h"
#import "ANaviPathInfoModel.h"
@implementation APathModel
+ (NSDictionary *)mj_objectClassInArray {
return @{@"naviList": [ANaviPathInfoModel class]};
}
@end

View File

@@ -1,64 +0,0 @@
//
// ASiteModel.h
// AMapNavIOSSDK
//
// Created by admin on 2026/3/25.
//
#import <Foundation/Foundation.h>
#import <MJExtension/MJExtension.h>
NS_ASSUME_NONNULL_BEGIN
/**
{
"innerSiteId": "202304241822210001",
"name": "滨海大道加油加气站",
"shortName": "滨海",
"siteNo": "000001",
"city": "浙江省-嘉兴市",
"address": "嘉兴市平湖市滨海大道1515号",
"contact": "陆平",
"phone": "18666666666",
"type": "",
"coOpMode": "签约",
"booking": "无需预约",
"siteStatus": "0",
"siteStatusName": "营运中",
"startBusiness": "08:00:00",
"endBusiness": "20:00:00",
"billingMethod": "月付款",
"term": "1703952000000",
"remark": "",
"longitude": "121.07112700",
"latitude": "30.59577700",
"distance": ""
}
*/
@interface ASiteModel : NSObject
@property (nonatomic, copy, nullable) NSString *innerSiteId;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy, nullable) NSString *shortName;
@property (nonatomic, copy, nullable) NSString *siteNo;
@property (nonatomic, copy, nullable) NSString *city;
@property (nonatomic, copy, nullable) NSString *address;
@property (nonatomic, copy, nullable) NSString *contact;
@property (nonatomic, copy, nullable) NSString *phone;
@property (nonatomic, copy, nullable) NSString *type;
@property (nonatomic, copy, nullable) NSString *coOpMode;
@property (nonatomic, copy, nullable) NSString *booking;
@property (nonatomic, copy, nullable) NSString *siteStatus;
@property (nonatomic, copy, nullable) NSString *siteStatusName;
@property (nonatomic, copy, nullable) NSString *startBusiness;
@property (nonatomic, copy, nullable) NSString *endBusiness;
@property (nonatomic, copy, nullable) NSString *billingMethod;
@property (nonatomic, copy, nullable) NSString *term;
@property (nonatomic, copy, nullable) NSString *remark;
@property (nonatomic, copy, nullable) NSString *longitude;
@property (nonatomic, copy, nullable) NSString *latitude;
@property (nonatomic, copy, nullable) NSString *distance;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,12 +0,0 @@
//
// ASiteModel.m
// AMapNavIOSSDK
//
// Created by admin on 2026/3/25.
//
#import "ASiteModel.h"
@implementation ASiteModel
@end

View File

@@ -1,65 +0,0 @@
//
// ATripCalcResponse.h
// AMapNavIOSSDK
//
// Created by admin on 2026/3/25.
//
#import <Foundation/Foundation.h>
#import <MJExtension/MJExtension.h>
#import "AAlgorithmPathModel.h"
#import "APathModel.h"
#import "ASiteModel.h"
#import "ANaviPathInfoModel.h"
#import "ATruckModel.h"
NS_ASSUME_NONNULL_BEGIN
@class ATruckModel;
@class ASiteModel;
@class APathModel;
@class AAlgorithmPathModel;
#pragma mark - data 节点
/**
{
"truckDto": { ... },
"truckDtoStr": null,
"destinationSite": { ... },
"pathDto": { ... },
"algorithmPath": { ... },
"isInvokeAlgorithm": true
}
*/
@interface ATripCalcDataModel : NSObject
@property (nonatomic, strong, nullable) ATruckModel *truckDto;
@property (nonatomic, copy, nullable) NSString *truckDtoStr;
@property (nonatomic, strong, nullable) ASiteModel *destinationSite;
@property (nonatomic, strong, nullable) APathModel *pathDto;
@property (nonatomic, strong, nullable) AAlgorithmPathModel *algorithmPath;
@property (nonatomic, assign) BOOL isInvokeAlgorithm;
@end
#pragma mark - 根响应
/**
{
"code": 200,
"msg": "操作成功!",
"data": { ... }
}
*/
@interface ATripCalcResponse : NSObject
@property (nonatomic, assign) NSInteger code;
@property (nonatomic, copy, nullable) NSString *msg;
@property (nonatomic, strong, nullable) ATripCalcDataModel *data;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,33 +0,0 @@
//
// ATripCalcResponse.m
// AMapNavIOSSDK
//
// Created by admin on 2026/3/25.
//
#import "ATripCalcResponse.h"
#import "ATruckModel.h"
#import "ASiteModel.h"
#import "APathModel.h"
#import "AAlgorithmPathModel.h"
@implementation ATripCalcDataModel
+ (NSDictionary *)mj_objectClassInArray {
return @{
@"truckDto": [ATruckModel class],
@"destinationSite": [ASiteModel class],
@"pathDto": [APathModel class],
@"algorithmPath": [AAlgorithmPathModel class]
};
}
@end
@implementation ATripCalcResponse
+ (NSDictionary *)mj_objectClassInArray {
return @{@"data":[ATripCalcDataModel class]};
}
@end

View File

@@ -1,58 +0,0 @@
//
// ATruckModel.h
// AMapNavIOSSDK
//
// Created by admin on 2026/3/25.
//
#import <Foundation/Foundation.h>
#import <MJExtension/MJExtension.h>
NS_ASSUME_NONNULL_BEGIN
/**
{
"isRestriction": true,
"mvehicleSizeName": "重型货车",
"mvehicleAxisUnit": "轴",
"mcarNumber": "浙F32111F",
"mcarType": 0,
"mvehicleHeight": "3.8",
"mvehicleHeightUnit": "M",
"mvehicleWeight": null,
"mvehicleWeightUnit": "T",
"mvehicleLoad": "49.0",
"mvehicleLoadUnit": "T",
"mvehicleLoadSwitch": false,
"mvehicleWidth": "0.0",
"mvehicleWidthUnit": "M",
"mvehicleLength": "7.6",
"mvehicleLengthUnit": "M",
"mvehicleSize": 4,
"mvehicleAxis": 5
}
*/
@interface ATruckModel : NSObject
@property (nonatomic, assign) BOOL isRestriction;
@property (nonatomic, copy, nullable) NSString *mvehicleSizeName;
@property (nonatomic, copy, nullable) NSString *mvehicleAxisUnit;
@property (nonatomic, copy, nullable) NSString *mcarNumber;
@property (nonatomic, assign) NSInteger mcarType;
@property (nonatomic, copy, nullable) NSString *mvehicleHeight;
@property (nonatomic, copy, nullable) NSString *mvehicleHeightUnit;
@property (nonatomic, copy, nullable) NSString *mvehicleWeight;
@property (nonatomic, copy, nullable) NSString *mvehicleWeightUnit;
@property (nonatomic, copy, nullable) NSString *mvehicleLoad;
@property (nonatomic, copy, nullable) NSString *mvehicleLoadUnit;
@property (nonatomic, assign) BOOL mvehicleLoadSwitch;
@property (nonatomic, copy, nullable) NSString *mvehicleWidth;
@property (nonatomic, copy, nullable) NSString *mvehicleWidthUnit;
@property (nonatomic, copy, nullable) NSString *mvehicleLength;
@property (nonatomic, copy, nullable) NSString *mvehicleLengthUnit;
@property (nonatomic, assign) NSInteger mvehicleSize;
@property (nonatomic, assign) NSInteger mvehicleAxis;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,12 +0,0 @@
//
// ATruckModel.m
// AMapNavIOSSDK
//
// Created by admin on 2026/3/25.
//
#import "ATruckModel.h"
@implementation ATruckModel
@end

View File

@@ -1,39 +0,0 @@
//
// AMapNavCommonUtil.h
// Pods
//
// Created by admin on 2026/2/11.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface AMapNavCommonUtil : NSObject
/// 显示加载转圈nil 消息时不显示文字)
+ (void)showLoadingWithMsg:(nullable NSString *)msg;
/// 关闭所有 MBProgressHUD
+ (void)dismiss;
/// 显示提示,自动 2.0s 后消失
+ (void)showMsg:(NSString *)msg;
/// 获取图片2x
+ (UIImage *)imageWithName:(NSString *)name;
/// 获取图片3x
+ (UIImage *)imageWithName3x:(NSString *)name;
/// 判断字符串是否为空
BOOL stringIsEmpty(NSString *str);
/// 判断字符串是否非空
BOOL stringIsNotEmpty(NSString *str);
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,144 +0,0 @@
//
// AMapNavCommonUtil.m
// Pods
//
// Created by admin on 2026/2/11.
//
#import "AMapNavCommonUtil.h"
#import <MBProgressHUD/MBProgressHUD.h>
/// HUD
static MBProgressHUD *_sharedHUD = nil;
@implementation AMapNavCommonUtil
#pragma mark - MBProgressHUD
+ (UIWindow *)_keyWindow {
if (@available(iOS 13.0, *)) {
for (UIWindowScene *scene in [UIApplication sharedApplication].connectedScenes) {
if (scene.activationState == UISceneActivationStateForegroundActive) {
for (UIWindow *window in scene.windows) {
if (window.isKeyWindow) return window;
}
}
}
}
return [UIApplication sharedApplication].keyWindow;
}
+ (void)showLoadingWithMsg:(NSString *)msg {
dispatch_async(dispatch_get_main_queue(), ^{
// [self dismiss];
UIWindow *window = [self _keyWindow];
if (!window) return;
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:window animated:YES];
hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
hud.bezelView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.75];
hud.contentColor = [UIColor whiteColor];
if (msg.length > 0) {
hud.label.text = msg;
hud.label.font = [UIFont systemFontOfSize:14];
}
hud.removeFromSuperViewOnHide = YES;
_sharedHUD = hud;
});
}
+ (void)dismiss {
dispatch_async(dispatch_get_main_queue(), ^{
if (_sharedHUD) {
[_sharedHUD hideAnimated:YES];
_sharedHUD = nil;
} else {
// HUD
UIWindow *window = [self _keyWindow];
if (window) {
[MBProgressHUD hideHUDForView:window animated:YES];
}
}
});
}
+ (void)showMsg:(NSString *)msg {
if (msg.length == 0) return;
dispatch_async(dispatch_get_main_queue(), ^{
UIWindow *window = [self _keyWindow];
if (!window) return;
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:window animated:YES];
hud.mode = MBProgressHUDModeText;
hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
hud.bezelView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.75];
hud.contentColor = [UIColor whiteColor];
hud.label.text = msg;
hud.label.font = [UIFont systemFontOfSize:14];
hud.removeFromSuperViewOnHide = YES;
// 2.0s
[hud hideAnimated:YES afterDelay:2.0];
});
}
#pragma mark -
BOOL stringIsEmpty (NSString *str)
{
if (str == nil || str == NULL)
{
return YES;
}
if ([str isKindOfClass:[NSNull class]])
{
return YES;
}
if ([str isKindOfClass:[NSString class]])
{
NSString * newStr = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSSet *emptySet = [NSSet setWithObjects:@"", @"null", @"(null)", @"<null>", @"NULL", @"无",@"kZero", nil];
if ([emptySet containsObject:str] || [emptySet containsObject:newStr]) {
return YES;
} else {
return [newStr length] == 0;
}
}
return NO;
}
BOOL stringIsNotEmpty (NSString *str)
{
return ! stringIsEmpty(str);
}
#pragma mark -
+(UIImage *)imageWithName:(NSString *)name {
NSURL * url = [[NSBundle mainBundle] URLForResource:@"AMapNavIOSSDK" withExtension:@"bundle"];
NSBundle *containnerBundle = [NSBundle bundleWithURL:url];
NSString * path = [containnerBundle pathForResource:[NSString stringWithFormat:@"%@@2x.png" , name] ofType:nil];
UIImage * arrowImage = [[UIImage imageWithContentsOfFile:path] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
return arrowImage;
}
+(UIImage *)imageWithName3x:(NSString *)name {
NSURL * url = [[NSBundle mainBundle] URLForResource:@"AMapNavIOSSDK" withExtension:@"bundle"];
NSBundle *containnerBundle = [NSBundle bundleWithURL:url];
NSString * path = [containnerBundle pathForResource:[NSString stringWithFormat:@"%@@3x.png" , name] ofType:nil];
UIImage * arrowImage = [[UIImage imageWithContentsOfFile:path] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
return arrowImage;
}
@end

View File

@@ -1,19 +0,0 @@
//
// AMapNavHttpUtil.h
// AMapNavIOSSDK
//
// Created by admin on 2026/2/11.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface AMapNavHttpUtil : NSObject
+ (void)postRequestWithURL:(NSString *)urlString parameters:(id)parameters requestHeader:(NSDictionary *)headParam successHandler:(void (^)(NSDictionary *data, NSURLResponse *response))successHandler failureHandler:(void ( ^)(NSError *error))failureHandler;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,114 +0,0 @@
//
// AMapNavHttpUtil.m
// AMapNavIOSSDK
//
// Created by admin on 2026/2/11.
//
#import "AMapNavHttpUtil.h"
#define AMapRequestMethod_POST @"POST"
@interface AMapNavHttpUtil ()
@property (nonatomic , copy) NSString * baseURL;
@end
@implementation AMapNavHttpUtil
+ (instancetype)sharedInstance {
static AMapNavHttpUtil *sharedInstance = nil;
static dispatch_once_t onceToken;
// dispatch_once
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
//
});
return sharedInstance;
}
- (instancetype)init {
self = [super init];
if (self) {
// if (sdk.config.developmentModel) {
// _baseURL = kYTOTPAnalyticsSDKTestHost;
// }else {
// _baseURL = kYTOTPAnalyticsSDKProductionHost;
// }
}
return self;
}
+ (void)postRequestWithURL:(NSString *)urlString parameters:(id)parameters requestHeader:(NSDictionary *)headParam successHandler:(void (^)(NSDictionary *data, NSURLResponse *response))successHandler failureHandler:(void ( ^)(NSError *error))failureHandler {
[self requestWithMethod:AMapRequestMethod_POST URL:urlString parameters:parameters requestHeader:headParam successHandler:successHandler failureHandler:failureHandler];
}
// 使NSURLSession
+ (void)requestWithMethod:(NSString *)method URL:(NSString *)urlString parameters:(id)parameters requestHeader:(NSDictionary *)headParam successHandler:(void (^)(NSDictionary *data, NSURLResponse *response))successHandler failureHandler:(void (^)(NSError *error))failureHandler {
if (!urlString) {
return;
}
// URL
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@" , urlString]];
//
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = method;
request.timeoutInterval = 30.0;
// json
if (headParam) {
for (NSString *key in headParam.allKeys) {
if (headParam[key]) {
[request setValue:[NSString stringWithFormat:@"%@",headParam[key]] forHTTPHeaderField:key];
}
}
}
// JSON
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:&error];
if (!jsonData) {}
if ([method isEqualToString: AMapRequestMethod_POST]) {
//
request.HTTPBody = jsonData;
}
__block NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
NSLog(@"request error:%@" , error);
if (failureHandler) {
failureHandler(error);
}
} else {
if (successHandler) {
NSDictionary * dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
if(dic){
NSLog(@"url: %@ , response data:%@", url , dic);
}
dispatch_async(dispatch_get_main_queue(), ^{
successHandler(dic, response);
});
// successHandler(dic, response);
}
}
[session finishTasksAndInvalidate];
session = nil;
}];
//
[task resume];
}
@end

View File

@@ -1,32 +0,0 @@
//
// AMapPrivacyUtility.h
// officialDemoNavi
//
// Created by menglong on 2021/10/29.
// Copyright © 2021 AutoNavi. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/*
* 隐私合规使用demo 工具类
*/
@interface AMapPrivacyUtility : NSObject
/**
* @brief 通过这个方法来判断是否同意隐私合规
* 1.如果没有同意隐私合规则创建的SDK manager 实例返回 为nil 无法使用SDK提供的功能
* 2.如果同意了下次启动不提示 的授权,则不会弹框给用户
* 3.如果只同意了,则下次启动还要给用户弹框提示
*/
+ (void)handlePrivacyAgreeStatus;
+ (void)handlePrivacyAgreeStatusIn:(UIViewController*)targetVC;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,137 +0,0 @@
//
// AMapPrivacyUtility.m
// officialDemoNavi
//
// Created by menglong on 2021/10/29.
// Copyright © 2021 AutoNavi. All rights reserved.
//
#import "AMapPrivacyUtility.h"
#import <UIKit/UIKit.h>
#import <AMapNavikit/AMapNaviManagerConfig.h>
@implementation AMapPrivacyUtility
+ (void)showPrivacyInfoInWindow:(UIWindow *)window {
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.alignment = NSTextAlignmentLeft;
NSMutableAttributedString *privacyInfo = [[NSMutableAttributedString alloc] initWithString:@"\n亲感谢您对XXX一直以来的信任我们依据最新的监管要求更新了XXX《隐私权政策》特向您说明如下\n1.为向您提供交易相关基本功能,我们会收集、使用必要的信息;\n2.基于您的明示授权,我们可能会获取您的位置(为您提供附近的商品、店铺及优惠资讯等)等信息,您有权拒绝或取消授权;\n3.我们会采取业界先进的安全措施保护您的信息安全;\n4.未经您同意,我们不会从第三方处获取、共享或向提供您的信息;" attributes:@{
NSParagraphStyleAttributeName:paragraphStyle,
}];
[privacyInfo addAttribute:NSLinkAttributeName
value:@"《隐私权政策》"
range:[[privacyInfo string] rangeOfString:@"《隐私权政策》"]];
UIAlertController *privacyInfoController = [UIAlertController alertControllerWithTitle:@"温馨提示(隐私合规示例)" message:@"" preferredStyle:UIAlertControllerStyleAlert];
[privacyInfoController setValue:privacyInfo forKey:@"attributedMessage"];
UIAlertAction *agreeAllAction = [UIAlertAction actionWithTitle:@"同意(下次不提示)" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"agreeStatus"];
[[NSUserDefaults standardUserDefaults] synchronize];
//SDK. since 8.1.0
[[AMapNaviManagerConfig sharedConfig] updatePrivacyAgree:AMapPrivacyAgreeStatusDidAgree];
}];
UIAlertAction *agreeAction = [UIAlertAction actionWithTitle:@"同意" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//SDK. since 8.1.0
[[AMapNaviManagerConfig sharedConfig] updatePrivacyAgree:AMapPrivacyAgreeStatusDidAgree];
}];
UIAlertAction *notAgreeAction = [UIAlertAction actionWithTitle:@"不同意" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"agreeStatus"];
[[NSUserDefaults standardUserDefaults] synchronize];
//SDK. since 8.1.0
[[AMapNaviManagerConfig sharedConfig] updatePrivacyAgree:AMapPrivacyAgreeStatusNotAgree];
}];
[privacyInfoController addAction:agreeAllAction];
[privacyInfoController addAction:agreeAction];
[privacyInfoController addAction:notAgreeAction];
[window.rootViewController presentViewController:privacyInfoController animated:YES completion:^{
//AppSDK. since 8.1.0
[[AMapNaviManagerConfig sharedConfig] updatePrivacyShow:AMapPrivacyShowStatusDidShow privacyInfo:AMapPrivacyInfoStatusDidContain];
}];
}
+ (void)handlePrivacyAgreeStatus {
//
// if(![[NSUserDefaults standardUserDefaults] boolForKey:@"agreeStatus"]){
//
[self showPrivacyInfoInWindow:[UIApplication sharedApplication].delegate.window];
// [[AMapNaviManagerConfig sharedConfig] updatePrivacyAgree:AMapPrivacyAgreeStatusDidAgree];
// }
}
+ (void)handlePrivacyAgreeStatusIn:(UIViewController*)targetVC {
if(![[NSUserDefaults standardUserDefaults] boolForKey:@"agreeStatus"]){
[self showPrivacyInfoInWindowWithVC:targetVC];
}
}
+ (void)showPrivacyInfoInWindowWithVC:(UIViewController *)window {
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.alignment = NSTextAlignmentLeft;
NSMutableAttributedString *privacyInfo = [[NSMutableAttributedString alloc] initWithString:@"\n感谢您一直以来的信任我们依据最新的监管要求更新了《隐私权政策》特向您说明如下\n1.为向您提供交易相关基本功能,我们会收集、使用必要的信息;\n2.基于您的明示授权,我们可能会获取您的位置(为您提供附近的店铺及优惠资讯等)等信息,您有权拒绝或取消授权;\n3.我们会采取业界先进的安全措施保护您的信息安全;\n4.未经您同意,我们不会从第三方处获取、共享或向提供您的信息;" attributes:@{
NSParagraphStyleAttributeName:paragraphStyle,
}];
[privacyInfo addAttribute:NSLinkAttributeName
value:@"《隐私权政策》"
range:[[privacyInfo string] rangeOfString:@"《隐私权政策》"]];
UIAlertController *privacyInfoController = [UIAlertController alertControllerWithTitle:@"温馨提示(隐私合规示例)" message:@"" preferredStyle:UIAlertControllerStyleAlert];
[privacyInfoController setValue:privacyInfo forKey:@"attributedMessage"];
UIAlertAction *agreeAllAction = [UIAlertAction actionWithTitle:@"同意(下次不提示)" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"agreeStatus"];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"usragreeStatus"];
[[NSUserDefaults standardUserDefaults] synchronize];
//SDK. since 8.1.0
[[AMapNaviManagerConfig sharedConfig] updatePrivacyAgree:AMapPrivacyAgreeStatusDidAgree];
[NSNotificationCenter.defaultCenter postNotificationName:@"ksAMapPrivacyDidUpdateNotification" object:nil];
}];
UIAlertAction *agreeAction = [UIAlertAction actionWithTitle:@"同意" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//SDK. since 8.1.0
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"usragreeStatus"];
[[NSUserDefaults standardUserDefaults] synchronize];
[[AMapNaviManagerConfig sharedConfig] updatePrivacyAgree:AMapPrivacyAgreeStatusDidAgree];
[NSNotificationCenter.defaultCenter postNotificationName:@"ksAMapPrivacyDidUpdateNotification" object:nil];
}];
UIAlertAction *notAgreeAction = [UIAlertAction actionWithTitle:@"不同意" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"agreeStatus"];
[[NSUserDefaults standardUserDefaults] synchronize];
//SDK. since 8.1.0
[[AMapNaviManagerConfig sharedConfig] updatePrivacyAgree:AMapPrivacyAgreeStatusNotAgree];
}];
[privacyInfoController addAction:agreeAllAction];
[privacyInfoController addAction:agreeAction];
[privacyInfoController addAction:notAgreeAction];
[window presentViewController:privacyInfoController animated:YES completion:^{
//AppSDK. since 8.1.0
[[AMapNaviManagerConfig sharedConfig] updatePrivacyShow:AMapPrivacyShowStatusDidShow privacyInfo:AMapPrivacyInfoStatusDidContain];
}];
}
@end

View File

@@ -1,22 +0,0 @@
//
// NaviPointAnnotation.h
// AMapNaviKit
//
// Created by 刘博 on 16/3/8.
// Copyright © 2016年 AutoNavi. All rights reserved.
//
#import <AMapNaviKit/MAMapKit.h>
typedef NS_ENUM(NSInteger, NaviPointAnnotationType)
{
NaviPointAnnotationStart,
NaviPointAnnotationWay,
NaviPointAnnotationEnd
};
@interface NaviPointAnnotation : MAPointAnnotation
@property (nonatomic, assign) NaviPointAnnotationType navPointType;
@end

View File

@@ -1,13 +0,0 @@
//
// NaviPointAnnotation.m
// AMapNaviKit
//
// Created by on 16/3/8.
// Copyright © 2016 AutoNavi. All rights reserved.
//
#import "NaviPointAnnotation.h"
@implementation NaviPointAnnotation
@end

View File

@@ -1,24 +0,0 @@
//
// SelectableOverlay.h
// officialDemo2D
//
// Created by yi chen on 14-5-8.
// Copyright (c) 2014年 AutoNavi. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <AMapNaviKit/MAMapKit.h>
/// 继承 MAPolyline自身就是 Polylinerenderer 用 self 初始化不会产生 overlay 不匹配警告
@interface SelectableOverlay : MAPolyline
@property (nonatomic, assign) NSInteger routeID;
@property (nonatomic, assign, getter = isSelected) BOOL selected;
@property (nonatomic, strong) UIColor *selectedColor;
@property (nonatomic, strong) UIColor *regularColor;
/// 用坐标数组和数量初始化(对应原来的 MAPolyline polylineWithCoordinates:count:
+ (instancetype)overlayWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
@end

View File

@@ -1,23 +0,0 @@
//
// SelectableOverlay.m
// officialDemo2D
//
// Created by yi chen on 14-5-8.
// Copyright (c) 2014 AutoNavi. All rights reserved.
//
#import "SelectableOverlay.h"
@implementation SelectableOverlay
+ (instancetype)overlayWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
{
// MAPolyline SelectableOverlay
SelectableOverlay *overlay = (SelectableOverlay *)[super polylineWithCoordinates:coords count:count];
overlay.selected = NO;
overlay.selectedColor = [UIColor colorWithRed:0.05 green:0.39 blue:0.9 alpha:0.8];
overlay.regularColor = [UIColor colorWithRed:0.5 green:0.6 blue:0.9 alpha:0.8];
return overlay;
}
@end

View File

@@ -1,32 +0,0 @@
//
// ABottomBarView.h
// AMapNavIOSSDK
//
// Created by admin on 2026/3/25.
//
#import <UIKit/UIKit.h>
#import "AMapNavSDKHeader.h"
NS_ASSUME_NONNULL_BEGIN
@class ABottomBarView;
@protocol ABottomBarViewDelegate <NSObject>
/// 点击「规划路线」按钮
- (void)bottomBarViewDidTapCalRoute:(ABottomBarView *)barView;
/// 输入框开始编辑(外部弹起搜索页)
- (void)bottomBarViewDidTapSearchField:(ABottomBarView *)barView;
@end
/// 底部搜索+规划路线栏
@interface ABottomBarView : UIView
@property (nonatomic, weak) id<ABottomBarViewDelegate> delegate;
/// 目的地文本(外部赋值后自动更新输入框)
@property (nonatomic, copy, nullable) NSString *destinationText;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,204 +0,0 @@
//
// ABottomBarView.m
// AMapNavIOSSDK
//
// Created by admin on 2026/3/25.
//
#import "ABottomBarView.h"
#import "AMapNavCommonUtil.h"
#import <Masonry/Masonry.h>
// 绿
static inline UIColor *ABottomBarThemeGreen(void) {
return [UIColor colorWithRed:0x1A/255.0 green:0x6E/255.0 blue:0x45/255.0 alpha:1.0];
}
@interface ABottomBarView () <UITextFieldDelegate>
///
@property (nonatomic, strong) UIView *cardView;
///
@property (nonatomic, strong) UIImageView *searchIconView;
///
@property (nonatomic, strong) UITextField *searchField;
/// 线
@property (nonatomic, strong) UIButton *calRouteButton;
@end
@implementation ABottomBarView
#pragma mark - Init
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
[self _buildUI];
}
return self;
}
- (instancetype)init {
return [self initWithFrame:CGRectZero];
}
#pragma mark - Build UI
- (void)_buildUI {
//
UIView *card = [[UIView alloc] init];
// card.backgroundColor = [UIColor colorWithRed:0.96 green:0.97 blue:0.98 alpha:0.96];
card.backgroundColor = [UIColor whiteColor];
card.layer.cornerRadius = 16;
//
card.layer.shadowColor = [UIColor blackColor].CGColor;
card.layer.shadowOpacity = 0.10;
card.layer.shadowRadius = 10;
card.layer.shadowOffset = CGSizeMake(0, -3);
card.layer.masksToBounds = NO;
[self addSubview:card];
self.cardView = card;
[card mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self);
}];
//
UIView *searchRow = [[UIView alloc] init];
searchRow.backgroundColor = [UIColor whiteColor];
searchRow.layer.cornerRadius = 5;
searchRow.layer.masksToBounds = YES;
searchRow.layer.borderColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.95 alpha:1].CGColor;
searchRow.layer.borderWidth = 1;
[card addSubview:searchRow];
[searchRow mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(card).offset(-18);
make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16);
make.height.mas_equalTo(50);
}];
//
UIImageView *searchIcon = [[UIImageView alloc] init];
searchIcon.contentMode = UIViewContentModeScaleAspectFit;
searchIcon.image = [AMapNavCommonUtil imageWithName3x:@"search_icon"];
[searchRow addSubview:searchIcon];
self.searchIconView = searchIcon;
[searchIcon mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(searchRow);
make.left.equalTo(searchRow).offset(12);
make.width.height.mas_equalTo(18);
}];
//
UITextField *field = [[UITextField alloc] init];
field.placeholder = @"请输入目的地,不输入则自动匹配附近成本最低加氢站";
field.font = [UIFont systemFontOfSize:14];
field.textColor = [UIColor colorWithWhite:0.1 alpha:1];
field.borderStyle = UITextBorderStyleNone;
field.backgroundColor = [UIColor clearColor];
field.delegate = self;
// placeholder
if (field.placeholder) {
field.attributedPlaceholder = [[NSAttributedString alloc]
initWithString:field.placeholder
attributes:@{NSForegroundColorAttributeName:
[UIColor colorWithWhite:0.65 alpha:1],
NSFontAttributeName:
[UIFont systemFontOfSize:13]}];
}
[searchRow addSubview:field];
self.searchField = field;
[field mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(searchRow);
make.left.equalTo(searchIcon.mas_right).offset(8);
make.right.equalTo(searchRow).offset(-12);
make.top.bottom.equalTo(searchRow);
}];
// 线
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.backgroundColor = ABottomBarThemeGreen();
btn.layer.cornerRadius = 24;
btn.layer.masksToBounds = YES;
//
UIImageView *routeIcon = [[UIImageView alloc] init];
routeIcon.contentMode = UIViewContentModeScaleAspectFit;
routeIcon.image = [AMapNavCommonUtil imageWithName3x:@"cal_ruoute_icon"];
routeIcon.userInteractionEnabled = NO;
[btn addSubview:routeIcon];
//
UILabel *titleLbl = [[UILabel alloc] init];
titleLbl.text = @"规划路线";
titleLbl.textColor = [UIColor whiteColor];
titleLbl.font = [UIFont boldSystemFontOfSize:16];
titleLbl.userInteractionEnabled = NO;
[btn addSubview:titleLbl];
//
[routeIcon mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(btn);
make.right.equalTo(titleLbl.mas_left).offset(-8);
make.width.height.mas_equalTo(22);
}];
[titleLbl mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(btn);
// titleLbl (22+8)/2 = 15pt
make.centerX.equalTo(btn).offset(15);
}];
[btn addTarget:self action:@selector(_onCalRouteTapped) forControlEvents:UIControlEventTouchUpInside];
[card addSubview:btn];
self.calRouteButton = btn;
CGFloat off_y = AMP_TabbarHeight;
#ifdef kAMapSDKDebugFlag
off_y = 0;
#endif
[btn mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(searchRow.mas_bottom).offset(20);
make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16);
make.height.mas_equalTo(48);
make.bottom.equalTo(card).offset(-40 - off_y);
}];
}
#pragma mark - Public
- (void)setDestinationText:(NSString *)destinationText {
_destinationText = destinationText;
self.searchField.text = destinationText;
}
#pragma mark - Actions
- (void)_onCalRouteTapped {
if ([self.delegate respondsToSelector:@selector(bottomBarViewDidTapCalRoute:)]) {
[self.delegate bottomBarViewDidTapCalRoute:self];
}
}
#pragma mark - UITextFieldDelegate
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
//
if ([self.delegate respondsToSelector:@selector(bottomBarViewDidTapSearchField:)]) {
[self.delegate bottomBarViewDidTapSearchField:self];
}
return NO;
}
@end

View File

@@ -1,21 +0,0 @@
//
// ACustomStepView.h
// AMapNavIOSSDK
//
// Created by admin on 2026/3/11.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface ACustomStepView : UIView
@property (nonatomic, readonly , assign) CGFloat value; // 当前值
- (instancetype)initWithValue:(CGFloat)currentValue maxValue:(CGFloat)maxValue min:(CGFloat)minValue;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,121 +0,0 @@
//
// ACustomStepView.m
// AMapNavIOSSDK
//
// Created by admin on 2026/3/11.
//
#import "ACustomStepView.h"
#import <Masonry/Masonry.h>
#define kStepValue 0.5
@interface ACustomStepView ()
@property CGFloat value;
@property CGFloat maxValue;
@property CGFloat minValue;
@end
@implementation ACustomStepView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor whiteColor];
self.layer.cornerRadius = 4;
self.layer.masksToBounds = YES;
self.clipsToBounds = YES;
self.layer.borderColor = [UIColor colorWithRed:225/255.0 green:225/255.0 blue:225/255.0 alpha:1].CGColor;
self.layer.borderWidth = 1;
[self setupSubviews];
self.value = 0; //
}
return self;
}
- (instancetype)initWithValue:(CGFloat)currentValue maxValue:(CGFloat)maxValue min:(CGFloat)minValue {
// self = [super initWithFrame:CGRectZero];
if (self) {
_value = currentValue;
_maxValue = maxValue;
_minValue = minValue;
}
return self;
}
- (void)setupSubviews {
//
UIButton *minusButton = [UIButton buttonWithType:UIButtonTypeSystem];
[minusButton setTitle:@"-" forState:UIControlStateNormal];
minusButton.titleLabel.font = [UIFont boldSystemFontOfSize:20];
[minusButton addTarget:self action:@selector(decrement:) forControlEvents:UIControlEventTouchUpInside];
[minusButton setTintColor:[UIColor colorWithRed:0x35/255.0 green:0x35/255.0 blue:0x35/255.0 alpha:1]];
[self addSubview:minusButton];
//
UIButton *plusButton = [UIButton buttonWithType:UIButtonTypeSystem];
[plusButton setTitle:@"+" forState:UIControlStateNormal];
plusButton.titleLabel.font = [UIFont boldSystemFontOfSize:20];
[plusButton setTintColor:[UIColor colorWithRed:0x35/255.0 green:0x35/255.0 blue:0x35/255.0 alpha:1]];
[plusButton addTarget:self action:@selector(increment:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:plusButton];
[plusButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.right.equalTo(self);
make.height.equalTo(@40);
}];
UIView * line = [[UIView alloc] init];
line.backgroundColor = [UIColor colorWithRed:230/255.0 green:230/255.0 blue:230/255.0 alpha:1];
[self addSubview:line];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self);
make.top.equalTo(plusButton.mas_bottom);
make.height.equalTo(@1);
}];
[minusButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self);
make.top.equalTo(plusButton.mas_bottom);
make.height.equalTo(plusButton);
}];
}
// 1
- (void)decrement:(UIButton *)sender {
if (self.value <= self.minValue) {
return;
}
if (self.value - kStepValue < self.minValue) {
self.value = self.minValue;
return;
}
self.value = self.value - kStepValue;
}
// 1
- (void)increment:(UIButton *)sender {
if (self.value >= self.maxValue) {
return;
}
if (self.value + kStepValue > self.maxValue) {
self.value = self.maxValue;
return;
}
self.value = self.value + kStepValue;
}
@end

View File

@@ -31,13 +31,7 @@ require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelpe
flutter_ios_podfile_setup flutter_ios_podfile_setup
target 'Runner' do target 'Runner' do
# use_frameworks! use_frameworks!
use_frameworks! :linkage => :static
pod 'AMapNavIOSSDK' , :path => './AMapNavIOSSDK'
## 本地仓库
# pod 'AMapNavIOSSDK' , :path => '../../../../demo/ANavDemo'
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do target 'RunnerTests' do

Some files were not shown because too many files have changed in this diff Show More