iOS项目从Xcode 12.2升级至13.1后出现Non-@objc property 'borderColor'无法重写错误
解决Xcode 13.1升级后UIView borderColor重写报错问题
我来帮你搞定这个升级后遇到的属性重写错误!
问题根源
在Xcode 13对应的iOS SDK版本里,UIView的borderColor属性被移到了extension中定义,而且没有标记@objc修饰符。按照Swift的规则,子类根本没法重写extension里的非@objc属性——这就是为啥你在Xcode 12.2里跑没问题,升级就报错的原因。
可行的解决方案
方案1:自定义属性避开冲突(最推荐)
直接换个自定义的@IBInspectable属性,彻底避免和系统属性撞名:
import Foundation import UIKit open class MaterialTextField: UITextField { // MARK: - Tooltip fileprivate var isTipRaised = false @IBInspectable var customBorderColor: UIColor? { didSet { self.setColorAppearance(self.defaultColor) // 要是需要同步到系统layer的边框色,加上这句 self.layer.borderColor = customBorderColor?.cgColor } } // 这里保留你原来的setColorAppearance逻辑 private func setColorAppearance(_ color: UIColor) { // 你的原有代码 } private var defaultColor: UIColor { // 返回你的默认颜色逻辑 return .gray } }
方案2:自定义同名属性绑定layer
如果你非要用borderColor这个名字,那别用override,直接自己写一个同名属性,和layer.borderColor绑定就行:
import Foundation import UIKit open class MaterialTextField: UITextField { // MARK: - Tooltip fileprivate var isTipRaised = false var borderColor: UIColor? { get { guard let cgColor = layer.borderColor else { return nil } return UIColor(cgColor: cgColor) } set { layer.borderColor = newValue?.cgColor self.setColorAppearance(self.defaultColor) } } // 保留原有方法 private func setColorAppearance(_ color: UIColor) { // 你的原有逻辑 } private var defaultColor: UIColor { return .gray } }
这种方式相当于绕开了系统的borderColor属性,自己实现了一套存取逻辑,完全不会触发重写错误。
方案3:用UIAppearance统一配置(适合全局样式)
如果你的setColorAppearance是用来统一设置文本框样式的,那可以直接用UIAppearance协议来配置,根本不用重写属性:
extension MaterialTextField { static func setupDefaultStyle() { let appearance = MaterialTextField.appearance() appearance.layer.borderColor = UIColor.gray.cgColor // 其他需要统一设置的样式都放这 } }
然后在AppDelegate或者SceneDelegate的启动方法里调用MaterialTextField.setupDefaultStyle()就好啦。
总结
优先选方案1,逻辑清晰还不会有潜在冲突;要是对属性名称有执念,方案2完美适配;全局样式场景下方案3最省心。
内容的提问来源于stack exchange,提问作者Alejandro Gonzalez
相关产品推荐
相关产品推荐

