Bläddra i källkod

Merge pull request #1048 from deltachat/message_voice_over_nav

Message voice over nav
cyBerta 4 år sedan
förälder
incheckning
ffff1b0573

+ 7 - 0
deltachat-ios/Chat/Views/AudioPlayerView.swift

@@ -7,7 +7,9 @@ open class AudioPlayerView: UIView {
     lazy var playButton: UIButton = {
     lazy var playButton: UIButton = {
         let playButton = UIButton(type: .custom)
         let playButton = UIButton(type: .custom)
         let playImage = UIImage(named: "play")
         let playImage = UIImage(named: "play")
+        playImage?.isAccessibilityElement = false
         let pauseImage = UIImage(named: "pause")
         let pauseImage = UIImage(named: "pause")
+        pauseImage?.isAccessibilityElement = false
         playButton.setImage(playImage?.withRenderingMode(.alwaysTemplate), for: .normal)
         playButton.setImage(playImage?.withRenderingMode(.alwaysTemplate), for: .normal)
         playButton.setImage(pauseImage?.withRenderingMode(.alwaysTemplate), for: .selected)
         playButton.setImage(pauseImage?.withRenderingMode(.alwaysTemplate), for: .selected)
         playButton.imageView?.contentMode = .scaleAspectFit
         playButton.imageView?.contentMode = .scaleAspectFit
@@ -15,6 +17,7 @@ open class AudioPlayerView: UIView {
         playButton.contentHorizontalAlignment = .fill
         playButton.contentHorizontalAlignment = .fill
         playButton.translatesAutoresizingMaskIntoConstraints = false
         playButton.translatesAutoresizingMaskIntoConstraints = false
         playButton.isUserInteractionEnabled = true
         playButton.isUserInteractionEnabled = true
+        playButton.accessibilityLabel = String.localized("menu_play")
         return playButton
         return playButton
     }()
     }()
 
 
@@ -26,6 +29,7 @@ open class AudioPlayerView: UIView {
         durationLabel.adjustsFontForContentSizeCategory = true
         durationLabel.adjustsFontForContentSizeCategory = true
         durationLabel.text = "0:00"
         durationLabel.text = "0:00"
         durationLabel.translatesAutoresizingMaskIntoConstraints = false
         durationLabel.translatesAutoresizingMaskIntoConstraints = false
+        durationLabel.isAccessibilityElement = false
         return durationLabel
         return durationLabel
     }()
     }()
 
 
@@ -33,6 +37,7 @@ open class AudioPlayerView: UIView {
         let progressView = UIProgressView(progressViewStyle: .default)
         let progressView = UIProgressView(progressViewStyle: .default)
         progressView.progress = 0.0
         progressView.progress = 0.0
         progressView.translatesAutoresizingMaskIntoConstraints = false
         progressView.translatesAutoresizingMaskIntoConstraints = false
+        progressView.isAccessibilityElement = false
         return progressView
         return progressView
     }()
     }()
 
 
@@ -80,6 +85,7 @@ open class AudioPlayerView: UIView {
         progressView.progress = 0
         progressView.progress = 0
         playButton.isSelected = false
         playButton.isSelected = false
         durationLabel.text = "0:00"
         durationLabel.text = "0:00"
+        playButton.accessibilityLabel = String.localized("menu_play")
     }
     }
 
 
     open func setProgress(_ progress: Float) {
     open func setProgress(_ progress: Float) {
@@ -106,5 +112,6 @@ open class AudioPlayerView: UIView {
 
 
     open func showPlayLayout(_ play: Bool) {
     open func showPlayLayout(_ play: Bool) {
         playButton.isSelected = play
         playButton.isSelected = play
+        playButton.accessibilityLabel = play ? String.localized("menu_pause") : String.localized("menu_play")
     }
     }
 }
 }

+ 5 - 0
deltachat-ios/Chat/Views/Cells/AudioMessageCell.swift

@@ -46,6 +46,11 @@ public class AudioMessageCell: BaseMessageCell {
         } else {
         } else {
             mainContentView.spacing = 0
             mainContentView.spacing = 0
         }
         }
