You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UIBarButtonItem的accessibilityElementDidBecomeFocused回调未触发问题

监听UIBarButtonItem无障碍焦点事件失败问题

问题描述

需要监听UIBarButtonItem获取/失去无障碍焦点的事件,实现了UIAccessibilityFocus非正式协议的方法,但回调始终未触发。


尝试的实现方案

方案1:Swift扩展UIBarButtonItem

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 {
        return self.accessibilityIdentifier == "hamburger"
    }
}

在Objective-C的ViewController中导入Swift桥接文件:

#import "Sample-Swift.h"

方案2:子类化UIBarButtonItem(HamburgerButton)

.h文件

#import <UIKit/UIKit.h>
#import <UIKit/UIAccessibility.h>

NS_ASSUME_NONNULL_BEGIN

@interface HamburgerButton : UIBarButtonItem

@end

NS_ASSUME_NONNULL_END

.m文件

@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 {
    return [self.accessibilityIdentifier isEqualToString:@"hamburger"];
}
@end

ViewController中使用子类实例

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;

实际测试中,焦点确实在两个BarButton间切换,但accessibilityElementDidBecomeFocused和accessibilityElementDidLoseFocus始终未触发。


后续尝试与疑问

更新1:通过通知监听,但无法区分具体按钮

注册无障碍焦点通知:

[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(hamburgerGotFocus:) name:UIAccessibilityElementFocusedNotification object:nil];

回调方法:

-(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"]){
            // 无法判断具体是哪个BarButtonItem
        }
    }
}

通知日志示例:

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>>";
}}

更新2:UILabel测试正常,怀疑兼容性问题

对UILabel使用分类和子类化的方式实现UIAccessibilityFocus协议方法,均能正常触发焦点回调。由此怀疑UIBarButtonItem是否与UIAccessibilityFocus非正式协议存在兼容性问题。


参考教程内容(翻译)

iOS无障碍开发:聚焦元素

  • 当VoiceOver等辅助技术聚焦到某个元素时,系统会调用accessibilityElementDidBecomeFocused方法;当元素失去焦点时,会调用accessibilityElementDidLoseFocus方法。
  • 这两个方法属于UIAccessibilityFocus非正式协议,主要针对继承自UIView的元素,用于在焦点变化时执行自定义逻辑。

内容的提问来源于stack exchange,提问作者Durai Amuthan.H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 13:50:24