9 Commits

Author SHA1 Message Date
b462312c2e 项目说明 2026-04-24 09:38:45 +08:00
ec96a96be2 Merge branch 'dev_map' into dev
version 1.2.5
# Conflicts:
#	ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ASearchAddressController.m
#	ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/View/AStationDetailPopupView.m
2026-04-16 10:50:57 +08:00
xiaogg
0ba9547992 fix:优化完善; 2026-04-15 20:03:37 +08:00
c6e7616be2 fix 2026-04-15 10:06:58 +08:00
eae654c47e fix 2026-04-14 14:04:19 +08:00
f01875abb9 调整 2026-04-14 11:50:33 +08:00
881da166d1 调整 2026-04-13 17:48:37 +08:00
14b2e6b35c Merge branch 'dev_map' into dev 2026-04-13 16:54:07 +08:00
xiaogg
5c74c7ccc0 fix:优化完善; 2026-04-13 16:13:23 +08:00
48 changed files with 2201 additions and 152 deletions

65
ln_jq_app/CLAUDE.md Normal file
View File

@@ -0,0 +1,65 @@
# CLAUDE.md
Behavioral guidelines to reduce common LLM coding mistakes. Merge with project-specific instructions as needed.
**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.
## 1. Think Before Coding
**Don't assume. Don't hide confusion. Surface tradeoffs.**
Before implementing:
- State your assumptions explicitly. If uncertain, ask.
- If multiple interpretations exist, present them - don't pick silently.
- If a simpler approach exists, say so. Push back when warranted.
- If something is unclear, stop. Name what's confusing. Ask.
## 2. Simplicity First
**Minimum code that solves the problem. Nothing speculative.**
- No features beyond what was asked.
- No abstractions for single-use code.
- No "flexibility" or "configurability" that wasn't requested.
- No error handling for impossible scenarios.
- If you write 200 lines and it could be 50, rewrite it.
Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.
## 3. Surgical Changes
**Touch only what you must. Clean up only your own mess.**
When editing existing code:
- Don't "improve" adjacent code, comments, or formatting.
- Don't refactor things that aren't broken.
- Match existing style, even if you'd do it differently.
- If you notice unrelated dead code, mention it - don't delete it.
When your changes create orphans:
- Remove imports/variables/functions that YOUR changes made unused.
- Don't remove pre-existing dead code unless asked.
The test: Every changed line should trace directly to the user's request.
## 4. Goal-Driven Execution
**Define success criteria. Loop until verified.**
Transform tasks into verifiable goals:
- "Add validation" → "Write tests for invalid inputs, then make them pass"
- "Fix the bug" → "Write a test that reproduces it, then make it pass"
- "Refactor X" → "Ensure tests pass before and after"
For multi-step tasks, state a brief plan:
```
1. [Step] → verify: [check]
2. [Step] → verify: [check]
3. [Step] → verify: [check]
```
Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.
---
**These guidelines are working if:** fewer unnecessary changes in diffs, fewer rewrites due to overcomplication, and clarifying questions come before implementation rather than after mistakes.

View File

@@ -1,19 +1,49 @@
# ln_jq_app
# 加氢预约app
### 主要功能介绍
1. 主要给本公司的合作司机提供加氢预约和路线规划的功能 方便日常预约加氢能源量
2. 主要给本公司的加氢站点提供预约查看功能,根据预约量准备和实际消耗数量
3. 主要核心流程
司机登录->无绑定记录需绑定车牌->绑定后即可提交预约(可选择修改预约时间、加氢量、站点)
站点登录->操作司机预约工单->确认或者拒绝->新预约单会有广播提醒->站点状态更改会广播提醒司机用户
4. 当前版本号1.2.5+8
sdk配置dart 3.9.0+
加氢预约app
# 代码仓库说明
地址http://gitea.lnh2e.com/guyongliang/ln-ios.git
git tag 可查看所有已推送版本历史,都已做好标签
>生产测试分别对应不同的域名build的时候切换对应分支即可
origin/main 生产环境
origin/dev 测试环境
origin/dev_map 联调高德相关
# 项目结构介绍
1、登录页面分为司机端和站点端具体可以查看HomeController类中的getHomePage()函数,根据登录渠道的不同进入不同的菜单栏
2、全局搜索HttpService.to. 可以看到http相关设置、get post请求等
>lib/
├── common/ # 公共模块、项目配置
│ ├── styles/ # 样式配置
│ └── model/ # 数据模型
│ └──styles/theme.dart #域名切换功能配置、域名地址、相关key、主题色等
├── pages/ # 页面模块
│ ├── home/ # 跳转页面,区分跳转逻辑
│ ├── b_page/ # 站点端页面
│ ├── c_page/ # 司机端页面
│ └──base_widgets/NativePageIOS.dart #该类由原生android、ios 实现了高德相关功能
│ ├── login/ # 登录页面
│ ├── common/ # 公共页面
│ └── url_host/ # 域名切换功能页面
├── main.dart # 启动类
└── storage_service.dart # 缓存类存储枚举key
android jks
小羚羚
Ln123456.
高德key
安卓 92495660f7bc990cb475426c47c03b65
苹果:3ac08e5e14df9d7a52e98d40e21a0189
key:2cc1d822e313307fe311c3127a1deeb5
秘钥:0529b72df6bf0c577ff2182cb8b1d970
# 基本配置如下
安卓包名com.lingniu.driver
iOS包名com.lnkj.ln_jq_app
iOS包名com.lnkj.lnJqApp
>android jks别名密码
>小羚羚
>Ln123456.

View File