+        if msg.type == DC_MSG_VOICE {
+            accessibilityLabel = String.localized("voice_message")
+        } else {
+            accessibilityLabel = String.localized("audio")
+        }
 
 
         super.update(msg: msg, messageStyle: messageStyle, isAvatarVisible: isAvatarVisible, isGroup: isGroup)
         super.update(msg: msg, messageStyle: messageStyle, isAvatarVisible: isAvatarVisible, isGroup: isGroup)
     }
     }

+ 54 - 7
deltachat-ios/Chat/Views/Cells/BaseMessageCell.swift

@@ -60,6 +60,7 @@ public class BaseMessageCell: UITableViewCell {
         view.translatesAutoresizingMaskIntoConstraints = false
         view.translatesAutoresizingMaskIntoConstraints = false
         view.isUserInteractionEnabled = true
         view.isUserInteractionEnabled = true
         view.isHidden = true
         view.isHidden = true
+        view.isAccessibilityElement = false
         return view
         return view
     }()
     }()
 
 
@@ -77,6 +78,7 @@ public class BaseMessageCell: UITableViewCell {
         view.label.setAttributes(attributes, detector: .url)
         view.label.setAttributes(attributes, detector: .url)
         view.label.setAttributes(attributes, detector: .phoneNumber)
         view.label.setAttributes(attributes, detector: .phoneNumber)
         view.isUserInteractionEnabled = true
         view.isUserInteractionEnabled = true
+        view.isAccessibilityElement = false
         return view
         return view
     }()
     }()
 
 
@@ -100,6 +102,7 @@ public class BaseMessageCell: UITableViewCell {
         view.clipsToBounds = true
         view.clipsToBounds = true
         view.paddingLeading = 4
         view.paddingLeading = 4
         view.paddingTrailing = 4
         view.paddingTrailing = 4
+        view.isAccessibilityElement = false
         return view
         return view
     }()
     }()
 
 
@@ -120,6 +123,7 @@ public class BaseMessageCell: UITableViewCell {
         label.paddingLeading = 4
         label.paddingLeading = 4
         label.paddingTrailing = 4
         label.paddingTrailing = 4
         label.clipsToBounds = true
         label.clipsToBounds = true
+        label.isAccessibilityElement = false
         return label
         return label
     }()
     }()
 
 
@@ -293,6 +297,40 @@ public class BaseMessageCell: UITableViewCell {
         }
         }
 
 
         messageLabel.delegate = self
         messageLabel.delegate = self
