iOS开发针对苹果新系统iOS26的兼容适配UITabBarButtonItem & UITabBar的液态玻璃效果/当前wifi ssid获取

1. UITabBarButtonItem液态玻璃效果

        兼容处理:

        第一种方式(不推荐):把所有的UITabBarButtonItem关闭液态玻璃效果:

 if (@available(iOS 26.0, *)) { self.navigationItem.rightBarButtonItem.hidesSharedBackground = YES; self.navigationItem.leftBarButtonItem.hidesSharedBackground = YES; } else { // Fallback on earlier versions }

        第二种方式:所有导航栏按钮全部采用UITabBarButtonItem,支持液态玻璃效果。

        第三种方式:降低Xcode版本到Xcode25及以下版本,然后再打包

        第四种方式:使用兼容模式显示传统UI风格,也就是取消TabBar液态玻璃效果:

        打开info.plist,添加一个Boolean键值对,取消液态玻璃效果,添加完成后重新运行,UITabBar恢复旧的样式:

<key>UIDesignRequiresCompatibility</key> <true/>

2.  采用UILayoutFittingExpandedSize设置自定义的navigationItem.titleView的内容尺寸,在iOS26上高度偏大,高度变为屏幕的高度,预期是高度应该为导航栏的高度;

原因:在iOS26之前UILayoutFittingExpandedSize最大尺寸限制在导航栏范围内,而在iOS26则允许充斥整个屏幕:

- (CGSize)intrinsicContentSize { return UILayoutFittingExpandedSize; }

        兼容处理:

        修改intrinsicContentSize,指定titleView的尺寸大小为导航栏大小:

 #define SCREEN_WIDTH ([[UIScreen mainScreen] respondsToSelector:@selector(nativeBounds)]?[UIScreen mainScreen].nativeBounds.size.width/[UIScreen mainScreen].nativeScale:[UIScreen mainScreen].bounds.size.width) - (CGSize)intrinsicContentSize { return CGSizeMake(SCREEN_WIDTH, 44); }

3、UITabBarController调用self.setValue(yourTabBar, forKey: "tabBar")自定义tabBar失效

        原因:iOS 26 之后对 UITabBarController 的 KVC 注入限制,导致无效,但不会crash

        兼容处理:

        方案1:使用兼容模式显示传统UI风格,也就是取消TabBar液态玻璃效果:

        打开info.plist,添加一个Boolean键值对,取消液态玻璃效果,添加完成后重新运行,UITabBar恢复旧的样式:

<key>UIDesignRequiresCompatibility</key> <true/>

        方案2:改为使用系统的UITabBarItem组件,能够支持新系统的液态玻璃效果

        方案3:降低Xcode版本到Xcode25及以下版本,然后再打包

4、创建一个由URL标识的代表任何资源的assert对象时报错:

AVAssetExportSessionStatusFailed: Error Domain=AVFoundationErrorDomain Code=-11800 "这项操作无法完成" UserInfo={ NSUnderlyingError=0x1586626a0 { Error Domain=NSOSStatusErrorDomain Code=-16979 "(null)" }, NSLocalizedFailureReason=发生未知错误(-16979), NSURL=file:///var/mobile/Media/DCIM/100APPLE/IMG_0426.MOV, NSLocalizedDescription=这项操作无法完成 }

        原因:AVAssetExportSession -11800 / -16979 转码失败,权限不足、文件不可读,创建一个由URL标识的代表任何资源的assert对象时,传入的originFilePath示例: file:///var/mobile/Media/DCIM/100APPLE/IMG_0426.MOV,没有读的权限,因为iOS 26对相册视频读取权限收紧,代码示例:

//originFilePath示例: file:///var/mobile/Media/DCIM/100APPLE/IMG_0426.MOV AVURLAsset *asset = [AVURLAsset URLAssetWithURL:originFilePath options:nil]; 

        兼容处理:先将相册的视频拷贝到 App 沙盒临时目录,然后再去创建资源对象AVURLAsset

 [self copyVideoToSandbox:originFilePath completion:^(NSURL *localUrl) { AVURLAsset *asset = [AVURLAsset URLAssetWithURL:localUrl options:nil]; }]; - (void)copyVideoToSandbox:(NSURL *)originUrl completion:(void (^)(NSURL *localUrl))completion { NSString *temp = [NSTemporaryDirectory() stringByAppendingPathComponent:@"tempVideo.mov"]; NSURL *localUrl = [NSURL fileURLWithPath:temp]; NSFileManager *fm = [NSFileManager defaultManager]; if ([fm fileExistsAtPath:temp]) { [fm removeItemAtPath:temp error:nil]; } NSError *err = nil; BOOL ok = [fm copyItemAtURL:originUrl toURL:localUrl error:&err]; if (!ok || err) { NSLog(@"拷贝失败: %@", err); completion(nil); return; } completion(localUrl); } 

5. 通过CNCopySupportedInterfaces获取wifi ssid的方式已失效:

 class func getWifiSSID() -> String? { var wifiName: let wifiInterfaces = CNCopySupportedInterfaces() if wifiInterfaces != nil { let interfaceArr = CFBridgingRetain(wifiInterfaces) as! [String] if interfaceArr.count > 0 { let interfaceName = interfaceArr[0] as CFString let ussafeInterfaceData = CNCopyCurrentNetworkInfo(interfaceName) if ussafeInterfaceData != nil { let interfaceData = ussafeInterfaceData as! [String: Any] wifiName = interfaceData["SSID"] as? String ?? "" } else { return nil } } } return wifiName }

        原因:iOS26不再推荐使用CNCopySupportedInterfaces,在iOS26将返回空值

        兼容处理:Capabilities添加Access WiFi Information权限;通过CLLocationManager确保有定位权限,然后使用NEHotspotNetwork获取wifi ssid:

NEHotspotNetwork.fetchCurrent { curNetwork in block(curNetwork?.ssid ?? "") }

Read more

机器人逆运动学——以六自由度机器人为例(详解、易懂,附全部Matlab代码)

机器人逆运动学——以六自由度机器人为例(详解、易懂,附全部Matlab代码)

前言 前面机器人正运动学主要讲关节变量到末端执行器位姿的关系,也就是知道了关节变量与连杆参数就可以利用D-H参数表来表达末端位姿。而逆运动学就是已知末端的位姿与连杆参数,来求得关节变量的过程。本文首先介绍何为逆运动学,再以例子的形式利用D-H参数表与齐次变换矩阵对机器人进行逆解。 **阅读提醒1:在运动学逆解前,需要掌握运动学正解的相关知识,也要掌握一定的矩阵运算规则。(相关知识点有在我之前的文章提到,我也在本文进行了引用,如有需要可以查阅;我对机器人正运动学相关的matlab分析单独发了一篇博客,有需要也可以查阅) **阅读提醒2:下文灰色补充块是用于解释正文的,用来补充正文没讲到的知识或细节。 一、运动学逆解 上面提到,已知末端执行器的位姿来求解这一位姿对应的全部关节变量就是逆解,然而由于机械结构的差异,有些时候一个末端位姿可能对应着不同的反解情况(多解)。逆运动学问题实质就是非线性超越方程组的求解问题,其解法分为两大类(封闭解法和数值解法),本文主要讲封闭解法。 1.【 封闭解法 】概述 封闭解法是指具有解析形式的解法,其计算速度快、效率高,更便于实时控制,具

ABB 机器人虚拟示教器基础操作教程

ABB 机器人虚拟示教器基础操作教程

一、基础操作界面与模式 1. 操作模式切换 * 手动模式:用于编程、调试和手动操作 自动模式:用于程序自动运行(需满足安全条件) 2. 动作模式选择(手动模式下) * 单轴模式:单独控制每个关节轴(1-6轴) * 优点:最直观,与坐标系无关 * 用途:调整机器人姿态,避免奇异点 * 线性模式:TCP沿直线运动 * 重定位模式:TCP位置不变,只改变工具姿态 点击示教器左上角 进入菜单栏 3. 坐标系选择(线性/重定位模式下) 四个可选坐标系: * 大地坐标系:机器人安装的基础坐标系 * 基座坐标系:机器人底座中心为原点(多数基本选择) * 工件坐标系:用户自定义的工作平面 * 工具坐标系:以工具末端为原点 二、三大核心数据设置 1. 工具数据(tooldata) 定义:描述工具(

FPGA原型验证学习笔记——开篇之问:Simulation or Emulation?

一些叽里咕噜的话 新人报道!今天是我跳槽进入新公司的第一天,也是我从传统FPGA开发转变为FPGA原型验证的一天。一切重新开始,一切重新学习。 第一天无非就是装装电脑,配置下服务器,闲来无事,阅读了下S2C公司撰写的数字芯片与验证相关的白皮书《Prototypical II》,觉得很有收获。不知何故,突然涌现一种强烈的分享欲望,想着也正好趁着刚开始学习新东西,不如开个专栏,作为自己日常学习笔记,同时也为了更好的以一个初学者的视角去记录我的学习心得,为更多跟我一样的初学者提供一些帮助。如果我的笔记有帮到您,那是我的荣幸,也让我倍感舒心。 另外,我也把《Prototypical II》链接放在了文章最后,有兴趣的小伙伴可自取,不过该网站需要您注册一些信息才可获取,另外该网站还提供了很多其他的资料供大家学习。 开篇之问:Simulation or Emulation? 在入手一门新技术时,总是要先问what/why,再去学习how。所以在进入FPGA原型验证的技术学习之前,我们需要先问清楚:什么是FPGA原型验证?为什么需要用到FPGA原型验证?而今天的第一篇笔记就是抛开乱七八糟

手把手教你用 OpenClaw + 飞书,打造专属 AI 机器人

手把手教你用 OpenClaw + 飞书,打造专属 AI 机器人

手把手教你用 OpenClaw + 飞书,打造专属 AI 机器人 当前版本 OpenClaw(2026.2.22-2)已内置飞书插件,无需额外安装。 你有没有想过,在飞书里直接跟 AI 对话,就像跟同事聊天一样自然? 今天这篇文章,带你从零开始,用 OpenClaw 搭建一个飞书 AI 机器人。全程命令行操作,10 分钟搞定。 一、准备工作 1.1 安装 Node.js(版本 ≥ 22) OpenClaw 依赖 Node.js 运行,首先确保你的 Node 版本不低于 22。 推荐使用 nvm 管理 Node