通过递归获取指定view的所有子视图.
1. 获取View的子视图
使用
let subViewArr = view.getAllSubViews() // 获取所有子视图
let imageViewArr = view.getSubView(name: "UIImageView") // 获取指定类名的子视图
实现
extension UIView {
private static var getAllsubviews: [UIView] = []
public func getSubView(name: String) -> [UIView] {
let viewArr = viewArray(root: self)
UIView.getAllsubviews = []
return viewArr.filter {$0.className == name}
}
public func getAllSubViews() -> [UIView] {
UIView.getAllsubviews = []
return viewArray(root: self)
}
private func viewArray(root: UIView) -> [UIView] {
for view in root.subviews {
if view.isKind(of: UIView.self) {
UIView.getAllsubviews.append(view)
}
_ = viewArray(root: view)
}
return UIView.getAllsubviews
}
}
extension NSObject {
var className: String {
let name = type(of: self).description()
if name.contains(".") {
return name.components(separatedBy: ".")[1]
} else {
return name
}
}
}
2. 获取UIAlertController的titleLabel和messageLabel
UIAlertController好用,但可自定义程度不高,例如我们想让message文字左对齐,就需要获取到messageLabel,但UIAlertController并没有提供这个属性.
我们就可以通过递归拿到alertTitleLabel和alertMessageLabel.
extension UIAlertController {
public var alertTitleLabel: UILabel? {
return self.view.getSubView(name: "UILabel").first as? UILabel
}
public var alertMessageLabel: UILabel? {
return self.view.getSubView(name: "UILabel").last as? UILabel
}
}
虽然通过这种方法可以拿到alertTitleLabel和alertMessageLabel.但没法区分哪个是哪个,alertTitleLabel为默认子控件的第一个label,如果title传空,message传值,alertTitleLabel和alertMessageLabel获取到的都是message的label.
如果有更好的方法欢迎讨论.