+        accessibilityLabel = configureAccessibilityString(message: msg)
+    }
+
+    func configureAccessibilityString(message: DcMsg) -> String {
+        var topLabelAccessibilityString = ""
+        var quoteAccessibilityString = ""
+        var messageLabelAccessibilityString = ""
+        var additionalAccessibilityString = ""
+
+        if let topLabelText = topLabel.text {
+            topLabelAccessibilityString = "\(topLabelText), "
+        }
+        if let messageLabelText = messageLabel.text {
+            messageLabelAccessibilityString = "\(messageLabelText), "
+        }
+        if let senderTitle = quoteView.senderTitle.text, let quote = quoteView.quote.text {
+            quoteAccessibilityString = "\(senderTitle), \(quote), \(String.localized("reply_noun")), "
+        }
+        if let additionalAccessibilityInfo = accessibilityLabel {
+            additionalAccessibilityString = "\(additionalAccessibilityInfo), "
+        }
+
+        return "\(topLabelAccessibilityString) " +
+            "\(quoteAccessibilityString) " +
+            "\(additionalAccessibilityString) " +
+            "\(messageLabelAccessibilityString) " +
+            "\(getFormattedBottomLineAccessibilityString(message: message))"
+    }
+
+    func getFormattedBottomLineAccessibilityString(message: DcMsg) -> String {
+        let padlock =  message.showPadlock() ? "\(String.localized("encrypted_message")), " : ""
+        let date = "\(message.formattedSentDate()), "
+        let sendingState = "\(getSendingStateString(message.state))"
+        return "\(date) \(padlock) \(sendingState)"
     }
     }
 
 
     func getFormattedBottomLine(message: DcMsg) -> NSAttributedString {
     func getFormattedBottomLine(message: DcMsg) -> NSAttributedString {
@@ -321,7 +359,6 @@ public class BaseMessageCell: UITableViewCell {
             }
             }
 
 
             text.append(NSAttributedString(string: message.formattedSentDate(), attributes: timestampAttributes))
             text.append(NSAttributedString(string: message.formattedSentDate(), attributes: timestampAttributes))
-
             if message.showPadlock() {
             if message.showPadlock() {
                 attachPadlock(to: text, color: bottomCompactView ? nil : DcColors.checkmarkGreen)
                 attachPadlock(to: text, color: bottomCompactView ? nil : DcColors.checkmarkGreen)
             }
             }
@@ -344,13 +381,27 @@ public class BaseMessageCell: UITableViewCell {
         } else {
         } else {
             imageAttachment.image = UIImage(named: "ic_lock")
             imageAttachment.image = UIImage(named: "ic_lock")
         }
         }
-        imageAttachment.image?.accessibilityIdentifier = String.localized("encrypted_message")
         let imageString = NSMutableAttributedString(attachment: imageAttachment)
         let imageString = NSMutableAttributedString(attachment: imageAttachment)
         imageString.addAttributes([NSAttributedString.Key.baselineOffset: -1], range: NSRange(location: 0, length: 1))
         imageString.addAttributes([NSAttributedString.Key.baselineOffset: -1], range: NSRange(location: 0, length: 1))
         text.append(NSAttributedString(string: " "))
         text.append(NSAttributedString(string: " "))
         text.append(imageString)
         text.append(imageString)
     }
     }
 
 
