Compare commits
9 Commits
20c39a4a12
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
| b462312c2e | |||
| ec96a96be2 | |||
|
|
0ba9547992 | ||
| c6e7616be2 | |||
| eae654c47e | |||
| f01875abb9 | |||
| 881da166d1 | |||
| 14b2e6b35c | |||
|
|
5c74c7ccc0 |
65
ln_jq_app/CLAUDE.md
Normal 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.
|
||||
@@ -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.
|
||||
|
||||
# 基本配置如下
|
||||
安卓包名:com.lingniu.driver
|
||||
iOS包名:com.lnkj.lnJqApp
|
||||
>android jks,别名密码
|
||||
>小羚羚
|
||||
>Ln123456.
|
||||
|
||||
|
||||
高德key
|
||||
安卓 92495660f7bc990cb475426c47c03b65
|
||||
苹果:3ac08e5e14df9d7a52e98d40e21a0189
|
||||
|
||||
key:2cc1d822e313307fe311c3127a1deeb5
|
||||
秘钥:0529b72df6bf0c577ff2182cb8b1d970
|
||||
|
||||
安卓包名:com.lingniu.driver
|
||||
iOS包名:com.lnkj.ln_jq_app
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 + "元";
|
||||
|
||||
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;
|
||||
distanceKmStr = String.format("%.1f", distanceKm) + "公里";
|
||||
durationMinStr = durationMin + "分钟";
|
||||
}
|
||||
}
|
||||
|
||||
tvDuration.setText("预计时间:" + durationMin + "分钟");
|
||||
tvDistance.setText("行驶里程:" + String.format("%.1f", distanceKm) + "公里");
|
||||
tvTolls.setText("过路费:" + tolls + "元");
|
||||
tvTollsFuel.setText("预计加氢费用:" + (isGetInputtips ? "--" : hydrogenCost) + "元");
|
||||
|
||||
// 增加多级非空校验,防止点击搜索条目时崩溃
|
||||
if (truckRouteData != null &&
|
||||
truckRouteData.algorithmPath != null &&
|
||||
truckRouteData.algorithmPath.hydrogenCost != null &&
|
||||
!truckRouteData.algorithmPath.hydrogenCost.isEmpty()) {
|
||||
hydrogenCost = truckRouteData.algorithmPath.hydrogenCost;
|
||||
hydrogenCost = (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);
|
||||
tvPerson.setText("站联系人:" + liaisonName);
|
||||
tvPrice.setText("加氢价格:" + hydrogenPrice);
|
||||
tvPhone.setText("联系方式:" + liaisonPhone);
|
||||
|
||||
isGetInputtips = false;
|
||||
|
||||
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(endPoint, 13f));
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "获取加氢费用失败", e);
|
||||
}
|
||||
|
||||
tvBusinessHours.setText("营业时间:" + startBusiness);
|
||||
if (liaisonName != null && liaisonName.length() > 5) {
|
||||
liaisonName = liaisonName.substring(0, 5) + "...";
|
||||
}
|
||||
tvPerson.setText("站联系人:" + liaisonName);
|
||||
tvPrice.setText("加氢价格:" + hydrogenPrice);
|
||||
tvPhone.setText("联系方式:" + liaisonPhone);
|
||||
|
||||
|
||||
|
||||
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(endPoint, 13f));
|
||||
|
||||
|
||||
} 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;
|
||||
}
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
40
ln_jq_app/android/app/src/main/res/drawable/ic_fuel.xml
Normal 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>
|
||||
|
Before Width: | Height: | Size: 781 B |
41
ln_jq_app/android/app/src/main/res/drawable/ic_mileage.xml
Normal 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>
|
||||
13
ln_jq_app/android/app/src/main/res/drawable/ic_path.xml
Normal 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>
|
||||
|
Before Width: | Height: | Size: 762 B |
20
ln_jq_app/android/app/src/main/res/drawable/ic_person.xml
Normal 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>
|
||||
|
Before Width: | Height: | Size: 865 B |
12
ln_jq_app/android/app/src/main/res/drawable/ic_phone.xml
Normal 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>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
40
ln_jq_app/android/app/src/main/res/drawable/ic_price.xml
Normal 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>
|
||||
26
ln_jq_app/android/app/src/main/res/drawable/ic_search.xml
Normal 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>
|
||||
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
19
ln_jq_app/android/app/src/main/res/drawable/ic_time.xml
Normal 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>
|
||||
|
Before Width: | Height: | Size: 791 B |
37
ln_jq_app/android/app/src/main/res/drawable/ic_toll.xml
Normal 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>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 844 B |
|
After Width: | Height: | Size: 792 B |
|
After Width: | Height: | Size: 909 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 864 B |
@@ -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
|
||||
@@ -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; // 箭头尖端 X(向右偏移ah = 45度)
|
||||
CGFloat arrowTipY = bh + ah; // 箭头尖端 Y(向下偏移ah = 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) ──
|
||||
// 子视图宽度统一约束到 kBubbleWidth(160),气泡主体实际宽度
|
||||
[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; // 箭头尖端 X(右下45度)
|
||||
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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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,7 +820,8 @@
|
||||
[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;
|
||||
}
|
||||
@@ -1100,14 +1160,26 @@
|
||||
self.stationDetailPopup.driveDistance = [NSString stringWithFormat:@"%.1f" , self.tjdPathInfoModel.pathDto.distance / 1000.0] ;
|
||||
///油费
|
||||
self.stationDetailPopup.tollFee = self.tjdPathInfoModel.pathDto.tolls;
|
||||
|
||||
///新增字段信息
|
||||
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 presentInViewController:self];
|
||||
[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;
|
||||
|
||||
@@ -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,7 +86,8 @@
|
||||
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];
|
||||
[self.view addSubview:btn];
|
||||
@@ -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 @@
|
||||
|
||||
//解析response获取POI信息,具体解析见 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];
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}];
|
||||
|
||||
// ── 开始导航按钮(里程行下方18pt,距卡片底部30pt) ──
|
||||
// ── 站点联系人行(过路费行下方,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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));
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||