如何移除通过UIView扩展添加的CALayer顶部边框?
如何移除通过UIView扩展添加的顶部边框?
嘿,这个问题的核心在于你当前的addTopBorderWithColor方法只是把边框layer直接加到视图的layer里,但没保存这个layer的引用——这就导致后面想找它移除的时候,根本不知道哪个是你要删的那个边框!
我给你推荐两种解决思路,优先选第一种,更稳妥:
方案一:修改扩展,给UIView添加可追踪的边框管理
我们可以用关联对象给UIView加一个“隐藏属性”,专门用来保存这个顶部边框的layer,这样添加和移除都能精准操作。
修改后的完整扩展代码:
import UIKit import ObjectiveC extension UIView { // 用一个唯一的key来标识我们的顶部边框layer private static let topBorderLayerKey = UnsafeRawPointer(bitPattern: "topBorderLayer".hashValue)! // 关联属性,用来存顶部边框的layer private var topBorderLayer: CALayer? { get { return objc_getAssociatedObject(self, UIView.topBorderLayerKey) as? CALayer } set { objc_setAssociatedObject(self, UIView.topBorderLayerKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } // 改进后的添加边框方法(还能避免重复添加) func addTopBorderWithColor(color: UIColor, width: CGFloat) { // 先移除已有的边框,防止重复叠加 removeTopBorder() let border = CALayer() border.backgroundColor = color.cgColor border.frame = CGRect(x: 0, y: 0, width: self.frame.size.width, height: width) self.layer.addSublayer(border) // 把这个边框存到关联属性里 self.topBorderLayer = border } // 新增的移除边框方法 func removeTopBorder() { topBorderLayer?.removeFromSuperlayer() topBorderLayer = nil } }
怎么用?
现在你想移除textLbl的边框时,直接调用就行:
textLbl.removeTopBorder()
额外优化:适配视图尺寸变化
对了,还有个小细节:原来的边框frame是基于视图当前的frame设置的,如果视图后续因为自动布局、屏幕旋转等原因尺寸变了,边框宽度不会跟着变。如果需要适配的话,可以在扩展里加个layoutSublayers的重写:
extension UIView { override open func layoutSublayers(of layer: CALayer) { super.layoutSublayers(of: layer) // 每次布局更新时,同步边框的宽度 topBorderLayer?.frame = CGRect(x: 0, y: 0, width: self.frame.size.width, height: topBorderLayer?.frame.height ?? 0) } }
方案二:遍历子Layer查找移除(不推荐)
如果你暂时不想改原来的扩展,也可以通过遍历视图的sublayers来查找并移除,但这个方法很容易误删其他layer,只有在紧急情况下用:
func removeTopBorder(from view: UIView) { view.layer.sublayers?.forEach { layer in // 这里要匹配你之前设置的边框参数:y=0,高度是你传的width(比如1) if layer.frame.origin.y == 0 && layer.frame.height == 1 { layer.removeFromSuperlayer() } } }
比如你之前给textLbl加的是高度1的白色边框,就可以用这个方法,但如果后续边框高度变了,或者有其他layer刚好符合这个条件,就会误删,所以还是优先用方案一。
内容的提问来源于stack exchange,提问作者froggomad
相关产品推荐
相关产品推荐