+    private func getSendingStateString(_ state: Int) -> String {
+        switch Int32(state) {
+        case DC_STATE_OUT_PENDING, DC_STATE_OUT_PREPARING:
+            return String.localized("a11y_delivery_status_sending")
+        case DC_STATE_OUT_DELIVERED:
+            return String.localized("a11y_delivery_status_delivered")
+        case DC_STATE_OUT_MDN_RCVD:
+            return String.localized("a11y_delivery_status_read")
+        case DC_STATE_OUT_FAILED:
+            return String.localized("a11y_delivery_status_error")
+        default:
+            return ""
+        }
+    }
+
     private func attachSendingState(_ state: Int, to text: NSMutableAttributedString) {
     private func attachSendingState(_ state: Int, to text: NSMutableAttributedString) {
         let imageAttachment = NSTextAttachment()
         let imageAttachment = NSTextAttachment()
         var offset = -2
         var offset = -2
@@ -358,23 +409,18 @@ public class BaseMessageCell: UITableViewCell {
         switch Int32(state) {
         switch Int32(state) {
         case DC_STATE_OUT_PENDING, DC_STATE_OUT_PREPARING:
         case DC_STATE_OUT_PENDING, DC_STATE_OUT_PREPARING:
             imageAttachment.image = #imageLiteral(resourceName: "ic_hourglass_empty_white_36pt").scaleDownImage(toMax: 14)?.maskWithColor(color: DcColors.grayDateColor)
             imageAttachment.image = #imageLiteral(resourceName: "ic_hourglass_empty_white_36pt").scaleDownImage(toMax: 14)?.maskWithColor(color: DcColors.grayDateColor)
-            imageAttachment.image?.accessibilityIdentifier = String.localized("a11y_delivery_status_sending")
         case DC_STATE_OUT_DELIVERED:
         case DC_STATE_OUT_DELIVERED:
             imageAttachment.image = #imageLiteral(resourceName: "ic_done_36pt").scaleDownImage(toMax: 18)
             imageAttachment.image = #imageLiteral(resourceName: "ic_done_36pt").scaleDownImage(toMax: 18)
-            imageAttachment.image?.accessibilityIdentifier = String.localized("a11y_delivery_status_delivered")
             offset = -3
             offset = -3
         case DC_STATE_OUT_MDN_RCVD:
         case DC_STATE_OUT_MDN_RCVD:
             imageAttachment.image = #imageLiteral(resourceName: "ic_done_all_36pt").scaleDownImage(toMax: 18)
             imageAttachment.image = #imageLiteral(resourceName: "ic_done_all_36pt").scaleDownImage(toMax: 18)
-            imageAttachment.image?.accessibilityIdentifier = String.localized("a11y_delivery_status_read")
             text.append(NSAttributedString(string: " "))
             text.append(NSAttributedString(string: " "))
             offset = -3
             offset = -3
         case DC_STATE_OUT_FAILED:
         case DC_STATE_OUT_FAILED:
             imageAttachment.image = #imageLiteral(resourceName: "ic_error_36pt").scaleDownImage(toMax: 17)
             imageAttachment.image = #imageLiteral(resourceName: "ic_error_36pt").scaleDownImage(toMax: 17)
-            imageAttachment.image?.accessibilityIdentifier = String.localized("a11y_delivery_status_error")
         default:
         default:
             imageAttachment.image = nil
             imageAttachment.image = nil
         }
         }
-
         let imageString = NSMutableAttributedString(attachment: imageAttachment)
         let imageString = NSMutableAttributedString(attachment: imageAttachment)
         imageString.addAttributes([.baselineOffset: offset],
         imageString.addAttributes([.baselineOffset: offset],
                                   range: NSRange(location: 0, length: 1))
                                   range: NSRange(location: 0, length: 1))
@@ -382,6 +428,7 @@ public class BaseMessageCell: UITableViewCell {
     }
     }
 
 
     override public func prepareForReuse() {
     override public func prepareForReuse() {
+        accessibilityLabel = nil
         textLabel?.text = nil
         textLabel?.text = nil
         textLabel?.attributedText = nil
         textLabel?.attributedText = nil
         topLabel.text = nil
         topLabel.text = nil

+ 1 - 0
deltachat-ios/Chat/Views/Cells/FileTextCell.swift

@@ -38,6 +38,7 @@ class FileTextCell: BaseMessageCell {
         }
         }
         
         
         fileView.configure(message: msg)
         fileView.configure(message: msg)
+        accessibilityLabel = "\(String.localized("document")), \(fileView.configureAccessibilityLabel())"
         super.update(msg: msg, messageStyle: messageStyle, isAvatarVisible: isAvatarVisible, isGroup: isGroup)
         super.update(msg: msg, messageStyle: messageStyle, isAvatarVisible: isAvatarVisible, isGroup: isGroup)
     }
     }
     
     

+ 3 - 0
deltachat-ios/Chat/Views/Cells/ImageTextCell.swift

@@ -50,6 +50,7 @@ class ImageTextCell: BaseMessageCell {
         tag = msg.id
         tag = msg.id
         if msg.type == DC_MSG_IMAGE, let image = msg.image {
         if msg.type == DC_MSG_IMAGE, let image = msg.image {
             contentImageView.image = image
             contentImageView.image = image
+            accessibilityLabel = String.localized("image")
             playButtonView.isHidden = true
             playButtonView.isHidden = true
             setAspectRatioFor(message: msg)
             setAspectRatioFor(message: msg)
         } else if msg.type == DC_MSG_GIF, let url = msg.fileURL {
         } else if msg.type == DC_MSG_GIF, let url = msg.fileURL {
@@ -60,9 +61,11 @@ class ImageTextCell: BaseMessageCell {
                                                                                        blue: 255),
                                                                                        blue: 255),
                                                                    size: CGSize(width: 500, height: 500)))
                                                                    size: CGSize(width: 500, height: 500)))
             playButtonView.isHidden = true
             playButtonView.isHidden = true
