如何移除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




