You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何移除iOS窗口中用于防截屏的安全文本框

如何移除iOS窗口中用于防截屏的安全文本框

这个问题我之前也碰到过,核心问题在于你原先的代码里没给那个安全文本框做唯一标识,后续找不到它来移除;而且你修改了图层的层级关系,直接删除文本框的话会导致窗口的图层结构错乱,界面大概率会出问题。我给你调整了代码,新增了移除的逻辑,你可以参考:

首先我们给安全文本框加一个唯一的Tag,方便后续查找,同时新增移除方法来恢复图层层级并删除文本框:

private let secureTextFieldTag = 9999 // 定义一个唯一的Tag值

extension UIWindow {
    func makeSecure() {
        // 先移除已有的安全文本框,避免重复添加
        removeSecure()
        
        let field = UITextField()
        field.tag = secureTextFieldTag // 给文本框标记唯一Tag
        let view = UIView(frame: CGRect(x: 0, y: 0, width: field.frame.width, height: field.frame.height))
        field.isSecureTextEntry = true
        self.addSubview(field)
        self.layer.superlayer?.addSublayer(field.layer)
        field.layer.sublayers?.last?.addSublayer(self.layer)
        field.leftView = view
        field.leftViewMode = .always
    }
    
    func removeSecure() {
        // 根据Tag找到我们添加的安全文本框
        guard let secureField = viewWithTag(secureTextFieldTag) as? UITextField else {
            return // 没找到的话直接返回
        }
        
        // 恢复窗口的图层层级:把窗口的图层移回原来的父图层
        self.layer.removeFromSuperlayer()
        self.layer.superlayer?.addSublayer(self.layer)
        
        // 移除安全文本框及其图层
        secureField.removeFromSuperview()
        secureField.layer.removeFromSuperlayer()
    }
}

之后你就可以根据布尔值来控制功能的开关了:

// 假设isSecureFeatureEnabled是你的控制开关变量
if isSecureFeatureEnabled {
    UIApplication.shared.keyWindow?.makeSecure()
} else {
    UIApplication.shared.keyWindow?.removeSecure()
}

这里要注意几个点:

  • makeSecure()开头调用removeSecure(),是为了避免重复触发添加多个文本框,导致后续移除逻辑混乱;
  • 恢复图层层级是关键,因为原来的代码把窗口的图层加到了文本框的子图层里,如果不恢复,删除文本框后窗口的图层会丢失,界面就会显示异常。

备注:内容来源于stack exchange,提问作者RP89

火山引擎 最新活动