+            accessibilityLabel = String.localized("gif")
             setAspectRatioFor(message: msg)
             setAspectRatioFor(message: msg)
         } else if msg.type == DC_MSG_VIDEO, let url = msg.fileURL {
         } else if msg.type == DC_MSG_VIDEO, let url = msg.fileURL {
             playButtonView.isHidden = false
             playButtonView.isHidden = false
+            accessibilityLabel = String.localized("video")
             if let image = ThumbnailCache.shared.restoreImage(key: url.absoluteString) {
             if let image = ThumbnailCache.shared.restoreImage(key: url.absoluteString) {
                 contentImageView.image = image
                 contentImageView.image = image
                 setAspectRatioFor(message: msg, with: image, isPlaceholder: false)
                 setAspectRatioFor(message: msg, with: image, isPlaceholder: false)

+ 2 - 0
deltachat-ios/Chat/Views/DocumentPreview.swift

@@ -31,6 +31,7 @@ public class DocumentPreview: DraftPreview {
     override public func cancel() {
     override public func cancel() {
         fileView.prepareForReuse()
         fileView.prepareForReuse()
         delegate?.onCancelAttachment()
         delegate?.onCancelAttachment()
+        accessibilityLabel = nil
     }
     }
 
 
     override public func configure(draft: DraftModel) {
     override public func configure(draft: DraftModel) {
@@ -42,6 +43,7 @@ public class DocumentPreview: DraftPreview {
             tmpMsg.text = draft.text
             tmpMsg.text = draft.text
             fileView.configure(message: tmpMsg)
             fileView.configure(message: tmpMsg)
             self.delegate?.onAttachmentAdded()
             self.delegate?.onAttachmentAdded()
+            accessibilityLabel = "\(String.localized("attachment")), \(fileView.configureAccessibilityLabel())"
             isHidden = false
             isHidden = false
         } else {
         } else {
             isHidden = true
             isHidden = true

+ 4 - 2
deltachat-ios/Chat/Views/DraftPreview.swift

@@ -15,8 +15,7 @@ public class DraftPreview: UIView {
         view.isUserInteractionEnabled = true
         view.isUserInteractionEnabled = true
         view.translatesAutoresizingMaskIntoConstraints = false
         view.translatesAutoresizingMaskIntoConstraints = false
         view.addSubview(cancelImageView)
         view.addSubview(cancelImageView)
-        view.accessibilityLabel = String.localized("cancel")
-        view.isAccessibilityElement = true
+        view.isAccessibilityElement = false
         return view
         return view
     }()
     }()
 
 
@@ -75,6 +74,9 @@ public class DraftPreview: UIView {
         let recognizer = UITapGestureRecognizer(target: self, action: #selector(cancel))
         let recognizer = UITapGestureRecognizer(target: self, action: #selector(cancel))
         cancelButton.addGestureRecognizer(recognizer)
         cancelButton.addGestureRecognizer(recognizer)
         backgroundColor = DcColors.chatBackgroundColor
         backgroundColor = DcColors.chatBackgroundColor
+        isAccessibilityElement = true
+        let accessibilityCancelAction = UIAccessibilityCustomAction(name: String.localized("cancel"), target: self, selector: #selector(cancel))
+        accessibilityCustomActions = [accessibilityCancelAction]
     }
     }
 
 
     @objc public func cancel() {
     @objc public func cancel() {

+ 15 - 0
deltachat-ios/Chat/Views/FileView.swift

@@ -44,6 +44,7 @@ public class FileView: UIView {
     private lazy var fileImageView: UIImageView = {
     private lazy var fileImageView: UIImageView = {
         let imageView = UIImageView()
         let imageView = UIImageView()
         imageView.contentMode = .scaleAspectFit
         imageView.contentMode = .scaleAspectFit
+        isAccessibilityElement = false
         return imageView
         return imageView
     }()
     }()
 
 
@@ -61,6 +62,7 @@ public class FileView: UIView {
         title.translatesAutoresizingMaskIntoConstraints = false
         title.translatesAutoresizingMaskIntoConstraints = false
         title.numberOfLines = 3
         title.numberOfLines = 3
         title.lineBreakMode = .byCharWrapping
         title.lineBreakMode = .byCharWrapping
+        isAccessibilityElement = false
         return title
         return title
     }()
     }()
 
 
@@ -69,6 +71,7 @@ public class FileView: UIView {
         subtitle.font = UIFont.preferredItalicFont(for: .caption2)
         subtitle.font = UIFont.preferredItalicFont(for: .caption2)
         subtitle.translatesAutoresizingMaskIntoConstraints = false
         subtitle.translatesAutoresizingMaskIntoConstraints = false
         subtitle.numberOfLines = 1
         subtitle.numberOfLines = 1
+        isAccessibilityElement = false
         return subtitle
         return subtitle
     }()
     }()
 
 
@@ -106,6 +109,18 @@ public class FileView: UIView {
         fileSubtitle.text = message.getPrettyFileSize()
         fileSubtitle.text = message.getPrettyFileSize()
     }
     }
 
 
+    public func configureAccessibilityLabel() -> String {
+        var accessibilityFileTitle = ""
+        var accessiblityFileSubtitle = ""
+        if let fileTitleText = fileTitle.text {
+            accessibilityFileTitle = fileTitleText
+        }
+        if let subtitleText = fileSubtitle.text {
+            accessiblityFileSubtitle = subtitleText
+        }
+        
+        return "\(accessibilityFileTitle), \(accessiblityFileSubtitle)"
+    }
 
 
     public func prepareForReuse() {
     public func prepareForReuse() {
         fileImageView.image = nil
         fileImageView.image = nil

+ 3 - 0
deltachat-ios/Chat/Views/MediaPreview.swift

@@ -44,6 +44,7 @@ class MediaPreview: DraftPreview {
                 } else if let image = image {
                 } else if let image = image {
                     self.setAspectRatio(image: image)
                     self.setAspectRatio(image: image)
                     self.delegate?.onAttachmentAdded()
                     self.delegate?.onAttachmentAdded()
+                    self.accessibilityLabel = "\(String.localized("attachment")), \(draft.viewType == DC_MSG_GIF ? String.localized("gif") : String.localized("image"))"
                 }
                 }
             })
             })
             isHidden = false
             isHidden = false
@@ -65,6 +66,7 @@ class MediaPreview: DraftPreview {
                 }
                 }
             }
             }
             self.isHidden = false
             self.isHidden = false
+            self.accessibilityLabel = "\(String.localized("attachment")), \(String.localized("video"))"
         } else {
         } else {
             isHidden = true
             isHidden = true
         }
         }
