67 lines
2.5 KiB
Swift
67 lines
2.5 KiB
Swift
//
|
|
// UIView+Accessibility.swift
|
|
// VDS
|
|
//
|
|
// Created by Matt Bruce on 8/4/23.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
|
|
extension UIView {
|
|
/// AccessibilityLabel helper for joining the accessibilityLabel property of all views passed in.
|
|
/// - Parameters:
|
|
/// - views: Array of Views that you want to join the accessibilityLabel.
|
|
/// - separator: Separator used between the accessibilityLabel for each UIView.
|
|
/// - Returns: Joined String.
|
|
public func combineAccessibilityLabel(for views: [AnyObject], separator: String = ", ") -> String? {
|
|
let labels: [String] = views.map({($0.accessibilityLabel?.isEmpty ?? true) ? nil : $0.accessibilityLabel}).compactMap({$0})
|
|
return labels.joined(separator: separator)
|
|
}
|
|
|
|
/// AccessibilityLabel helper for joining the accessibilityLabel property of all views passed in.
|
|
/// - Parameter views: Array of Views that you want to join the accessibilityLabel.
|
|
public func setAccessibilityLabel(for views: [AnyObject]) {
|
|
accessibilityLabel = combineAccessibilityLabel(for: views)
|
|
}
|
|
|
|
/// Will tell if the view is actually visibile on screen, also it will check the hierarchy above this view.
|
|
public var isVisibleOnScreen: Bool {
|
|
// Ensure the view has a window, meaning it's part of the view hierarchy
|
|
guard let window = self.window, !self.isHidden, self.alpha > 0 else {
|
|
return false
|
|
}
|
|
|
|
// Check if the view's frame intersects with the window's bounds
|
|
let viewFrameInWindow = self.convert(self.bounds, to: window)
|
|
var isIntersecting = viewFrameInWindow.intersects(window.bounds)
|
|
|
|
// Check parent views for visibility
|
|
var currentView: UIView? = self
|
|
while let view = currentView, isIntersecting {
|
|
// If any parent has a constraint making it effectively invisible, set isIntersecting to false
|
|
if view.bounds.size.width == 0 || view.bounds.size.height == 0 {
|
|
isIntersecting = false
|
|
break
|
|
}
|
|
currentView = view.superview
|
|
}
|
|
|
|
return isIntersecting
|
|
}
|
|
|
|
public func gatherAccessibilityElements(from view: AnyObject) -> [AnyObject] {
|
|
var elements: [AnyObject] = []
|
|
|
|
for subview in view.subviews {
|
|
if subview.isAccessibilityElement && subview.isVisibleOnScreen {
|
|
elements.append(subview)
|
|
} else {
|
|
elements.append(contentsOf: gatherAccessibilityElements(from: subview))
|
|
}
|
|
}
|
|
|
|
return elements
|
|
}
|
|
}
|