I'd like to know when BarButton items gets the accessibility focus or loses the accessibility focus and so I implemented the informal protocol methods of UIAccessibilityFocus but it's not still firing.
extension UIBarButtonItem {
override open func accessibilityElementDidBecomeFocused() {
if self.accessibilityElementIsFocused() {
print("My element has become focused.")
}
}
override open func accessibilityElementDidLoseFocus() {
if self.accessibilityElementIsFocused() {
print("My element has lost focus.")
}
}
override open func accessibilityElementIsFocused() -> Bool {
if (self.accessibilityIdentifier == "hamburger") {
return true
} else {
return false
}
}
I imported the swift file into viewcontroller as well
#import "Sample-Swift.h"
then I tried subclassing and implemented the methods that also didn't work
.h header file
#import <UIKit/UIKit.h>
#import <UIKit/UIAccessibility.h>
NS_ASSUME_NONNULL_BEGIN
@interface HamburgerButton : UIBarButtonItem
@end
NS_ASSUME_NONNULL_END
.m implementation file
@implementation HamburgerButton
- (BOOL)isAccessibilityElement
{
return YES;
}
- (void)accessibilityElementDidBecomeFocused {
if ([self accessibilityElementIsFocused]) {
NSLog(@"My element has become focused.");
}
}
- (void)accessibilityElementDidLoseFocus {
if ([self accessibilityElementIsFocused]) {
NSLog(@"My element has lost focus.");
}
}
- (BOOL)accessibilityElementIsFocused {
if ([self.accessibilityIdentifier isEqualToString:@"hamburger"]) {
return YES;
} else {
return NO;
}
}
@end
Here is the implementation in view controller
HamburgerButton *leftButton = [[HamburgerButton alloc]
initWithTitle:@"Hamburger"
style:UIBarButtonItemStylePlain
target:self
action:@selector(flipView:)];
leftButton.accessibilityIdentifier=@"Hamburger";
leftButton.tag = 88;
leftButton.isAccessibilityElement = YES;
HamburgerButton *rightButton = [[HamburgerButton alloc]
initWithTitle:@"Chat"
style:UIBarButtonItemStylePlain
target:self
action:@selector(flipView:)];
rightButton.accessibilityIdentifier=@"Chat";
rightButton.tag = 89;
rightButton.isAccessibilityElement = YES;
self.navigationItem.leftBarButtonItem = leftButton;
self.navigationItem.rightBarButtonItem = rightButton;
Even though the focus comes and goes away from bar button , I'm not getting the call back on accessibilityElementDidBecomeFocused
Any ideas what could be done to get accessibilityElementDidBecomeFocused firing ?
I could achieve this functionality by the means of notification observer but it's not giving enough information about the receiver of focus so couldn't differentiate one bar button from the other.
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(hamburgerGotFocus:) name:UIAccessibilityElementFocusedNotification object:nil];
and find the selector method below
-(void)hamburgerGotFocus:(NSNotification *) notification{
NSLog(@"Focus:%@",notification);
UIView *receiver = notification.userInfo[@"UIAccessibilityFocusedElementKey"];
if(receiver!=nil){
NSString *strElement = [[NSString alloc]initWithFormat:@"%@",notification.userInfo[@"UIAccessibilityFocusedElementKey"]];
if([strElement containsString:@"UIButtonBarButton"]){
}
}
}
Here is the log of notification
2022-10-12 18:57:03.992859+0530 Sample[32427:1579550] Focus:NSConcreteNotification 0x280ac9980 {name = UIAccessibilityElementFocusedNotification; userInfo = {
UIAccessibilityAssistiveTechnologyKey = UIAccessibilityNotificationVoiceOverIdentifier;
UIAccessibilityFocusedElementKey = "<_UIButtonBarButton: 0x10690fce0; frame = (0 0; 49 44); tintColor = UIExtendedSRGBColorSpace 0 1 0 1; gestureRecognizers = <NSArray: 0x2804262e0>; layer = <CALayer: 0x280afa9e0>>";
}}
I tried doing this with UIlabel using Category and subclassing both worked
@interface SampleLabel : UILabel
@end
@implementation SampleLabel
- (void)accessibilityElementDidBecomeFocused {
NSLog(@"accessibilityIdentifier:%@",self.accessibilityIdentifier);
UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, @"sample label from subclass");
}
- (void)accessibilityElementDidLoseFocus {
if ([self accessibilityElementIsFocused]) {
NSLog(@"My element has lost focus.subclass");
}
}
- (BOOL)accessibilityElementIsFocused {
return YES;
}
@end
By means of category
@interface UILabel (SampleLabel1)
@end
@implementation UILabel (SampleLabel1)
- (void)accessibilityElementDidBecomeFocused {
NSLog(@"accessibilityIdentifier:%@",self.accessibilityIdentifier);
UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, @"sample label from category");
}
- (void)accessibilityElementDidLoseFocus {
if ([self accessibilityElementIsFocused]) {
NSLog(@"My element has lost focus.Category");
}
}
- (BOOL)accessibilityElementIsFocused {
return YES;
}
@end
I'm wondering whether accessibilityElementDidBecomeFocused is not compatible with UIBarButtonItem ?
FYI: I'm following this tutorial to implement accessibilityElementDidLoseFocus.
accessibilityElementDidBecomeFocused
is not firing for bar button but it's firing for UIButton. So I just created a bar button using UIButton like below and the problem is fixed
// Image
UIImage *img1 = [UIImage imageNamed:@"img1"];
// Button
UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeCustom];
[btn1 setImage:img1 forState:UIControlStateNormal];
btn1.frame = CGRectMake(0.0, 0.0, img1.size.width, img1.size.height);
btn1.tintColor = [UIColor greenColor];
[btn1 addTarget:self action:@selector(barButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
// Bar button
UIBarButtonItem *barButton1 = [[UIBarButtonItem alloc]initWithCustomView:btn1];
// Accessibility element
btn1.isAccessibilityElement = true;
img1.isAccessibilityElement = false;
btn1.accessibilityLabel = @"some accessibility text";
btn1.accessibilityTraits = UIAccessibilityTraitNone;
self.navigationItem.rightBarButtonItem = barButton1;