@@ -74,6 +76,7 @@ class MediaPreview: DraftPreview {
         contentImageView.sd_cancelCurrentImageLoad()
         contentImageView.sd_cancelCurrentImageLoad()
         contentImageView.image = nil
         contentImageView.image = nil
         delegate?.onCancelAttachment()
         delegate?.onCancelAttachment()
+        accessibilityLabel = nil
     }
     }
 
 
     func setAspectRatio(image: UIImage) {
     func setAspectRatio(image: UIImage) {

+ 2 - 0
deltachat-ios/Chat/Views/QuotePreview.swift

@@ -23,6 +23,7 @@ public class QuotePreview: DraftPreview {
         quoteView.prepareForReuse()
         quoteView.prepareForReuse()
         delegate?.onCancelQuote()
         delegate?.onCancelQuote()
         quoteView.quote.numberOfLines = 3
         quoteView.quote.numberOfLines = 3
+        accessibilityLabel = nil
     }
     }
 
 
     override public func configure(draft: DraftModel) {
     override public func configure(draft: DraftModel) {
@@ -44,6 +45,7 @@ public class QuotePreview: DraftPreview {
                     quoteView.citeBar.backgroundColor = contact.color
                     quoteView.citeBar.backgroundColor = contact.color
                 }
                 }
             }
             }
