Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ActiveLabel as AccessibleElement by default. #424

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 52 additions & 17 deletions ActiveLabel/ActiveLabel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Foundation
import UIKit

public protocol ActiveLabelDelegate: class {
public protocol ActiveLabelDelegate: AnyObject {
func didSelect(_ text: String, type: ActiveType)
}

Expand All @@ -23,6 +23,8 @@ typealias ElementTuple = (range: NSRange, element: ActiveElement, type: ActiveTy

open var enabledTypes: [ActiveType] = [.mention, .hashtag, .url]

open var accessibleType: ActiveType?

open var urlMaximumLength: Int?

open var configureLinkAttribute: ConfigureLinkAttribute?
Expand Down Expand Up @@ -64,6 +66,10 @@ typealias ElementTuple = (range: NSRange, element: ActiveElement, type: ActiveTy
didSet { updateTextStorage(parseText: false) }
}

public var isAccessibilityEnabled: Bool = true {
didSet { updateAccessibility(isEnabled: isAccessibilityEnabled) }
}

// MARK: - Computed Properties
private var hightlightFont: UIFont? {
guard let highlightFontName = highlightFontName, let highlightFontSize = highlightFontSize else { return nil }
Expand Down Expand Up @@ -145,6 +151,11 @@ typealias ElementTuple = (range: NSRange, element: ActiveElement, type: ActiveTy
didSet { textContainer.lineBreakMode = lineBreakMode }
}

open override func accessibilityActivate() -> Bool {
setAccessibilityElement()
return isAccessibilityEnabled
}

// MARK: - init functions
override public init(frame: CGRect) {
super.init(frame: frame)
Expand Down Expand Up @@ -215,22 +226,7 @@ typealias ElementTuple = (range: NSRange, element: ActiveElement, type: ActiveTy
selectedElement = nil
}
case .ended, .regionExited:
guard let selectedElement = selectedElement else { return avoidSuperCall }

switch selectedElement.element {
case .mention(let userHandle): didTapMention(userHandle)
case .hashtag(let hashtag): didTapHashtag(hashtag)
case .url(let originalURL, _): didTapStringURL(originalURL)
case .custom(let element): didTap(element, for: selectedElement.type)
case .email(let element): didTapStringEmail(element)
}

let when = DispatchTime.now() + Double(Int64(0.25 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: when) {
self.updateAttributesWhenSelected(false)
self.selectedElement = nil
}
avoidSuperCall = true
avoidSuperCall = setSelectedElement(avoidSuperCall: avoidSuperCall)
case .cancelled:
updateAttributesWhenSelected(false)
selectedElement = nil
Expand All @@ -243,6 +239,38 @@ typealias ElementTuple = (range: NSRange, element: ActiveElement, type: ActiveTy
return avoidSuperCall
}

@discardableResult
private func setSelectedElement(avoidSuperCall: Bool) -> Bool {
guard let selectedElement = selectedElement else { return avoidSuperCall }

switch selectedElement.element {
case .mention(let userHandle): didTapMention(userHandle)
case .hashtag(let hashtag): didTapHashtag(hashtag)
case .url(let originalURL, _): didTapStringURL(originalURL)
case .custom(let element): didTap(element, for: selectedElement.type)
case .email(let element): didTapStringEmail(element)
}

let when = DispatchTime.now() + Double(Int64(0.25 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: when) {
self.updateAttributesWhenSelected(false)
self.selectedElement = nil
}

return true
}

private func setAccessibilityElement() {
guard isAccessibilityEnabled else { return }

if let accessibleType = accessibleType {
selectedElement = ElementTuple(range: NSRange(location: 0, length: 0), element: ActiveElement.create(with: accessibleType, text: ""), type: accessibleType)
} else {
selectedElement = activeElements.values.filter{ $0.count>0 }.flatMap{ $0 }.first
}
setSelectedElement(avoidSuperCall: true)
}

// MARK: - private properties
fileprivate var _customizing: Bool = true
fileprivate var defaultCustomColor: UIColor = .black
Expand Down Expand Up @@ -300,6 +328,13 @@ typealias ElementTuple = (range: NSRange, element: ActiveElement, type: ActiveTy
setNeedsDisplay()
}

fileprivate func updateAccessibility(isEnabled: Bool) {
if isEnabled {
isAccessibilityElement = isEnabled
accessibilityTraits = UIAccessibilityTraits.button
}
}

fileprivate func clearActiveElements() {
selectedElement = nil
for (type, _) in activeElements {
Expand Down