我正在尝试找到最近的可能子视图。在我的应用中,有7个UIButton
并且UILabel
位于下方,边距为20.它不是子视图。
我想要什么?要用较少的努力找出最接近按钮的标签。
我目前在做什么?我正在函数中传递UIButton并计算从该按钮到所有标签的可能距离。然后对距离进行排序会导致上升并选择第一个对象以获得最小距离,这应该是我最近的标签。
internal func findNearByLabel(withRespectToButton button: UIButton) -> UILabel? {
var distance = Array<CGFloat>()
var labels: Array<UILabel> = self.view.subViews(type: UILabel.self)
labels.forEach { (label) in
distance.append(self.distance(label.frame.origin, button.frame.origin))
}
if !distance.isEmpty {
let sortedDistance = Array.init(distance).sorted()
let minDistance = sortedDistance.first!
let indexOfMinDistance = distance.index(of: minDistance)!
return labels[indexOfMinDistance]
}
return nil
}
internal func distance(_ a: CGPoint, _ b: CGPoint) -> CGFloat {
let xDistance = a.x - b.x
let yDistance = a.y - b.y
return CGFloat(sqrt((xDistance * xDistance) + (yDistance * yDistance)))
}
extension UIView {
func subViews<T : UIView>(type : T.Type) -> [T]{
var all = [T]()
for view in self.subviews {
if let aView = view as? T{
all.append(aView)
}
}
return all
}
}
什么是问题?没问题,它有效,但我想检查这是否是最佳解决方案,还是可以进行改进?
答案 0 :(得分:3)
Just a few improvements using functional patterns.
// generic method, can be in a category
extension CGPoint {
func distance(to point: CGPoint) -> CGFloat {
// there is already a function for sqrt(x * x + y * y)
return hypot(self.x - point.x, self.y - point.y)
}
}
internal func findNearByLabel(withRespectToButton button: UIButton) -> UILabel? {
// you don't really need the subViews method
let labels = self.view.subviews.flatMap { $0 as? UILabel }
// don't forget we got "map"
let distances = labels.map { $0.frame.origin.distance(to: button.frame.origin) }
// we zip both sequences into one, that way we don't have to worry about sorting two arrays
let labelDistances = zip(labels, distances)
// we don't need sorting just to get the minimum
let closestLabel = labelDistances.min { $0.1 < $1.1 }
return closestLabel?.0
}