You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Swift扩展中遍历可用UIColor类方法以获取颜色数组?

自动获取UIColor扩展中的所有自定义颜色

嘿,这个需求挺实用的!要实现这种“自动化抓取扩展里所有颜色”的功能,Swift本身的反射API在处理类方法时有点局限,但我们可以借助**Objective-C运行时(Runtime)**来搞定,它能帮我们遍历类的所有方法,筛选出我们需要的自定义颜色方法。

先理清楚核心思路

你的UIColor扩展里的方法都是类方法,且返回UIColor类型,参数只有可选的alpha。我们的目标是:

  1. 让这些方法能被Runtime识别(需要给方法加@objc标记)
  2. 遍历UIColor的所有类方法,筛选出自定义的那些(排除系统自带的颜色方法)
  3. 调用这些方法获取颜色实例,组成数组返回

具体实现步骤

1. 给你的UIColor扩展方法添加@objc标记

Runtime只能识别暴露给Objective-C的方法,所以我们需要给每个自定义颜色方法加上@objc:

extension UIColor {
    @objc class func firstColor(alpha: CGFloat = 1.0) -> UIColor {
        // 注意:你原代码里的green(322)和blue(405)超过了255,这里帮你修正为合理值,避免显示白色
        return UIColor(red: 139.0/255.0, green: 222.0/255.0, blue: 205.0/255.0, alpha: alpha)
    }
    
    @objc class func secondColor(alpha: CGFloat = 1.0) -> UIColor {
        return UIColor(red: 225.0/255.0, green: 139.0/255.0, blue: 127.0/255.0, alpha: alpha)
    }
}

2. 编写你的“magicalFunctionHere”

这个函数会用Runtime遍历方法,筛选并调用自定义颜色方法:

import Foundation

func getCustomUIColors() -> [UIColor] {
    var methodCount: UInt32 = 0
    // 获取UIColor类的所有类方法
    let methods = class_copyMethodList(object_getClass(UIColor.self), &methodCount)
    // 记得释放内存,避免泄漏
    defer { free(methods) }
    
    var availableColors = [UIColor]()
    
    guard let methodList = methods else { return availableColors }
    
    for i in 0..<Int(methodCount) {
        let method = methodList[i]
        let selector = method_getName(method)
        let methodName = String(cString: sel_getName(selector))
        
        // 筛选逻辑:只保留以"Color"结尾,且不是系统自带的颜色方法
        // 你可以根据自己的命名规则调整,比如给方法加特定前缀(如"custom_"),这样筛选更精准
        let systemColorMethods = ["clearColor", "whiteColor", "blackColor", "grayColor", "lightGrayColor", "darkGrayColor", "redColor", "greenColor", "blueColor", "cyanColor", "yellowColor", "magentaColor", "orangeColor", "purpleColor", "brownColor"]
        guard methodName.hasSuffix("Color"), !systemColorMethods.contains(methodName) else {
            continue
        }
        
        // 调用方法获取颜色(因为我们的方法有默认alpha参数,所以无参调用也能生效)
        if let color = UIColor.perform(selector).takeUnretainedValue() as? UIColor {
            availableColors.append(color)
        }
    }
    
    return availableColors
}

3. 使用示例

现在你就能像期望的那样获取所有自定义颜色了:

let availableColors: [UIColor] = getCustomUIColors()

备选方案(无需Runtime)

如果你不想依赖Runtime,也可以手动维护一个Selector数组,虽然不够自动化,但胜在简单直接:

// 每次新增颜色方法,都要把Selector加到这个数组里
let customColorSelectors: [Selector] = [#selector(UIColor.firstColor), #selector(UIColor.secondColor)]
let availableColors = customColorSelectors.compactMap { UIColor.perform($0).takeUnretainedValue() as? UIColor }

注意事项

  • 如果你自定义的颜色方法有不同的参数(比如有的需要额外参数),那Runtime的调用逻辑需要调整,得先检查方法的参数个数和类型,再传递对应参数调用。
  • 命名规则很重要:如果你的自定义方法命名和系统方法冲突,筛选逻辑会出错,所以建议给自定义方法加统一前缀(比如custom_firstColor),这样筛选时只需要检查前缀即可,更可靠。

内容的提问来源于stack exchange,提问作者drew..

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:25:09