Swift读取图库照片并判断是否为横向图:解决CGFloat?比较错误
解决Swift中判断横向图时的可选类型比较错误
嘿,这个问题我之前也踩过坑!报错的核心原因很直白:你用来比较的图片宽度和高度都是可选类型(CGFloat?),Swift不允许直接对可选值做大小比较——毕竟可选值可能是nil,Swift没法判断nil和另一个值谁大谁小。下面结合读取图库照片的场景,给你几种靠谱的解决办法:
1. 可选绑定(最安全推荐)
这是Swift里处理可选值最规范的方式,先确认宽高的可选值不为nil,再取出实际值进行比较,完全避免崩溃风险。
比如你从图库拿到UIImage后,可以这么写:
func isLandscapeImage(from image: UIImage?) -> Bool { // 先确保图片不为空,且能获取到CGImage的宽高 guard let image = image, let cgImage = image.cgImage else { // 图片为空或无法获取宽高时,按需求返回默认值(这里返回false) return false } // 将Int类型的宽高转成CGFloat,再比较 let width = CGFloat(cgImage.width) let height = CGFloat(cgImage.height) return width > height }
如果是直接拿到CGSize的可选值(比如某些图库框架返回的尺寸),可以简化成:
func isLandscape(from size: CGSize?) -> Bool { guard let size = size else { return false } return size.width > size.height }
2. nil合并运算符(快速处理默认值)
如果你能确定可选值为nil时的默认逻辑(比如默认按纵向图处理),可以用??给可选值指定默认值,快速完成解包和比较:
// 假设width和height是你从图片中拿到的CGFloat?类型 let width: CGFloat? = image?.size.width let height: CGFloat? = image?.size.height // 当width或height为nil时,默认用0替代,再比较 let isLandscape = (width ?? 0) > (height ?? 0)
⚠️ 注意:这种方式要考虑默认值是否符合你的业务逻辑,比如如果width为nil,用0替代的话,可能会误判为纵向图,所以只适合你明确知道nil场景的处理逻辑时使用。
3. 强制解包(谨慎使用!)
如果你100%确定宽高的可选值不可能为nil(比如已经提前做过层层判断),可以用!强制解包,但强烈不推荐在不确定的场景下用——一旦可选值为nil,程序会直接崩溃:
// 仅当你能绝对保证width和height都有值时才用! let isLandscape = width! > height!
补充:避免踩坑的小细节
在读取图库照片时,如果你是通过UIImage的size属性获取宽高,那image.size.width和image.size.height本身就是非可选的CGFloat,不会出现这个报错。你之前的错误大概率是从cgImage里取width/height(这两个是Int?类型),转成CGFloat时没处理可选值导致的,记得先解包cgImage再转换哦。
内容的提问来源于stack exchange,提问作者Miloo
相关产品推荐
相关产品推荐