@@ -37,8 +37,8 @@ android {
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = 7
versionName = "1.2.4"
versionCode = 8
versionName = "1.2.5"
}
signingConfigs {

View File

@@ -61,7 +61,6 @@ import com.amap.api.services.geocoder.RegeocodeAddress;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.amap.api.services.route.BusRouteResult;
import com.amap.api.services.route.DrivePath;
import com.amap.api.services.route.DriveRouteResult;
import com.amap.api.services.route.RideRouteResult;
import com.amap.api.services.route.RouteSearch;
@@ -205,7 +204,9 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
endInput = new TextView(context);
endInput.setHint("请输入目的地,不输入则自动匹配推荐加氢站");
endInput.setTextSize(13);
endInput.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_search, 0, 0, 0);
endInput.setCompoundDrawablePadding(dp2px(8));
endInput.setTextSize(12);
endInput.setTextColor(Color.parseColor("#333333"));
endInput.setHintTextColor(Color.GRAY);
endInput.setPadding(dp2px(12), dp2px(12), dp2px(12), dp2px(12));
@@ -249,13 +250,33 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
View vSpace = new View(context);
searchArea.addView(vSpace, new LinearLayout.LayoutParams(1, dp2px(12)));
Button planBtn = new Button(context);
planBtn.setText("规划路线");
planBtn.setTextColor(Color.WHITE);
planBtn.setTypeface(Typeface.DEFAULT_BOLD);
planBtn.setBackground(getRoundedDrawable(Color.parseColor("#017143"), 99));
planBtn.setOnClickListener(v -> calculateRouteBeforeNavi());
searchArea.addView(planBtn, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp2px(48)));
// 创建自定义按钮布局
LinearLayout planBtnContainer = new LinearLayout(context);
planBtnContainer.setOrientation(LinearLayout.HORIZONTAL);
planBtnContainer.setGravity(Gravity.CENTER);
planBtnContainer.setBackground(getRoundedDrawable(Color.parseColor("#017143"), 99));
planBtnContainer.setPadding(0, 0, 0, 0);
// 添加图标
ImageView pathIcon = new ImageView(context);
pathIcon.setImageResource(R.drawable.ic_path);
pathIcon.setColorFilter(Color.WHITE);
LinearLayout.LayoutParams iconParams = new LinearLayout.LayoutParams(dp2px(20), dp2px(20));
iconParams.rightMargin = dp2px(6); // 图标和文字之间的间距
planBtnContainer.addView(pathIcon, iconParams);
// 添加文字
TextView planText = new TextView(context);
planText.setText("规划路线");
planText.setTextColor(Color.WHITE);
planText.setTextSize(14);
planText.setTypeface(Typeface.DEFAULT_BOLD);
planText.setGravity(Gravity.CENTER);
planBtnContainer.addView(planText);
// 设置点击事件
planBtnContainer.setOnClickListener(v -> calculateRouteBeforeNavi());
searchArea.addView(planBtnContainer, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp2px(40)));
bottomContainer.addView(searchArea);
@@ -378,8 +399,8 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
row1.setOrientation(LinearLayout.HORIZONTAL);
row1.setGravity(Gravity.CENTER_VERTICAL);
row1.setPadding(0, dp2px(8), 0, 0); // 增加行间距
tvDuration = createInfoItem(row1, R.drawable.ic_time, "预计时间:", "", 1.0f);
tvTollsFuel = createInfoItem(row1, R.drawable.ic_fuel, "加氢费用:", "", 1.0f);
tvDuration = createInfoItem(row1, R.drawable.ic_time, "预计时间:", "-", 1.0f);
tvTollsFuel = createInfoItem(row1, R.drawable.ic_fuel, "加氢费用:", "-", 1.0f);
routeInfoLayout.addView(row1);
// 第二行:里程 + 过路费
@@ -389,9 +410,9 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
row2.setPadding(0, dp2px(10), 0, 0); // 增加行间距
// 里程
tvDistance = createInfoItem(row2, R.drawable.ic_mileage, "行驶里程:", "", 1.0f);
tvDistance = createInfoItem(row2, R.drawable.ic_mileage, "行驶里程:", "-", 1.0f);
// 过路费
tvTolls = createInfoItem(row2, R.drawable.ic_toll, "过路费:", "", 1.0f);
tvTolls = createInfoItem(row2, R.drawable.ic_toll, "过路费:", "-", 1.0f);
routeInfoLayout.addView(row2);
//第三行
@@ -399,15 +420,15 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
row3.setOrientation(LinearLayout.HORIZONTAL);
row3.setGravity(Gravity.CENTER_VERTICAL);
row3.setPadding(0, dp2px(8), 0, 0); // 增加行间距
tvPerson = createInfoItem(row3, R.drawable.ic_person, "站联系人:", "", 1.0f);
tvPrice = createInfoItem(row3, R.drawable.ic_price, "加氢价格:", "", 1.0f);
tvPerson = createInfoItem(row3, R.drawable.ic_person, "站联系人:", "-", 1.0f);
tvPrice = createInfoItem(row3, R.drawable.ic_price, "加氢价格:", "-", 1.0f);
routeInfoLayout.addView(row3);
LinearLayout row4 = new LinearLayout(context);
row4.setOrientation(LinearLayout.HORIZONTAL);
row4.setGravity(Gravity.CENTER_VERTICAL);
row4.setPadding(0, dp2px(8), 0, 0); // 增加行间距
tvPhone = createInfoItem(row4, R.drawable.ic_phone, "联系方式:", "", 1.0f);
tvPhone = createInfoItem(row4, R.drawable.ic_phone, "联系方式:", "-", 1.0f);
routeInfoLayout.addView(row4);
@@ -432,6 +453,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
searchArea.setVisibility(View.VISIBLE);
planToggleBtn.setVisibility(View.VISIBLE);
mLocBtn.setVisibility(View.VISIBLE);
}
private boolean isGetInputtips = false;
@@ -450,6 +472,8 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
//如果是输入地址提示内容
if (isGetInputtips) {
truckRouteData = null;
RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(new LatLonPoint(startPoint.latitude, startPoint.longitude), new LatLonPoint(endPoint.latitude, endPoint.longitude));
RouteSearch.DriveRouteQuery query = new RouteSearch.DriveRouteQuery(fromAndTo, RouteSearch.DRIVING_SINGLE_DEFAULT, null, null, "");
routeSearch.calculateDriveRouteAsyn(query);
@@ -473,9 +497,19 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
@Override
public void run() {
String hydrogenCost = "-"; // 默认显示横线
String hydrogenPrice = "-"; // 默认显示横线
String liaisonName = "-";
String liaisonPhone = "-";
String startBusiness = "-";
String endBusiness = "-";
double distanceKm = 0;
String distanceKmStr = "-";
long durationMin = 0;
String durationMinStr = "-";
String tolls = "-";
if (rCode == AMapException.CODE_AMAP_SUCCESS && result != null && !result.getPaths().isEmpty()) {
DrivePath path = result.getPaths().get(0);
// 规划成功,显示详情面板,隐藏模式选择
if (detailPanel != null)
@@ -490,52 +524,61 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
tvStationName.setText(endName);
tvStationAddr.setText(endAddress);
DestinationSite destinationSite = truckRouteData.destinationSite;
double distanceKm = truckRouteData.pathDto.distance / 1000f;
long durationMin = truckRouteData.pathDto.duration / 60;
String tolls = truckRouteData.pathDto.tolls;
if (truckRouteData != null) {
PathDto pathDto = truckRouteData.pathDto;
if (pathDto != null) {
distanceKm = pathDto.distance / 1000f;
durationMin = pathDto.duration / 60;
tolls = pathDto.tolls + "";
distanceKmStr = String.format("%.1f", distanceKm) + "公里";
durationMinStr = durationMin + "分钟";
}
}
String hydrogenCost = "-"; // 默认显示横线
String hydrogenPrice = "-"; // 默认显示横线
String liaisonName = "-";
String liaisonPhone = "-";
String startBusiness = "-";
String endBusiness = "-";
try {
// 增加多级非空校验,防止点击搜索条目时崩溃
if (truckRouteData != null &&
truckRouteData.algorithmPath != null &&
truckRouteData.algorithmPath.hydrogenCost != null &&
!truckRouteData.algorithmPath.hydrogenCost.isEmpty()) {
hydrogenCost = truckRouteData.algorithmPath.hydrogenCost;
hydrogenCost = (isGetInputtips ? "--" : hydrogenCost) + "";
}
tvDuration.setText("预计时间:" + durationMin + "分钟");
tvDistance.setText("行驶里程:" + String.format("%.1f", distanceKm) + "公里");
tvTolls.setText("过路费:" + tolls + "");
tvTollsFuel.setText("预计加氢费用:" + (isGetInputtips ? "--" : hydrogenCost) + "");
tvDuration.setText("预计时间:" + durationMinStr);
tvDistance.setText("行驶里程:" + distanceKmStr);
tvTolls.setText("过路费:" + tolls);
tvTollsFuel.setText("预计加氢费用:" + hydrogenCost);
if (truckRouteData != null) {
DestinationSite destinationSite = truckRouteData.destinationSite;
if (destinationSite != null) {
startBusiness = destinationSite.startBusiness;
endBusiness = destinationSite.endBusiness;
hydrogenPrice = destinationSite.hydrogenPrice;
hydrogenPrice = destinationSite.hydrogenPrice + "/L";
liaisonName = destinationSite.liaisonName;
liaisonPhone = destinationSite.liaisonPhone;
//开始结束时间
startBusiness = startBusiness + "-" + endBusiness;
}
}
tvBusinessHours.setText("营业时间:" + startBusiness + "-" + endBusiness);
tvBusinessHours.setText("营业时间:" + startBusiness);
if (liaisonName != null && liaisonName.length() > 5) {
liaisonName = liaisonName.substring(0, 5) + "...";
}
tvPerson.setText("站联系人:" + liaisonName);
tvPrice.setText("加氢价格:" + hydrogenPrice);
tvPhone.setText("联系方式:" + liaisonPhone);
isGetInputtips = false;
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(endPoint, 13f));
} catch (Exception e) {
Log.e(TAG, "获取加氢费用失败", e);
}
} else {
// 规划失败回退面板
searchArea.setVisibility(View.VISIBLE);
@@ -628,6 +671,11 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
// 检查途径点数量,决定使用哪种导航方式
int wayPointsCount = waysPoiIds.size();
Log.d(TAG, "途经点数量: " + wayPointsCount);
//如果是输入地址提示内容,不判断途经点
if (isGetInputtips) {
wayPointsCount = 0;
}
if (wayPointsCount > 3) {
// 途经点超过3个跳转到 NavigationActivity
Intent intent = new Intent(mContext, NavigationActivity.class);
@@ -694,13 +742,11 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
* 获取货车路线算法信息
*/
private void fetchTruckRouteAlgorithm(AMapLocation loc) {
showLoading();
if (plateNumber == null || plateNumber.isEmpty()) {
Toast.makeText(mActivity,"请先绑定车辆后进行导航",Toast.LENGTH_SHORT).show();
return;
}
showLoading();
try {
JSONObject json = new JSONObject();
json.put("longitude", String.valueOf(loc.getLongitude()));
@@ -820,11 +866,13 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
if (detailPanel != null && detailPanel.getVisibility() == View.VISIBLE) {
resetView();
}
modeMenu.setVisibility(View.GONE);
});
aMap.setOnPOIClickListener(poi -> {
if (detailPanel != null && detailPanel.getVisibility() == View.VISIBLE) {
resetView();
}
modeMenu.setVisibility(View.GONE);
});
MyLocationStyle myLocationStyle = new MyLocationStyle();
@@ -882,7 +930,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
// 简化逻辑,直接设置文本
endInput.post(() -> {
try {
endInput.setText(district != null && !district.isEmpty() ? name + " " + district : name);
endInput.setText(district != null && !district.isEmpty() ? (name + " " + district ): name);
} catch (Exception e) {
Log.e(TAG, "Failed to set text to endInput", e);
}
@@ -1107,6 +1155,9 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
// 更新 UI 和 业务逻辑
endName = marker.getTitle();
isUserSelectedDestination = true; // 标识用户手动选择了目的地
isGetInputtips = false;
endInput.setText("");
// 需要传入当前位置以便接口计算路线
if (mlocationClient != null && mlocationClient.getLastKnownLocation() != null) {
@@ -1251,9 +1302,12 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
// 文本内容
TextView tv = new TextView(mContext);
tv.setText(label + value);
tv.setTextSize(14);
tv.setTextColor(Color.parseColor("#333333"));
tv.setTextSize(12);
tv.setTextColor(Color.parseColor("#ff1d2129"));
tv.setPadding(dp2px(6), 0, 0, 0);
LinearLayout.LayoutParams tvParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f);
@@ -1266,23 +1320,6 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
return tv; // 返回TextView以便后续更新内容
}
// 过载一个不需要weight的方法给第一行使用
private TextView createInfoItem(LinearLayout parent, int iconRes, String label, String value) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ImageView iv = new ImageView(mContext);
iv.setImageResource(iconRes);
iv.setColorFilter(Color.parseColor("#017143"));
parent.addView(iv, new LinearLayout.LayoutParams(dp2px(18), dp2px(18)));
TextView tv = new TextView(mContext);
tv.setTextSize(14);
tv.setTextColor(Color.parseColor("#333333"));
tv.setPadding(dp2px(6), 0, 0, 0);
parent.addView(tv, params);
return tv;
}
// 创建模式菜单视图
private View createModeMenu(Context context) {
@@ -1305,9 +1342,9 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
TextView item3 = createMenuItem(context, "加氢规划模式", true);
item3.setOnClickListener(v -> switchMode("加氢规划"));
menu.addView(item1);
menu.addView(item2);
menu.addView(item3);
menu.addView(item2);
menu.addView(item1);
return menu;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,40 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:strokeWidth="1"
android:pathData="M8,14.667C10.946,14.667 13.333,12.496 13.333,9.818C13.333,7.192 11.556,4.364 8,1.333C4.444,4.364 2.667,7.192 2.667,9.818C2.667,12.496 5.054,14.667 8,14.667Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"/>
<path
android:strokeWidth="1"
android:pathData="M6.286,6.333L8,8.123L9.714,6.333"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M6,8.719H10"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M6,10.509H10"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M8,8.719V12"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 781 B

View File

@@ -0,0 +1,41 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:strokeWidth="1"
android:pathData="M3.667,1.375L2,13.375"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M12.333,1.375L13.988,13.36"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M8,1.375V3.375"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M8,11.042V13.375"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M8,6.042V8.375"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
</vector>

View File

@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group>
<clip-path
android:pathData="M0,0h24v24h-24z"/>
<path
android:pathData="M6.518,10.241C4.181,10.241 2.29,12.135 2.29,14.469C2.29,16.804 6.518,21.684 6.518,21.684C6.518,21.684 10.746,16.806 10.746,14.469C10.746,12.133 8.853,10.241 6.518,10.241ZM6.518,15.616C5.853,15.616 5.313,15.077 5.313,14.411C5.313,13.745 5.853,13.206 6.518,13.206C7.184,13.206 7.723,13.745 7.723,14.411C7.723,15.077 7.181,15.616 6.518,15.616ZM19.676,2.301C18.567,2.301 17.67,3.198 17.67,4.307C17.67,5.416 19.676,7.729 19.676,7.729C19.676,7.729 21.682,5.416 21.682,4.307C21.682,3.198 20.785,2.301 19.676,2.301ZM19.676,4.851C19.36,4.851 19.104,4.595 19.104,4.279C19.104,3.963 19.36,3.707 19.676,3.707C19.992,3.707 20.248,3.963 20.248,4.279C20.246,4.595 19.99,4.851 19.676,4.851ZM18.026,13.185C17.386,12.813 16.629,12.674 15.898,12.538C14.845,12.344 14.196,12.191 14.074,11.72C14.051,11.627 14.037,11.493 14.156,11.291C14.325,11.005 14.855,10.422 16.519,9.735C16.993,9.539 17.449,9.382 17.801,9.27C18.168,9.153 18.393,8.768 18.296,8.395C18.199,8.019 17.812,7.792 17.442,7.909C17.056,8.03 16.543,8.205 15.999,8.43C14.431,9.074 13.404,9.798 12.945,10.579C12.663,11.057 12.584,11.575 12.713,12.077C12.877,12.709 13.303,13.185 13.978,13.485C14.482,13.71 15.073,13.818 15.642,13.923C16.256,14.036 16.889,14.153 17.318,14.402C17.597,14.563 17.888,14.819 17.916,15.487C17.958,16.427 16.88,17.448 14.881,18.367C13.833,18.848 12.764,19.192 12.099,19.385C11.729,19.493 11.5,19.869 11.589,20.244C11.68,20.625 12.064,20.86 12.441,20.752C13.144,20.55 14.295,20.183 15.45,19.654C16.547,19.152 17.424,18.606 18.054,18.032C18.938,17.228 19.364,16.349 19.322,15.426C19.278,14.413 18.842,13.661 18.026,13.185Z"
android:fillColor="#ffffff"/>
</group>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 762 B

View File

@@ -0,0 +1,20 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:strokeWidth="1"
android:pathData="M8,6.042C9.289,6.042 10.333,4.997 10.333,3.708C10.333,2.42 9.289,1.375 8,1.375C6.711,1.375 5.667,2.42 5.667,3.708C5.667,4.997 6.711,6.042 8,6.042Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M2,12.975V13.375H14V12.975C14,11.481 14,10.735 13.709,10.164C13.454,9.663 13.046,9.255 12.544,8.999C11.974,8.708 11.227,8.708 9.733,8.708H6.267C4.773,8.708 4.026,8.708 3.456,8.999C2.954,9.255 2.546,9.663 2.291,10.164C2,10.735 2,11.481 2,12.975Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 865 B

View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:strokeWidth="1"
android:pathData="M5.665,1.937C5.908,1.937 6.131,2.068 6.248,2.28L7.064,3.749C7.171,3.941 7.176,4.174 7.077,4.371L6.292,5.942C6.292,5.942 6.519,7.112 7.472,8.065C8.425,9.018 9.591,9.242 9.591,9.242L11.162,8.456C11.359,8.358 11.592,8.363 11.785,8.47L13.258,9.289C13.469,9.407 13.6,9.63 13.6,9.872V11.563C13.6,12.424 12.8,13.046 11.984,12.771C10.308,12.205 7.707,11.128 6.058,9.479C4.409,7.831 3.332,5.229 2.767,3.553C2.491,2.737 3.113,1.937 3.975,1.937H5.665Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,40 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:strokeWidth="1"
android:pathData="M8,14.042C11.682,14.042 14.667,11.057 14.667,7.375C14.667,3.693 11.682,0.708 8,0.708C4.318,0.708 1.333,3.693 1.333,7.375C1.333,11.057 4.318,14.042 8,14.042Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"/>
<path
android:strokeWidth="1"
android:pathData="M6,6.708H10"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M6,8.708H10"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M8.003,6.708V10.708"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M10,4.375L8,6.375L6,4.375"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
</vector>

View File

@@ -0,0 +1,26 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="18dp"
android:height="18dp"
android:viewportWidth="18"
android:viewportHeight="18">
<path
android:strokeWidth="1"
android:pathData="M7.875,14.5C11.396,14.5 14.25,11.646 14.25,8.125C14.25,4.604 11.396,1.75 7.875,1.75C4.354,1.75 1.5,4.604 1.5,8.125C1.5,11.646 4.354,14.5 7.875,14.5Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#4E5969"/>
<path
android:strokeWidth="1"
android:pathData="M9.997,5.629C9.454,5.086 8.704,4.75 7.875,4.75C7.047,4.75 6.297,5.086 5.754,5.629"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#4E5969"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M12.458,12.707L15.64,15.889"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#4E5969"
android:strokeLineCap="round"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:strokeWidth="1"
android:pathData="M8,14.042C11.682,14.042 14.667,11.057 14.667,7.375C14.667,3.693 11.682,0.708 8,0.708C4.318,0.708 1.333,3.693 1.333,7.375C1.333,11.057 4.318,14.042 8,14.042Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"/>
<path
android:strokeWidth="1"
android:pathData="M8.003,3.375L8.003,7.378L10.829,10.204"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 791 B

View File

@@ -0,0 +1,37 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:strokeWidth="1"
android:pathData="M1.333,2.042H3.667C3.667,2.042 4,3.708 5.667,3.708C7.333,3.708 7.667,2.042 7.667,2.042H14.667V12.708H7.667C7.667,12.708 7.333,11.042 5.667,11.042C4,11.042 3.667,12.708 3.667,12.708H1.333V2.042Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M5.667,5.708V6.375"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M5.667,8.375V9.042"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M8.333,6.375H12"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M8.333,8.375H12"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 909 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 B

View File

@@ -0,0 +1,30 @@
//
// AAddHPopView.h
// AMapNavIOSSDK
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/**
* 气泡弹框视图
*
* 用法:
* AAddHPopView *pop = [[AAddHPopView alloc] init];
* [pop showInView:self.view sourceView:addHbtn];
*
* - 点击气泡外部自动消失
* - 箭头在右下角45度指向 sourceView 中心
*/
@interface AAddHPopView : UIView
/// 展示气泡sourceView 为箭头指向的锚定按钮(坐标系属于 view
- (void)showInView:(UIView *)view sourceView:(UIView *)sourceView;
/// 手动消失(点击空白处会自动调用)
- (void)dismiss;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,359 @@
//
// AAddHPopView.m
// AMapNavIOSSDK
//
#import "AAddHPopView.h"
#import <Masonry/Masonry.h>
#import "UIColor+ANavMap.h"
//
static const CGFloat kBubbleWidth = 200.f; //
static const CGFloat kHeaderHeight = 50.f; // 绿
static const CGFloat kOptionHeight = 60.f; //
static const CGFloat kArrowWidth = 50.f; // aw = ah*2 使45
static const CGFloat kArrowHeight = 15.f; //
static const CGFloat kBubbleRadius = 15.f; //
static const CGFloat kBubbleGap = 5.f; // sourceView
static const CGFloat kScreenPadding = 15.f; //
// +
@interface _ABubbleContainerView : UIView
/// X view showInView
@property (nonatomic, assign) CGFloat arrowCenterX;
@end
@implementation _ABubbleContainerView
- (instancetype)init {
self = [super init];
if (self) {
self.backgroundColor = [UIColor clearColor];
_arrowCenterX = kBubbleWidth / 2.f;
}
return self;
}
- (void)setArrowCenterX:(CGFloat)arrowCenterX {
_arrowCenterX = arrowCenterX;
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
CGFloat bw = kBubbleWidth; // 160
CGFloat bh = kHeaderHeight + kOptionHeight * 2.f; // 150
CGFloat r = kBubbleRadius; // 10
CGFloat aw = kArrowWidth; // 16
CGFloat ah = kArrowHeight; // 10
// 45
// : (arrowX-aw/2, bh) (arrowX, bh)
// : (arrowX + ah, bh + ah) 45
CGFloat arrowX = bw - 15.f; // X
CGFloat arrowTipX = arrowX + ah; // Xah = 45
CGFloat arrowTipY = bh + ah; // Yah = 45
UIBezierPath *path = [UIBezierPath bezierPath];
//
[path moveToPoint:CGPointMake(r, 0)];
[path addLineToPoint:CGPointMake(bw - r, 0)];
[path addArcWithCenter:CGPointMake(bw - r, r) radius:r
startAngle:-M_PI_2 endAngle:0 clockwise:YES];
//
[path addLineToPoint:CGPointMake(bw, bh - r)];
[path addArcWithCenter:CGPointMake(bw - r, bh - r) radius:r
startAngle:0 endAngle:M_PI_2 clockwise:YES];
//
[path addLineToPoint:CGPointMake(arrowX, bh)];
// 45
[path addLineToPoint:CGPointMake(arrowTipX, arrowTipY)];
//
[path addLineToPoint:CGPointMake(arrowX - ah, bh)];
//
[path addArcWithCenter:CGPointMake(r, bh - r) radius:r
startAngle:M_PI_2 endAngle:M_PI clockwise:YES];
//
[path addLineToPoint:CGPointMake(0, r)];
[path addArcWithCenter:CGPointMake(r, r) radius:r
startAngle:M_PI endAngle:-M_PI_2 clockwise:YES];
[path closePath];
// +
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);
CGContextSetShadowWithColor(ctx, CGSizeMake(0, 3), 10.f,
[[UIColor blackColor] colorWithAlphaComponent:0.15f].CGColor);
[[UIColor whiteColor] setFill];
[path fill];
CGContextRestoreGState(ctx);
[[UIColor whiteColor] setFill];
[path fill];
//
_arrowTipX = arrowTipX;
_arrowTipY = arrowTipY;
}
// 访
static CGFloat _arrowTipX = 0;
static CGFloat _arrowTipY = 0;
@end
// AAddHPopView
@interface AAddHPopView ()
@property (nonatomic, strong) _ABubbleContainerView *bubbleContainer;
@property (nonatomic, strong) UIView *headerView;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIView *separatorLine1;
@property (nonatomic, strong) UILabel *option1Label;
@property (nonatomic, strong) UIView *separatorLine2;
@property (nonatomic, strong) UILabel *option2Label;
@end
@implementation AAddHPopView
#pragma mark - Init
- (instancetype)init {
return [self initWithFrame:CGRectZero];
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self p_setupUI];
}
return self;
}
#pragma mark - Setup UI
- (void)p_setupUI {
self.backgroundColor = [UIColor clearColor];
// self
UITapGestureRecognizer *bgTap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(dismiss)];
bgTap.cancelsTouchesInView = NO;
[self addGestureRecognizer:bgTap];
//
[self addSubview:self.bubbleContainer];
// header绿
[self.bubbleContainer addSubview:self.headerView];
[self.headerView addSubview:self.titleLabel];
// 线 1
[self.bubbleContainer addSubview:self.separatorLine1];
// 1
[self.bubbleContainer addSubview:self.option1Label];
// 线 2
[self.bubbleContainer addSubview:self.separatorLine2];
// 2
[self.bubbleContainer addSubview:self.option2Label];
// bgTap
UITapGestureRecognizer *bubbleTap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(p_bubbleTapped)];
[self.bubbleContainer addGestureRecognizer:bubbleTap];
// Masonry bubbleContainer
// kBubbleWidth160
[self.headerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.equalTo(self.bubbleContainer);
make.width.mas_equalTo(kBubbleWidth);
make.height.mas_equalTo(kHeaderHeight);
}];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.headerView);
}];
[self.separatorLine1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.headerView.mas_bottom);
make.left.mas_equalTo(@0);
make.width.mas_equalTo(kBubbleWidth);
make.height.mas_equalTo(0.5);
}];
[self.option1Label mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.separatorLine1.mas_bottom);
make.left.mas_equalTo(@0);
make.width.mas_equalTo(kBubbleWidth);
make.height.mas_equalTo(kOptionHeight);
}];
[self.separatorLine2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.option1Label.mas_bottom);
make.left.mas_equalTo(@0);
make.width.mas_equalTo(kBubbleWidth);
make.height.mas_equalTo(0.5);
}];
[self.option2Label mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.separatorLine2.mas_bottom);
make.left.mas_equalTo(@0);
make.width.mas_equalTo(kBubbleWidth);
make.height.mas_equalTo(kOptionHeight);
}];
}
#pragma mark - Show / Dismiss
- (void)showInView:(UIView *)view sourceView:(UIView *)sourceView {
self.frame = view.bounds;
[view addSubview:self];
// sourceView view frame
CGRect srcFrame = [sourceView convertRect:sourceView.bounds toView:view];
//
CGFloat containerW = kBubbleWidth; // 160
CGFloat containerH = kHeaderHeight + kOptionHeight * 2.f; // 150
CGFloat ah = kArrowHeight; // 16
// bubbleContainer
// drawRect arrowX = bw - 35, arrowTipX = arrowX + ah
CGFloat arrowX_inContainer = containerW - 25.f; // X
CGFloat arrowTipX_inContainer = arrowX_inContainer + ah; // X45
CGFloat arrowTipY_inContainer = containerH + ah; // Y
//
CGFloat srcCenterX = CGRectGetMidX(srcFrame);
CGFloat srcCenterY = CGRectGetMidY(srcFrame);
//
CGFloat containerX = srcCenterX - arrowTipX_inContainer;
containerX = MAX(kScreenPadding, MIN(containerX, view.bounds.size.width - containerW - kScreenPadding));
//
CGFloat containerY = srcCenterY - arrowTipY_inContainer;
containerY = MAX(kScreenPadding, containerY);
self.bubbleContainer.bounds = CGRectMake(0, 0, containerW, containerH + ah);
//
self.bubbleContainer.layer.anchorPoint = CGPointMake(arrowTipX_inContainer / containerW,
arrowTipY_inContainer / (containerH + ah));
self.bubbleContainer.center = CGPointMake(srcCenterX - 25, srcCenterY - 20);
//
self.alpha = 0.f;
self.bubbleContainer.transform = CGAffineTransformMakeScale(0.85f, 0.85f);
[UIView animateWithDuration:0.25f
delay:0.f
usingSpringWithDamping:0.72f
initialSpringVelocity:0.3f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.alpha = 1.f;
self.bubbleContainer.transform = CGAffineTransformIdentity;
} completion:nil];
}
- (void)dismiss {
[UIView animateWithDuration:0.18f
delay:0.f
options:UIViewAnimationOptionCurveEaseIn
animations:^{
self.alpha = 0.f;
self.bubbleContainer.transform = CGAffineTransformMakeScale(0.85f, 0.85f);
} completion:^(BOOL finished) {
[self removeFromSuperview];
}];
}
#pragma mark - Private Actions
- (void)p_bubbleTapped {
//
}
#pragma mark - Lazy Load
- (_ABubbleContainerView *)bubbleContainer {
if (!_bubbleContainer) {
_bubbleContainer = [[_ABubbleContainerView alloc] init];
}
return _bubbleContainer;
}
- (UIView *)headerView {
if (!_headerView) {
_headerView = [[UIView alloc] init];
_headerView.backgroundColor = [UIColor hp_colorWithRGBHex:0x1BA855];
if (@available(iOS 11.0, *)) {
_headerView.layer.cornerRadius = kBubbleRadius;
_headerView.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner;
_headerView.clipsToBounds = YES;
}
}
return _headerView;
}
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.text = @"加氢规划模式";
_titleLabel.textColor = [UIColor whiteColor];
_titleLabel.font = [UIFont boldSystemFontOfSize:15.f];
_titleLabel.textAlignment = NSTextAlignmentCenter;
}
return _titleLabel;
}
- (UIView *)separatorLine1 {
if (!_separatorLine1) {
_separatorLine1 = [[UIView alloc] init];
_separatorLine1.backgroundColor = [UIColor colorWithWhite:0.88f alpha:1.f];
}
return _separatorLine1;
}
- (UILabel *)option1Label {
if (!_option1Label) {
_option1Label = [[UILabel alloc] init];
_option1Label.text = @"送货规划模式";
_option1Label.textColor = [UIColor hp_colorWithRGBHex:0xC9CDD4];
_option1Label.font = [UIFont boldSystemFontOfSize:14.f];
_option1Label.textAlignment = NSTextAlignmentCenter;
}
return _option1Label;
}
- (UIView *)separatorLine2 {
if (!_separatorLine2) {
_separatorLine2 = [[UIView alloc] init];
_separatorLine2.backgroundColor = [UIColor colorWithWhite:0.88f alpha:1.f];
}
return _separatorLine2;
}
- (UILabel *)option2Label {
if (!_option2Label) {
_option2Label = [[UILabel alloc] init];
_option2Label.text = @"成本计算模式";
_option2Label.textColor = [UIColor hp_colorWithRGBHex:0xC9CDD4];
_option2Label.font = [UIFont boldSystemFontOfSize:14.f];
_option2Label.textAlignment = NSTextAlignmentCenter;
}
return _option2Label;
}
@end