+            accessibilityLabel = quoteView.configureAccessibilityLabel()
 
 
             isHidden = false
             isHidden = false
         } else {
         } else {

+ 21 - 0
deltachat-ios/Chat/Views/QuoteView.swift

@@ -8,6 +8,7 @@ public class QuoteView: UIView {
         view.clipsToBounds = true
         view.clipsToBounds = true
         view.layer.cornerRadius = 1.5
         view.layer.cornerRadius = 1.5
         view.translatesAutoresizingMaskIntoConstraints = false
         view.translatesAutoresizingMaskIntoConstraints = false
+        view.isAccessibilityElement = false
         return view
         return view
     }()
     }()
 
 
@@ -17,6 +18,7 @@ public class QuoteView: UIView {
         view.textColor = DcColors.grayTextColor
         view.textColor = DcColors.grayTextColor
         view.numberOfLines = 3
         view.numberOfLines = 3
         view.translatesAutoresizingMaskIntoConstraints = false
         view.translatesAutoresizingMaskIntoConstraints = false
+        view.isAccessibilityElement = false
         return view
         return view
     }()
     }()
 
 
@@ -24,6 +26,7 @@ public class QuoteView: UIView {
         let view = UILabel()
         let view = UILabel()
         view.font = UIFont.preferredFont(for: .caption1, weight: .semibold)
         view.font = UIFont.preferredFont(for: .caption1, weight: .semibold)
         view.translatesAutoresizingMaskIntoConstraints = false
         view.translatesAutoresizingMaskIntoConstraints = false
+        view.isAccessibilityElement = false
         return view
         return view
     }()
     }()
 
 
@@ -32,6 +35,7 @@ public class QuoteView: UIView {
         view.translatesAutoresizingMaskIntoConstraints = false
         view.translatesAutoresizingMaskIntoConstraints = false
         view.contentMode = .scaleAspectFill
         view.contentMode = .scaleAspectFill
         view.clipsToBounds = true
         view.clipsToBounds = true
+        view.isAccessibilityElement = false
         return view
         return view
     }()
     }()
 
 
@@ -45,6 +49,7 @@ public class QuoteView: UIView {
     }
     }
 
 
     private func setupSubviews() {
     private func setupSubviews() {
+        isAccessibilityElement = true
         addSubview(citeBar)
         addSubview(citeBar)
         addSubview(senderTitle)
         addSubview(senderTitle)
         addSubview(imagePreview)
         addSubview(imagePreview)
@@ -70,6 +75,22 @@ public class QuoteView: UIView {
         ])
         ])
     }
     }
 
 
+    public func configureAccessibilityLabel() -> String {
+        var accessibilitySenderTitle = ""
+        var accessibilityQuoteText = ""
+        var accessibilityQuoteImageText = ""
+        if let senderTiteText = senderTitle.text {
+            accessibilitySenderTitle = "\(senderTiteText), "
+        }
+        if let quoteText = quote.text {
+            accessibilityQuoteText = "\(quoteText), "
+        }
+        if imagePreview.image != nil {
+            accessibilityQuoteImageText = "\(String.localized("image")), "
+        }
+        return "\(accessibilitySenderTitle), \(accessibilityQuoteText), \(accessibilityQuoteImageText)"
+    }
+
     public func prepareForReuse() {
     public func prepareForReuse() {
         quote.text = nil
         quote.text = nil
         quote.attributedText = nil
         quote.attributedText = nil