View File

@@ -0,0 +1,16 @@
//
// ACustomNaviDriveController.h
// AMapNavIOSSDK
//
// Created by admin on 2026/4/11.
//
#import "ABaseViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface ACustomNaviDriveController : ABaseViewController
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,22 @@
//
// ACustomNaviDriveController.m
// AMapNavIOSSDK
//
// Created by admin on 2026/4/11.
//
#import "ACustomNaviDriveController.h"
@interface ACustomNaviDriveController ()
@end
@implementation ACustomNaviDriveController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
@end

View File

@@ -21,8 +21,8 @@
NS_ASSUME_NONNULL_BEGIN
@interface ARoutePlaneController : ABaseViewController
@interface ARoutePlaneController : ABaseViewController<AMapNaviDriveDataRepresentable>
@property (nonatomic , strong) AMapNaviDriveView * driveView;
@end
NS_ASSUME_NONNULL_END

View File

@@ -18,7 +18,7 @@
#import "AMapPrivacyUtility.h"
#import "AStationDetailPopupController.h"
#import "AStationDetailPopupView.h"
#define kRouteIndicatorViewHeight 64.f
@@ -26,8 +26,9 @@
#import "AMapNavHttpUtil.h"
#import "ACustomStepView.h"
#import "ABottomBarView.h"
#import "AAddHPopView.h"
@interface ARoutePlaneController ()<MAMapViewDelegate, AMapNaviDriveManagerDelegate,AMapNaviCompositeManagerDelegate , AMapLocationManagerDelegate , UITextFieldDelegate , AStationDetailPopupDelegate, ABottomBarViewDelegate>
@interface ARoutePlaneController ()<MAMapViewDelegate, AMapNaviDriveManagerDelegate,AMapNaviCompositeManagerDelegate , AMapLocationManagerDelegate , UITextFieldDelegate , AStationDetailPopupViewDelegate, ABottomBarViewDelegate>
@property (nonatomic, strong) UITextField *textField;
/// +线
@@ -65,11 +66,16 @@
@property (nonatomic , strong)ACustomStepView * stepView;
///
@property (nonatomic , strong)AStationDetailPopupController * stationDetailPopup;
@property (nonatomic , strong)AStationDetailPopupView * stationDetailPopup;
@property (nonatomic, strong) ANavPointModel *pointModel; //
@property (nonatomic, strong) ATripCalcDataModel * tjdPathInfoModel;//
@property (nonatomic, strong) CLLocationManager * locationManager;
///
@property (nonatomic, weak) UIButton *addHBtn;
@property (nonatomic ,strong)MAAnnotationView * currAnnotionView;
@end
@implementation ARoutePlaneController
@@ -156,6 +162,8 @@
-(void)requestRoutePathWithParms:(NSDictionary*)dic completeHandle:(void(^)(ATripCalcDataModel * tjd))blk {
///
self.tjdPathInfoModel = nil;
NSString * token = [[NSUserDefaults standardUserDefaults]valueForKey:@"flutter.token"];
NSString * carNo = [[NSUserDefaults standardUserDefaults]valueForKey:@"flutter.plateNumber"];
@@ -279,7 +287,8 @@
[bottomBar mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.view);
make.bottom.equalTo(self.view);
// make.bottom.equalTo(self.view).offset(-AMP_TabbarHeight - 13);
make.bottom.equalTo(self.view).offset(0);
}];
// startTf / dstTf
@@ -319,25 +328,55 @@
[stepView addObserver:self forKeyPath:@"value" options:NSKeyValueObservingOptionNew context:nil];
self.stepView = stepView;
stepView.hidden = YES;
///
UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setImage:[AMapNavCommonUtil imageWithName3x:@"my_location_icon"] forState:UIControlStateNormal];
btn.backgroundColor = [UIColor lightGrayColor];
[btn setBackgroundImage:[AMapNavCommonUtil imageWithName3x:@"my_location_icon"] forState:UIControlStateNormal];
btn.backgroundColor = [UIColor whiteColor];
btn.titleLabel.font = [UIFont systemFontOfSize:14];
btn.layer.cornerRadius = 20;
btn.layer.cornerRadius = 22;
[btn addTarget:self action:@selector(updateUserLocalAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
[btn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.view).offset(-10);
make.width.height.equalTo(@40);
make.bottom.equalTo(bottomBar.mas_top).offset(-85);
make.width.height.equalTo(@44);
make.bottom.equalTo(bottomBar.mas_top).offset(-105);
}];
///
UIButton *addHbtn = [UIButton buttonWithType:UIButtonTypeCustom];
addHbtn.backgroundColor = [UIColor hp_colorWithRGBHex:0x017137];
addHbtn.titleLabel.numberOfLines = 2;
[addHbtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[addHbtn setTitle:@"加氢规划" forState:UIControlStateNormal];
addHbtn.titleLabel.font = [UIFont boldSystemFontOfSize:11];
addHbtn.titleEdgeInsets = UIEdgeInsetsMake(0, 3, 0, 3);
addHbtn.layer.cornerRadius = 22;
[addHbtn addTarget:self action:@selector(addHbtnAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:addHbtn];
[addHbtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.view).offset(-10);
make.width.height.equalTo(@44);
make.bottom.equalTo(btn.mas_top).offset(-25);
}];
self.addHBtn = addHbtn;
}
- (void)addHbtnAction:(UIButton *)sender {
//
AAddHPopView *popView = [[AAddHPopView alloc] init];
[popView showInView:self.view sourceView:sender];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"value"]) {
self.mapView.zoomLevel = [change[NSKeyValueChangeNewKey] doubleValue];
@@ -363,6 +402,7 @@
self.mapView.userTrackingMode = MAUserTrackingModeFollowWithHeading;
self.mapView.desiredAccuracy = kCLLocationAccuracyNearestTenMeters; //
_mapView.showsScale= YES;
_mapView.showsCompass = NO;
_mapView.logoCenter = CGPointMake(CGRectGetWidth(self.view.bounds)-55, 450);
self.mapView.zoomLevel = 11;
@@ -389,7 +429,7 @@
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(self.latitude, self.longitude);
[_mapView setCenterCoordinate:coord animated:YES];
// [_mapView setZoomLevel:10 animated:YES];
[_mapView setZoomLevel:15.0 animated:YES];
} else {
//
[_mapView setUserTrackingMode:MAUserTrackingModeFollow animated:YES];
@@ -508,7 +548,7 @@
0,
0,
0);
strategy = AMapNaviDrivingStrategyMultipleDefault;//使
strategy = AMapNaviDrivingStrategyMultipleDefault;//使DRIVING_MULTIPLE_ROUTES_DEFAULT
id delegate = [AMapNaviDriveManager sharedInstance].delegate;
if (!delegate) {
@@ -780,6 +820,7 @@
[config setNeedCalculateRouteWhenPresent:NO];//
[config setMultipleRouteNaviMode:NO];//线
// [config setNeedDestoryDriveManagerInstanceWhenDismiss:NO];
[config setShowDrivingStrategyPreferenceView:NO];
[self.compositeManager presentRoutePlanViewControllerWithOptions:config];
}
@@ -797,6 +838,8 @@
// [config setMultipleRouteNaviMode:NO];//线
// [config setNeedDestoryDriveManagerInstanceWhenDismiss:NO];
// [config setShowDrivingStrategyPreferenceView:NO];
[self.compositeManager presentRoutePlanViewControllerWithOptions:config];
}
@@ -978,6 +1021,7 @@
}
- (void)mapView:(MAMapView *)mapView didSelectAnnotationView:(MAAnnotationView *)view {
self.currAnnotionView = view;
id pointAnnotation = view.annotation;
if ([pointAnnotation isMemberOfClass:ACustomPointAnnotation.class]) {
@@ -995,9 +1039,13 @@
[self updateUIWithData:aoi textField:self.dstTf];
///
//
[self willRequestTJDInfo];
//
self.bottomBarView.destinationText = aoi.name;
// self.bottomBarView.destinationText = aoi.name;
self.bottomBarView.destinationText = nil;
}
}
@@ -1009,6 +1057,7 @@
self.dstPoi = nil;
self.dstTf.text = nil;
self.bottomBarView.destinationText = nil;
self.currAnnotionView = nil;
}
}
@@ -1056,6 +1105,7 @@
AMapPOI *_dstPoi = self.dstPoi ? self.dstPoi : self.defaultDstPoi;
if (!_dstPoi) {
[AMapNavCommonUtil showMsg:@"请先选择目的地"];
return;
}
@@ -1066,9 +1116,19 @@
navPoint.stationID = _dstPoi.uid;
self.pointModel = navPoint;
if (self.stationDetailPopup) {
[self.stationDetailPopup resetUI];
}
///_stationID 线
if (!navPoint.stationID) {
[self gd_calPathWithNoStationId:navPoint];
// [self gd_calPathWithNoStationId:navPoint];
ANavPointModel * model = [ANavPointModel new];
model.name = navPoint.name;
model.address = navPoint.address;
[self showDstInfoPop:model];
return;
}else {
__weak typeof(self) weakSelf = self;
@@ -1084,7 +1144,7 @@
// --- ---
if (!self.stationDetailPopup) {
AStationDetailPopupController *popup = [[AStationDetailPopupController alloc] init];
AStationDetailPopupView *popup = [[AStationDetailPopupView alloc] init];
popup.delegate = self;
self.stationDetailPopup = popup;
}
@@ -1101,13 +1161,25 @@
///
self.stationDetailPopup.tollFee = self.tjdPathInfoModel.pathDto.tolls;
[self.stationDetailPopup presentInViewController:self];
///
self.stationDetailPopup.contactName = self.tjdPathInfoModel.destinationSite.liaisonName;
self.stationDetailPopup.contactPhone = self.tjdPathInfoModel.destinationSite.liaisonPhone;
self.stationDetailPopup.businessHours = [NSString stringWithFormat:@"%@-%@" , [AMapNavCommonUtil stringValueFromStr:self.tjdPathInfoModel.destinationSite.startBusiness] , [AMapNavCommonUtil stringValueFromStr:self.tjdPathInfoModel.destinationSite.endBusiness]];
self.stationDetailPopup.hydrogenPrice = [AMapNavCommonUtil stringValueFromStr:self.tjdPathInfoModel.destinationSite.hydrogenPrice];
[self.stationDetailPopup showInView:self.view];
// [self addChildViewController:self.stationDetailPopup];
//
// CGRect rect = CGRectMake(CGRectGetMinX(self.view.frame), CGRectGetMinY(self.view.frame), CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame) - (AMP_TabbarHeight + 20) * 2);
// self.stationDetailPopup.view.frame = rect;
//
// [self.view addSubview:self.stationDetailPopup.view];
}
#pragma mark - AStationDetailPopupDelegate
#pragma mark - AStationDetailPopupViewDelegate
- (void)stationDetailPopupDidTapStartNavi:(AStationDetailPopupController *)popup {
- (void)stationDetailPopupViewDidTapStartNavi:(AStationDetailPopupView *)popup {
self.stationDetailPopup = nil;
///
///1线
@@ -1126,13 +1198,17 @@
}
}
- (void)stationDetailPopupDidTapClose:(AStationDetailPopupController *)popup {
- (void)stationDetailPopupViewDidTapClose:(AStationDetailPopupView *)popup {
self.stationDetailPopup = nil;
}
#pragma mark - ABottomBarViewDelegate
- (void)bottomBarViewDidTapCalRoute:(ABottomBarView *)barView {
if (self.currAnnotionView) {
[self.mapView deselectAnnotation:self.currAnnotionView.annotation animated:NO];
self.currAnnotionView = nil;
}
//
[self willRequestTJDInfo];
@@ -1140,6 +1216,14 @@
}
- (void)bottomBarViewDidTapSearchField:(ABottomBarView *)barView {
///
self.tjdPathInfoModel = nil;
if (self.currAnnotionView) {
[self.mapView deselectAnnotation:self.currAnnotionView.annotation animated:NO];
self.currAnnotionView = nil;
}
//
ASearchAddressController *vc = [[ASearchAddressController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
@@ -1160,7 +1244,8 @@
-(void)updateUIWithData: (AMapPOI*)poi textField: (UITextField*)tf {
BOOL isStart = tf.tag == 100;
tf.text = poi.name;
///
// tf.text = poi.name;
if (isStart) {
self.startPoi = poi;

View File

@@ -18,10 +18,12 @@
@property (nonatomic , strong) UIBarButtonItem *rightItem;
@property (nonatomic ,strong)UIButton * backBtn;
@property (nonatomic , strong) NSArray *dataArr;
@property (nonatomic , strong) NSMutableArray *dataArr;
@property (nonatomic, strong) UITextField *inputAddressTf;
@property (nonatomic, strong) AMapSearchAPI *search;
@property (nonatomic,assign)NSInteger currPage;
@end
@implementation ASearchAddressController
@@ -30,6 +32,9 @@
[super viewDidLoad];
// Do any additional setup after loading the view.
self.title = @"选择地点";
self.currPage = 1;
_dataArr = [NSMutableArray array];
[self initSubview];
@@ -65,8 +70,9 @@
[inputAddressTf mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self.view).offset(10);
make.right.mas_equalTo(self.view).offset(-10);
make.top.mas_equalTo(self.view).offset(kRoutePlanBarHeight + 10);
make.height.mas_equalTo(@30);
make.height.mas_equalTo(@35);
}];
self.inputAddressTf = inputAddressTf;
@@ -80,6 +86,7 @@
btn.layer.borderWidth = 1;
btn.layer.cornerRadius = 5;
btn.titleLabel.font = [UIFont systemFontOfSize:12];
btn.hidden = YES;
[btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(searchBtnAction) forControlEvents:UIControlEventTouchUpInside];
@@ -134,6 +141,14 @@
// [self.navigationController popViewControllerAnimated:YES];
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == self.dataArr.count - 1 && (self.dataArr.count % 20 == 0)) {
self.currPage = self.currPage + 1;
[self requestAddressWithAddress:self.inputAddressTf.text atPage:self.currPage];
}
}
#pragma mark -
- (UITableView *)tableView {
if (!_tableView) {
@@ -178,28 +193,32 @@
return;
}
[self requestAddressWithAddress:addr atPage:1];
}
-(void)requestAddressWithAddress:(NSString *)addr atPage:(NSInteger)page {
AMapPOIKeywordsSearchRequest *request = [[AMapPOIKeywordsSearchRequest alloc] init];
request.keywords = addr;
AMapNavSDKManager * sdk = [AMapNavSDKManager sharedManager];
request.city = sdk.localCity;
// request.city = sdk.localCity;
// request.types = @"高等院校";
// request.requireExtension = YES;
request.offset =20;
request.page = page;
/* SDK 3.2.0 POI*/
request.cityLimit = YES;
// request.cityLimit = YES;
// request.requireSubPOIs = YES;
[self.search AMapPOIKeywordsSearch:request];
}
#pragma mark -
/* POI . */
- (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response
@@ -212,7 +231,8 @@
//responsePOI Demo
self.dataArr = [NSArray arrayWithArray:pois];
[self.dataArr addObjectsFromArray:pois];
[self.tableView reloadData];
}
@@ -221,6 +241,8 @@
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
[self.dataArr removeAllObjects];
self.currPage = 1;
[self startSearchWithAddress:textField.text];

View File

@@ -39,6 +39,19 @@ NS_ASSUME_NONNULL_BEGIN
/// 过路费,如 @"30元";若 nil 则隐藏
@property (nonatomic, copy, nullable) NSString *tollFee;
/// 营业时间,如 @"00:00-24:00";有值显示,无值显示 -
@property (nonatomic, copy, nullable) NSString *businessHours;
/// 站点联系人,如 @"陈凯";有值显示,无值显示 -
@property (nonatomic, copy, nullable) NSString *contactName;
/// 联系方式,如 @"18019187371";有值显示,无值显示 -
@property (nonatomic, copy, nullable) NSString *contactPhone;
/// 加氢价格,如 @"32元/L";有值显示,无值显示 -
@property (nonatomic, copy, nullable) NSString *hydrogenPrice;
@property (nonatomic, weak, nullable) id<AStationDetailPopupDelegate> delegate;
/// 以半透明蒙层方式弹出在目标控制器上
@@ -50,6 +63,9 @@ NS_ASSUME_NONNULL_BEGIN
/// 关闭弹框,动画结束后执行 completion用于关闭后再 present 其他页面)
- (void)dismissWithCompletion:(nullable void(^)(void))completion;
-(void)resetUI;
@end
NS_ASSUME_NONNULL_END

View File

@@ -57,6 +57,21 @@ static inline UIColor *AStationThemeGreen(void) {
/// bottom constraint
@property (nonatomic, strong) MASConstraint *cardBottomConstraint;
//
@property (nonatomic, strong) UILabel *businessHoursLabel;
//
@property (nonatomic, strong) UIImageView *contactPersonIconView;
@property (nonatomic, strong) UILabel *contactPersonLabel;
//
@property (nonatomic, strong) UIImageView *priceIconView;
@property (nonatomic, strong) UILabel *priceLabel;
//
@property (nonatomic, strong) UIImageView *phoneIconView;
@property (nonatomic, strong) UILabel *phoneLabel;
@end
@implementation AStationDetailPopupController
@@ -121,6 +136,26 @@ static inline UIColor *AStationThemeGreen(void) {
if (self.isViewLoaded) [self _updateUI];
}
- (void)setBusinessHours:(NSString *)businessHours {
_businessHours = [businessHours copy];
if (self.isViewLoaded) [self _updateUI];
}
- (void)setContactName:(NSString *)contactName {
_contactName = [contactName copy];
if (self.isViewLoaded) [self _updateUI];
}
- (void)setContactPhone:(NSString *)contactPhone {
_contactPhone = [contactPhone copy];
if (self.isViewLoaded) [self _updateUI];
}
- (void)setHydrogenPrice:(NSString *)hydrogenPrice {
_hydrogenPrice = [hydrogenPrice copy];
if (self.isViewLoaded) [self _updateUI];
}
#pragma mark - Build UI
/**
@@ -168,10 +203,13 @@ static inline UIColor *AStationThemeGreen(void) {
[card addSubview:closeBtn];
self.closeButton = closeBtn;
UIColor * headTextColor = [UIColor hp_colorWithRGBHex:0x1D2129];
UIFont * headTextFont = [UIFont hp_pingFangMedium:14];
//
UILabel *nameLabel = [[UILabel alloc] init];
nameLabel.font = [UIFont boldSystemFontOfSize:18];
nameLabel.textColor = [UIColor colorWithWhite:0.1 alpha:1];
nameLabel.font = [UIFont hp_pingFangMedium:18];
nameLabel.textColor = headTextColor;
nameLabel.numberOfLines = 2;
// nameLabel.adjustsFontSizeToFitWidth = YES;
nameLabel.minimumScaleFactor = 0.8;
@@ -180,8 +218,8 @@ static inline UIColor *AStationThemeGreen(void) {
// 20pt
UILabel *costLabel = [[UILabel alloc] init];
costLabel.font = [UIFont systemFontOfSize:14];
costLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1];
costLabel.font = headTextFont;
costLabel.textColor = headTextColor;
costLabel.numberOfLines = 1;
costLabel.textAlignment = NSTextAlignmentLeft;
// [costLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
@@ -189,10 +227,18 @@ static inline UIColor *AStationThemeGreen(void) {
[card addSubview:costLabel];
self.costLabel = costLabel;
// 4pt
UILabel *bizHoursLabel = [[UILabel alloc] init];
bizHoursLabel.font = [UIFont hp_pingFangRegular:14];
bizHoursLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
bizHoursLabel.numberOfLines = 1;
[card addSubview:bizHoursLabel];
self.businessHoursLabel = bizHoursLabel;
//
UILabel *addrLabel = [[UILabel alloc] init];
addrLabel.font = [UIFont systemFontOfSize:13];
addrLabel.textColor = [UIColor colorWithWhite:0.5 alpha:1];
addrLabel.font = [UIFont hp_pingFangRegular:14];
addrLabel.textColor = [UIColor hp_colorWithRGBHex:0x86909C];
addrLabel.numberOfLines = 2;
[card addSubview:addrLabel];
self.addressLabel = addrLabel;
@@ -212,45 +258,84 @@ static inline UIColor *AStationThemeGreen(void) {
//
UIImageView *timeIcon = [[UIImageView alloc] init];
timeIcon.contentMode = UIViewContentModeScaleAspectFit;
timeIcon.image = [AMapNavCommonUtil imageWithName3x:@"pre_time_icon"];
timeIcon.image = [AMapNavCommonUtil imageWithName3x:@"ic_time"];
[card addSubview:timeIcon];
self.timeIconView = timeIcon;
//
UILabel *timeLabel = [[UILabel alloc] init];
timeLabel.font = [UIFont systemFontOfSize:14];
timeLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1];
timeLabel.font = headTextFont;
timeLabel.textColor = headTextColor;
[card addSubview:timeLabel];
self.timeLabel = timeLabel;
//
UIImageView *distIcon = [[UIImageView alloc] init];
distIcon.contentMode = UIViewContentModeScaleAspectFit;
distIcon.image = [AMapNavCommonUtil imageWithName3x:@"pre_distance_icon"];
distIcon.image = [AMapNavCommonUtil imageWithName3x:@"ic_mileage"];
[card addSubview:distIcon];
self.distanceIconView = distIcon;
//
UILabel *distLabel = [[UILabel alloc] init];
distLabel.font = [UIFont systemFontOfSize:14];
distLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1];
distLabel.font = headTextFont;
distLabel.textColor = headTextColor;
[card addSubview:distLabel];
self.distanceLabel = distLabel;
//
UIImageView *tollIcon = [[UIImageView alloc] init];
tollIcon.contentMode = UIViewContentModeScaleAspectFit;
tollIcon.image = [AMapNavCommonUtil imageWithName3x:@"pre_cost_icon"];
tollIcon.image = [AMapNavCommonUtil imageWithName3x:@"ic_toll"];
[card addSubview:tollIcon];
self.tollIconView = tollIcon;
//
UILabel *tollLabel = [[UILabel alloc] init];
tollLabel.font = [UIFont systemFontOfSize:14];
tollLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1];
tollLabel.font = headTextFont;
tollLabel.textColor = headTextColor;
[card addSubview:tollLabel];
self.tollLabel = tollLabel;
// &
UIImageView *personIcon = [[UIImageView alloc] init];
personIcon.contentMode = UIViewContentModeScaleAspectFit;
personIcon.image = [AMapNavCommonUtil imageWithName3x:@"ic_person"];
[card addSubview:personIcon];
self.contactPersonIconView = personIcon;
UILabel *personLabel = [[UILabel alloc] init];
personLabel.font = headTextFont;
personLabel.textColor = headTextColor;
[card addSubview:personLabel];
self.contactPersonLabel = personLabel;
// &
UIImageView *priceIcon = [[UIImageView alloc] init];
priceIcon.contentMode = UIViewContentModeScaleAspectFit;
priceIcon.image = [AMapNavCommonUtil imageWithName3x:@"ic_price"];
[card addSubview:priceIcon];
self.priceIconView = priceIcon;
UILabel *priceLabel = [[UILabel alloc] init];
priceLabel.font = headTextFont;
priceLabel.textColor = headTextColor;
[card addSubview:priceLabel];
self.priceLabel = priceLabel;
// &
UIImageView *phoneIcon = [[UIImageView alloc] init];
phoneIcon.contentMode = UIViewContentModeScaleAspectFit;
phoneIcon.image = [AMapNavCommonUtil imageWithName3x:@"ic_phone"];
[card addSubview:phoneIcon];
self.phoneIconView = phoneIcon;
UILabel *phoneLabel = [[UILabel alloc] init];
phoneLabel.font = headTextFont;
phoneLabel.textColor = headTextColor;
[card addSubview:phoneLabel];
self.phoneLabel = phoneLabel;
//
UIButton *naviBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[naviBtn setTitle:@"开始导航" forState:UIControlStateNormal];
@@ -301,24 +386,34 @@ static inline UIColor *AStationThemeGreen(void) {
make.right.equalTo(self.closeButton.mas_left).offset(-12);
}];
// 6pt
[self.addressLabel mas_makeConstraints:^(MASConstraintMaker *make) {
// 6pt
[self.businessHoursLabel 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);
}];
// 6pt
[self.addressLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.businessHoursLabel.mas_bottom).offset(10);
make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16);
}];
self.separator.hidden = YES;
// 线12pt
[self.separator mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.addressLabel.mas_bottom).offset(15);
make.top.equalTo(self.addressLabel.mas_bottom).offset(10);
make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16);
make.height.mas_equalTo(0.5);
}];
CGFloat _offset_y = 18;
// 线14pt
[self.timeIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.separator.mas_bottom).offset(15);
make.top.equalTo(self.separator.mas_bottom).offset(12);
make.left.equalTo(card).offset(16);
make.width.height.mas_equalTo(iconSize);
}];
@@ -333,7 +428,7 @@ static inline UIColor *AStationThemeGreen(void) {
///cost
[self.costIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.timeIconView);
make.left.equalTo(self.timeLabel.mas_right).offset(30);
make.left.equalTo(self.timeLabel.mas_right).offset(40);
make.width.height.mas_equalTo(iconSize);
}];
@@ -346,7 +441,7 @@ static inline UIColor *AStationThemeGreen(void) {
// + 12pt
[self.distanceIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.timeIconView.mas_bottom).offset(15);
make.top.equalTo(self.timeIconView.mas_bottom).offset(_offset_y);
make.left.equalTo(card).offset(16);
make.width.height.mas_equalTo(iconSize);
}];
@@ -372,9 +467,49 @@ static inline UIColor *AStationThemeGreen(void) {
make.height.mas_equalTo(24);
}];
// 18pt30pt
// 14pt
[self.contactPersonIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.distanceIconView.mas_bottom).offset(_offset_y);
make.left.equalTo(card).offset(16);
make.width.height.mas_equalTo(iconSize);
}];
[self.contactPersonLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.contactPersonIconView);
make.left.equalTo(self.contactPersonIconView.mas_right).offset(6);
make.height.mas_equalTo(24);
}];
// costIconView
[self.priceIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.contactPersonIconView);
make.left.equalTo(self.costIconView.mas_left);
make.width.height.mas_equalTo(iconSize);
}];
[self.priceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.contactPersonIconView);
make.left.equalTo(self.priceIconView.mas_right).offset(6);
make.right.lessThanOrEqualTo(card).offset(-10);
make.height.mas_equalTo(24);
}];
// 12pt
[self.phoneIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.contactPersonIconView.mas_bottom).offset(_offset_y);
make.left.equalTo(card).offset(16);
make.width.height.mas_equalTo(iconSize);
}];
[self.phoneLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.phoneIconView);
make.left.equalTo(self.phoneIconView.mas_right).offset(6);
make.height.mas_equalTo(24);
}];
// 18pt safeArea
[self.startNaviButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.distanceIconView.mas_bottom).offset(50);
make.top.equalTo(self.phoneIconView.mas_bottom).offset(40);
make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16);
make.height.mas_equalTo(48);
@@ -386,29 +521,63 @@ static inline UIColor *AStationThemeGreen(void) {
- (void)_updateUI {
self.stationNameLabel.text = (self.pointModel.name.length > 0)
? self.pointModel.name : @"--";
? self.pointModel.name : @"-";
//
self.businessHoursLabel.text = (self.businessHours.length > 0)
? [NSString stringWithFormat:@"营业时间:%@", self.businessHours]
: @"营业时间:-";
self.costLabel.text = (self.estimatedCost.length > 0)
? [NSString stringWithFormat:@"预计加氢费用:%@元", self.estimatedCost]
: @"预计加氢费用:--元";
: @"预计加氢费用:-";
self.addressLabel.text = (self.pointModel.address.length > 0)
? self.pointModel.address : @"--";
? 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]
: @"过路费:--元";
: @"过路费:-";
// -
self.contactPersonLabel.text = (self.contactName.length > 0)
? [NSString stringWithFormat:@"站联系人:%@", self.contactName]
: @"站联系人:-";
// -
self.priceLabel.text = (self.hydrogenPrice.length > 0)
? [NSString stringWithFormat:@"加氢价格:%@/L", self.hydrogenPrice]
: @"加氢价格:-";
// -
self.phoneLabel.text = (self.contactPhone.length > 0)
? [NSString stringWithFormat:@"联系方式:%@", self.contactPhone]
: @"联系方式:-";
}
// UI
-(void)resetUI {
self.stationNameLabel.text = @"-";
self.businessHoursLabel.text = @"营业时间:-";
self.costLabel.text = @"预计加氢费用:-";
self.addressLabel.text = @"地址:-";
self.timeLabel.text = @"预计时间:-";
self.distanceLabel.text = @"行驶里程:-";
self.tollLabel.text = @"过路费:-";
self.contactPersonLabel.text = @"站联系人:-";
self.priceLabel.text = @"加氢价格:-";
self.phoneLabel.text = @"联系方式:-";
}
#pragma mark - Animation

View File

@@ -59,6 +59,11 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, copy, nullable) NSString *latitude;
@property (nonatomic, copy, nullable) NSString *distance;
///新增弹框参数4.13
@property (nonatomic, copy, nullable) NSString *hydrogenPrice;
@property (nonatomic, copy, nullable) NSString *liaisonName;
@property (nonatomic, copy, nullable) NSString *liaisonPhone;
@end
NS_ASSUME_NONNULL_END

View File

@@ -7,6 +7,8 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "UIColor+ANavMap.h"
#import "UIFont+HP.h"
NS_ASSUME_NONNULL_BEGIN
@@ -34,6 +36,8 @@ BOOL stringIsEmpty(NSString *str);
/// 判断字符串是否非空
BOOL stringIsNotEmpty(NSString *str);
+(NSString *)stringValueFromStr:(NSString *)str;
@end
NS_ASSUME_NONNULL_END

View File

@@ -117,6 +117,15 @@ BOOL stringIsNotEmpty (NSString *str)
return ! stringIsEmpty(str);
}
///
+(NSString *)stringValueFromStr:(NSString *)str {
if (stringIsEmpty(str)) {
return @"";
}
return str;
}
#pragma mark -
+(UIImage *)imageWithName:(NSString *)name {

View File

@@ -0,0 +1,20 @@
//
// UIColor+ANavMap.h
// AMapNavIOSSDK
//
// Created by admin on 2026/4/11.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIColor (ANavMap)
+ (UIColor *)hp_colorWithRGBHex:(UInt32)hex;
+ (UIColor *)hp_colorWithRGBHex:(UInt32)hex alpha:(CGFloat)alpha;
//格式AHEX
+ (UIColor *)hp_colorWithRGBAHEX:(UInt32)hex;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,53 @@
//
// UIColor+ANavMap.m
// AMapNavIOSSDK
//
// Created by admin on 2026/4/11.
//
#import "UIColor+ANavMap.h"
@implementation UIColor (ANavMap)
//HEX
+ (UIColor *)hp_colorWithRGBHex:(UInt32)hex
{
CGFloat r = (hex >> 16) & 0xFF;
CGFloat g = (hex >> 8) & 0xFF;
CGFloat b = (hex) & 0xFF;
CGFloat a = 1.0f;
return [UIColor colorWithRed:r / 255.0f
green:g / 255.0f
blue:b / 255.0f
alpha:a];
}
+ (UIColor *)hp_colorWithRGBHex:(UInt32)hex alpha:(CGFloat)alpha
{
CGFloat r = (hex >> 16) & 0xFF;
CGFloat g = (hex >> 8) & 0xFF;
CGFloat b = (hex) & 0xFF;
CGFloat a = alpha;
return [UIColor colorWithRed:r / 255.0f
green:g / 255.0f
blue:b / 255.0f
alpha:a];
}
//AHEX
+ (UIColor *)hp_colorWithRGBAHEX:(UInt32)hex
{
CGFloat r = (hex >> 24) & 0xFF;
CGFloat g = (hex >> 16) & 0xFF;
CGFloat b = (hex >> 8) & 0xFF;
CGFloat a = (hex) & 0xFF;
return [UIColor colorWithRed:r / 255.0f
green:g / 255.0f
blue:b / 255.0f
alpha:a / 255.0f];
}
@end

View File

@@ -0,0 +1,36 @@
//
// UIFont+HP.h
// Hippo
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/**
* UIFont 快捷分类
* 统一使用 PingFang SC 字族,覆盖 Light / Regular / Medium / Semibold 四个字重。
*
* 使用示例:
* label.font = [UIFont hp_pingFangLight:14];
* label.font = [UIFont hp_pingFangRegular:16];
* label.font = [UIFont hp_pingFangMedium:15];
* label.font = [UIFont hp_pingFangSemibold:18];
*/
@interface UIFont (HP)
#pragma mark - PingFang SC Light细体
+ (UIFont *)hp_pingFangLight:(CGFloat)size;
#pragma mark - PingFang SC Regular常规
+ (UIFont *)hp_pingFangRegular:(CGFloat)size;
#pragma mark - PingFang SC Medium中等
+ (UIFont *)hp_pingFangMedium:(CGFloat)size;
#pragma mark - PingFang SC Semibold半粗
+ (UIFont *)hp_pingFangSemibold:(CGFloat)size;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,45 @@
//
// UIFont+HP.m
// Hippo
//
#import "UIFont+HP.h"
// PingFang SC
static NSString * const kHPFontPingFangLight = @"PingFangSC-Light";
static NSString * const kHPFontPingFangRegular = @"PingFangSC-Regular";
static NSString * const kHPFontPingFangMedium = @"PingFangSC-Medium";
static NSString * const kHPFontPingFangSemibold = @"PingFangSC-Semibold";
@implementation UIFont (HP)
#pragma mark - PingFang SC Light
+ (UIFont *)hp_pingFangLight:(CGFloat)size {
UIFont *font = [UIFont fontWithName:kHPFontPingFangLight size:size];
// 退
return font ?: [UIFont systemFontOfSize:size weight:UIFontWeightLight];
}
#pragma mark - PingFang SC Regular
+ (UIFont *)hp_pingFangRegular:(CGFloat)size {
UIFont *font = [UIFont fontWithName:kHPFontPingFangRegular size:size];
return font ?: [UIFont systemFontOfSize:size weight:UIFontWeightRegular];
}
#pragma mark - PingFang SC Medium
+ (UIFont *)hp_pingFangMedium:(CGFloat)size {
UIFont *font = [UIFont fontWithName:kHPFontPingFangMedium size:size];
return font ?: [UIFont systemFontOfSize:size weight:UIFontWeightMedium];
}
#pragma mark - PingFang SC Semibold
+ (UIFont *)hp_pingFangSemibold:(CGFloat)size {
UIFont *font = [UIFont fontWithName:kHPFontPingFangSemibold size:size];
return font ?: [UIFont systemFontOfSize:size weight:UIFontWeightSemibold];
}
@end

View File

@@ -163,6 +163,7 @@ static inline UIColor *ABottomBarThemeGreen(void) {
self.calRouteButton = btn;
CGFloat off_y = AMP_TabbarHeight;
off_y = 0;
#ifdef kAMapSDKDebugFlag
off_y = 0;
#endif
@@ -172,7 +173,7 @@ static inline UIColor *ABottomBarThemeGreen(void) {
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);
make.bottom.equalTo(card).offset(-40 + (-AMP_TabbarHeight - 13));
}];
}

View File

@@ -0,0 +1,70 @@
//
// AStationDetailPopupView.h
// AMapNavIOSSDK
//
// Created by admin on 2026/3/22.
//
#import <UIKit/UIKit.h>
#import "ANavPointModel.h"
#import "AMapNavSDKHeader.h"
NS_ASSUME_NONNULL_BEGIN
@class AStationDetailPopupView;
@protocol AStationDetailPopupViewDelegate <NSObject>
@optional
/// 点击"开始导航"
- (void)stationDetailPopupViewDidTapStartNavi:(AStationDetailPopupView *)popup;
/// 点击关闭
- (void)stationDetailPopupViewDidTapClose:(AStationDetailPopupView *)popup;
@end
@interface AStationDetailPopupView : UIView
@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;
/// 营业时间,如 @"00:00-24:00";有值显示,无值显示 -
@property (nonatomic, copy, nullable) NSString *businessHours;
/// 站点联系人,如 @"陈凯";有值显示,无值显示 -
@property (nonatomic, copy, nullable) NSString *contactName;
/// 联系方式,如 @"18019187371";有值显示,无值显示 -
@property (nonatomic, copy, nullable) NSString *contactPhone;
/// 加氢价格,如 @"32元/L";有值显示,无值显示 -
@property (nonatomic, copy, nullable) NSString *hydrogenPrice;
@property (nonatomic, weak, nullable) id<AStationDetailPopupViewDelegate> delegate;
/// 显示弹框动画
- (void)showInView:(UIView *)parentView;
/// 隐藏弹框动画
- (void)hideWithCompletion:(nullable void(^)(void))completion;
/// 隐藏弹框动画(无 completion
- (void)hide;
/// 重置 UI 状态
- (void)resetUI;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,707 @@
//
// AStationDetailPopupView.m
// AMapNavIOSSDK
//
// Created by admin on 2026/3/22.
//
#import "AStationDetailPopupView.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 AStationDetailPopupView ()
///
@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;
//
@property (nonatomic, strong) UILabel *businessHoursLabel;
//
@property (nonatomic, strong) UIImageView *contactPersonIconView;
@property (nonatomic, strong) UILabel *contactPersonLabel;
//
@property (nonatomic, strong) UIImageView *priceIconView;
@property (nonatomic, strong) UILabel *priceLabel;
//
@property (nonatomic, strong) UIImageView *phoneIconView;
@property (nonatomic, strong) UILabel *phoneLabel;
@end
@implementation AStationDetailPopupView
#pragma mark - Init
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
[self setupUI];
}
return self;
}
#pragma mark - Setup UI
- (void)setupUI {
[self addSubview:self.maskControl];
[self.cardView addSubview:self.closeButton];
[self.cardView addSubview:self.stationNameLabel];
[self.cardView addSubview:self.costLabel];
[self.cardView addSubview:self.businessHoursLabel];
[self.cardView addSubview:self.addressLabel];
[self.cardView addSubview:self.costIconView];
[self.cardView addSubview:self.separator];
[self.cardView addSubview:self.timeIconView];
[self.cardView addSubview:self.timeLabel];
[self.cardView addSubview:self.distanceIconView];
[self.cardView addSubview:self.distanceLabel];
[self.cardView addSubview:self.tollIconView];
[self.cardView addSubview:self.tollLabel];
[self.cardView addSubview:self.contactPersonIconView];
[self.cardView addSubview:self.contactPersonLabel];
[self.cardView addSubview:self.priceIconView];
[self.cardView addSubview:self.priceLabel];
[self.cardView addSubview:self.phoneIconView];
[self.cardView addSubview:self.phoneLabel];
[self.cardView addSubview:self.startNaviButton];
[self setupConstraints];
[self updateUI];
}
#pragma mark - Masonry Constraints
- (void)setupConstraints {
UIView *card = self.cardView;
CGFloat iconSize = 16;
//
[self.maskControl mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self);
}];
// 16
[card mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self).offset(0);
make.right.equalTo(self).offset(-0);
make.bottom.equalTo(self).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);
}];
//
[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.right.equalTo(self.closeButton.mas_left).offset(-12);
}];
// 10pt
[self.businessHoursLabel 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);
}];
// 10pt
[self.addressLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.businessHoursLabel.mas_bottom).offset(10);
make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16);
}];
self.separator.hidden = YES;
// 线10pt
[self.separator mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.addressLabel.mas_bottom).offset(10);
make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16);
make.height.mas_equalTo(0.5);
}];
CGFloat _offset_y = 18;
// 线12pt
[self.timeIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.separator.mas_bottom).offset(12);
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.height.mas_equalTo(24);
}];
/// cost
[self.costIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.timeIconView);
make.left.equalTo(self.timeLabel.mas_right).offset(40);
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(_offset_y);
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.height.mas_equalTo(24);
}];
// 14pt
[self.contactPersonIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.distanceIconView.mas_bottom).offset(_offset_y);
make.left.equalTo(card).offset(16);
make.width.height.mas_equalTo(iconSize);
}];
[self.contactPersonLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.contactPersonIconView);
make.left.equalTo(self.contactPersonIconView.mas_right).offset(6);
// make.height.mas_equalTo(24);
make.width.lessThanOrEqualTo(self).multipliedBy(0.4);
}];
// costIconView
[self.priceIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.contactPersonIconView);
make.left.equalTo(self.costIconView.mas_left);
make.width.height.mas_equalTo(iconSize);
}];
[self.priceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.contactPersonIconView);
make.left.equalTo(self.priceIconView.mas_right).offset(6);
make.right.lessThanOrEqualTo(card).offset(-10);
make.height.mas_equalTo(24);
}];
// 12pt
[self.phoneIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.contactPersonIconView.mas_bottom).offset(_offset_y);
make.left.equalTo(card).offset(16);
make.width.height.mas_equalTo(iconSize);
}];
[self.phoneLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.phoneIconView);
make.left.equalTo(self.phoneIconView.mas_right).offset(6);
make.height.mas_equalTo(24);
}];
// 18pt safeArea
[self.startNaviButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.phoneIconView.mas_bottom).offset(40);
make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16);
make.height.mas_equalTo(48);
make.bottom.equalTo(card).offset(-AMP_TabbarSafeBottomMargin + (-AMP_TabbarHeight - 13));
}];
}
#pragma mark - Public
- (void)showInView:(UIView *)parentView {
self.alpha = 0;
self.maskControl.alpha = 0;
[parentView addSubview:self];
[self mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(parentView);
}];
[self playShowAnimation];
}
- (void)hide {
[self hideWithCompletion:nil];
}
- (void)hideWithCompletion:(void(^)(void))completion {
[self playDismissAnimationWithCompletion:^{
[self removeFromSuperview];
if (completion) {
completion();
}
}];
}
#pragma mark - Setter Override
- (void)setPointModel:(ANavPointModel *)pointModel {
_pointModel = pointModel;
[self updateUI];
}
- (void)setEstimatedCost:(NSString *)estimatedCost {
_estimatedCost = [estimatedCost copy];
[self updateUI];
}
- (void)setEstimatedTime:(NSString *)estimatedTime {
_estimatedTime = [estimatedTime copy];
[self updateUI];
}
- (void)setDriveDistance:(NSString *)driveDistance {
_driveDistance = [driveDistance copy];
[self updateUI];
}
- (void)setTollFee:(NSString *)tollFee {
_tollFee = [tollFee copy];
[self updateUI];
}
- (void)setBusinessHours:(NSString *)businessHours {
_businessHours = [businessHours copy];
[self updateUI];
}
- (void)setContactName:(NSString *)contactName {
_contactName = [contactName copy];
[self updateUI];
}
- (void)setContactPhone:(NSString *)contactPhone {
_contactPhone = [contactPhone copy];
[self updateUI];
}
- (void)setHydrogenPrice:(NSString *)hydrogenPrice {
_hydrogenPrice = [hydrogenPrice copy];
[self updateUI];
}
#pragma mark - Data Update
- (void)updateUI {
self.stationNameLabel.text = (self.pointModel.name.length > 0)
? self.pointModel.name : @"-";
//
self.businessHoursLabel.text = (self.businessHours.length > 0)
? [NSString stringWithFormat:@"营业时间:%@", self.businessHours]
: @"营业时间:-";
self.costLabel.text = ((self.estimatedCost.length > 0) && [self.estimatedCost doubleValue])
? [NSString stringWithFormat:@"预计加氢费用:%@元", self.estimatedCost]
: @"预计加氢费用:-";
self.addressLabel.text = (self.pointModel.address.length > 0)
? self.pointModel.address : @"-";
// "-- 分钟"
self.timeLabel.text = ((self.estimatedTime.length > 0) && [self.estimatedTime doubleValue] > 0)
? [NSString stringWithFormat:@"预计时间:%@分钟", self.estimatedTime]
: @"预计时间:-";
// "-- 公里"
self.distanceLabel.text = ((self.driveDistance.length > 0) && [self.driveDistance doubleValue] > 0)
? [NSString stringWithFormat:@"行驶里程:%@公里", self.driveDistance]
: @"行驶里程:-";
// "-- 元"
self.tollLabel.text = (self.tollFee.length > 0)
? [NSString stringWithFormat:@"过路费:%@元", self.tollFee]
: @"过路费:-";
// -
self.contactPersonLabel.text = (self.contactName.length > 0)
? [NSString stringWithFormat:@"站联系人:%@", self.contactName]
: @"站联系人:-";
// -
self.priceLabel.text = (self.hydrogenPrice.length > 0)
? [NSString stringWithFormat:@"加氢价格:%@/L", self.hydrogenPrice]
: @"加氢价格:-";
// -
self.phoneLabel.text = (self.contactPhone.length > 0)
? [NSString stringWithFormat:@"联系方式:%@", self.contactPhone]
: @"联系方式:-";
}
- (void)resetUI {
self.stationNameLabel.text = @"-";
self.businessHoursLabel.text = @"营业时间:-";
self.costLabel.text = @"预计加氢费用:-";
self.addressLabel.text = @"地址:-";
self.timeLabel.text = @"预计时间:-";
self.distanceLabel.text = @"行驶里程:-";
self.tollLabel.text = @"过路费:-";
self.contactPersonLabel.text = @"站联系人:-";
self.priceLabel.text = @"加氢价格:-";
self.phoneLabel.text = @"联系方式:-";
}
#pragma mark - Animation
/**
*/
- (void)playShowAnimation {
//
[self.cardView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self).offset(0);
make.right.equalTo(self).offset(-0);
make.top.equalTo(self.mas_bottom).offset(0);
}];
[self layoutIfNeeded];
//
[self.cardView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self).offset(0);
make.right.equalTo(self).offset(-0);
make.bottom.equalTo(self).offset(0);
}];
[UIView animateWithDuration:0.36
delay:0
usingSpringWithDamping:0.82
initialSpringVelocity:0.5
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.alpha = 1;
self.maskControl.alpha = 1;
[self layoutIfNeeded];
} completion:nil];
}
- (void)playDismissAnimationWithCompletion:(void(^)(void))completion {
[self.cardView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self).offset(0);
make.right.equalTo(self).offset(-0);
make.top.equalTo(self.mas_bottom).offset(20);
}];
[UIView animateWithDuration:0.25
delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
self.maskControl.alpha = 0;
[self layoutIfNeeded];
} completion:^(BOOL finished) {
if (completion) completion();
}];
}
#pragma mark - Actions
- (void)onMaskTapped {
if ([self.delegate respondsToSelector:@selector(stationDetailPopupViewDidTapClose:)]) {
[self.delegate stationDetailPopupViewDidTapClose:self];
}
[self hide];
}
- (void)onCloseTapped {
if ([self.delegate respondsToSelector:@selector(stationDetailPopupViewDidTapClose:)]) {
[self.delegate stationDetailPopupViewDidTapClose:self];
}
[self hide];
}
- (void)onStartNaviTapped {
__weak typeof(self) weakSelf = self;
[self hideWithCompletion:^{
__strong typeof(weakSelf) strongSelf = weakSelf;
if ([strongSelf.delegate respondsToSelector:@selector(stationDetailPopupViewDidTapStartNavi:)]) {
[strongSelf.delegate stationDetailPopupViewDidTapStartNavi:strongSelf];
}
}];
}
#pragma mark - Lazy Load
- (UIControl *)maskControl {
if (!_maskControl) {
_maskControl = [[UIControl alloc] init];
_maskControl.backgroundColor = [UIColor colorWithWhite:0 alpha:0];
[_maskControl addTarget:self action:@selector(onMaskTapped) forControlEvents:UIControlEventTouchUpInside];
}
return _maskControl;
}
- (UIView *)cardView {
if (!_cardView) {
_cardView = [[UIView alloc] init];
_cardView.backgroundColor = [UIColor whiteColor];
_cardView.layer.cornerRadius = 16;
_cardView.layer.masksToBounds = NO;
_cardView.layer.shadowColor = [UIColor blackColor].CGColor;
_cardView.layer.shadowOpacity = 0.15;
_cardView.layer.shadowRadius = 12;
_cardView.layer.shadowOffset = CGSizeMake(0, -4);
[self addSubview:_cardView];
}
return _cardView;
}
- (UIButton *)closeButton {
if (!_closeButton) {
_closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_closeButton setImage:[AMapNavCommonUtil imageWithName:@"icon_close"] forState:UIControlStateNormal];
[_closeButton setTitleColor:[UIColor colorWithWhite:0.5 alpha:1] forState:UIControlStateNormal];
_closeButton.titleLabel.font = [UIFont systemFontOfSize:16];
[_closeButton addTarget:self action:@selector(onCloseTapped) forControlEvents:UIControlEventTouchUpInside];
}
return _closeButton;
}
- (UILabel *)stationNameLabel {
if (!_stationNameLabel) {
_stationNameLabel = [[UILabel alloc] init];
_stationNameLabel.font = [UIFont hp_pingFangMedium:18];
_stationNameLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
_stationNameLabel.numberOfLines = 2;
_stationNameLabel.minimumScaleFactor = 0.8;
}
return _stationNameLabel;
}
- (UILabel *)costLabel {
if (!_costLabel) {
_costLabel = [[UILabel alloc] init];
_costLabel.font = [UIFont hp_pingFangMedium:14];
_costLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
_costLabel.numberOfLines = 1;
_costLabel.textAlignment = NSTextAlignmentLeft;
}
return _costLabel;
}
- (UILabel *)businessHoursLabel {
if (!_businessHoursLabel) {
_businessHoursLabel = [[UILabel alloc] init];
_businessHoursLabel.font = [UIFont hp_pingFangRegular:14];
_businessHoursLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
_businessHoursLabel.numberOfLines = 1;
}
return _businessHoursLabel;
}
- (UILabel *)addressLabel {
if (!_addressLabel) {
_addressLabel = [[UILabel alloc] init];
_addressLabel.font = [UIFont hp_pingFangRegular:14];
_addressLabel.textColor = [UIColor hp_colorWithRGBHex:0x86909C];
_addressLabel.numberOfLines = 2;
}
return _addressLabel;
}
- (UIImageView *)costIconView {
if (!_costIconView) {
_costIconView = [[UIImageView alloc] init];
_costIconView.contentMode = UIViewContentModeScaleAspectFit;
_costIconView.image = [AMapNavCommonUtil imageWithName3x:@"ic_fuel"];
}
return _costIconView;
}
- (UIView *)separator {
if (!_separator) {
_separator = [[UIView alloc] init];
_separator.backgroundColor = [UIColor colorWithWhite:0.88 alpha:1];
_separator.hidden = YES;
}
return _separator;
}
- (UIImageView *)timeIconView {
if (!_timeIconView) {
_timeIconView = [[UIImageView alloc] init];
_timeIconView.contentMode = UIViewContentModeScaleAspectFit;
_timeIconView.image = [AMapNavCommonUtil imageWithName3x:@"ic_time"];
}
return _timeIconView;
}
- (UILabel *)timeLabel {
if (!_timeLabel) {
_timeLabel = [[UILabel alloc] init];
_timeLabel.font = [UIFont hp_pingFangMedium:14];
_timeLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
}
return _timeLabel;
}
- (UIImageView *)distanceIconView {
if (!_distanceIconView) {
_distanceIconView = [[UIImageView alloc] init];
_distanceIconView.contentMode = UIViewContentModeScaleAspectFit;
_distanceIconView.image = [AMapNavCommonUtil imageWithName3x:@"ic_mileage"];
}
return _distanceIconView;
}
- (UILabel *)distanceLabel {
if (!_distanceLabel) {
_distanceLabel = [[UILabel alloc] init];
_distanceLabel.font = [UIFont hp_pingFangMedium:14];
_distanceLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
}
return _distanceLabel;
}
- (UIImageView *)tollIconView {
if (!_tollIconView) {
_tollIconView = [[UIImageView alloc] init];
_tollIconView.contentMode = UIViewContentModeScaleAspectFit;
_tollIconView.image = [AMapNavCommonUtil imageWithName3x:@"ic_toll"];
}
return _tollIconView;
}
- (UILabel *)tollLabel {
if (!_tollLabel) {
_tollLabel = [[UILabel alloc] init];
_tollLabel.font = [UIFont hp_pingFangMedium:14];
_tollLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
}
return _tollLabel;
}
- (UIImageView *)contactPersonIconView {
if (!_contactPersonIconView) {
_contactPersonIconView = [[UIImageView alloc] init];
_contactPersonIconView.contentMode = UIViewContentModeScaleAspectFit;
_contactPersonIconView.image = [AMapNavCommonUtil imageWithName3x:@"ic_person"];
}
return _contactPersonIconView;
}
- (UILabel *)contactPersonLabel {
if (!_contactPersonLabel) {
_contactPersonLabel = [[UILabel alloc] init];
_contactPersonLabel.font = [UIFont hp_pingFangMedium:14];
_contactPersonLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
}
return _contactPersonLabel;
}
- (UIImageView *)priceIconView {
if (!_priceIconView) {
_priceIconView = [[UIImageView alloc] init];
_priceIconView.contentMode = UIViewContentModeScaleAspectFit;
_priceIconView.image = [AMapNavCommonUtil imageWithName3x:@"ic_price"];
}
return _priceIconView;
}
- (UILabel *)priceLabel {
if (!_priceLabel) {
_priceLabel = [[UILabel alloc] init];
_priceLabel.font = [UIFont hp_pingFangMedium:14];
_priceLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
}
return _priceLabel;
}
- (UIImageView *)phoneIconView {
if (!_phoneIconView) {
_phoneIconView = [[UIImageView alloc] init];
_phoneIconView.contentMode = UIViewContentModeScaleAspectFit;
_phoneIconView.image = [AMapNavCommonUtil imageWithName3x:@"ic_phone"];
}
return _phoneIconView;
}
- (UILabel *)phoneLabel {
if (!_phoneLabel) {
_phoneLabel = [[UILabel alloc] init];
_phoneLabel.font = [UIFont hp_pingFangMedium:14];
_phoneLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
}
return _phoneLabel;
}
- (UIButton *)startNaviButton {
if (!_startNaviButton) {
_startNaviButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_startNaviButton setTitle:@"开始导航" forState:UIControlStateNormal];
[_startNaviButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
_startNaviButton.titleLabel.font = [UIFont boldSystemFontOfSize:17];
_startNaviButton.backgroundColor = AStationThemeGreen();
_startNaviButton.layer.cornerRadius = 24;
[_startNaviButton addTarget:self action:@selector(onStartNaviTapped) forControlEvents:UIControlEventTouchUpInside];
}
return _startNaviButton;
}
@end

View File

@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.2.4+7
version: 1.2.5+8
environment:
sdk: ^3.9.0