39

画面上に視覚的に直感的に配置されているボタンがたくさんありますが、VoiceOver によって直感的な順序で読み取られません。これは、上や下などの特定のボタンが上下に配置されているためです。ただし、ナレーションは左から右へ、上から下へと読み上げを開始するようです。

これにより、ナレーションが「上」の直後に「下」を読み上げるのではなく、「上」の右側のボタンを読み上げます。

読み上げたいボタンをナレーションで読み上げさせるにはどうすればよいですか? ナレーションでスワイプして要素を循環させる機能を使用していることに言及する必要があります。

私のすべてのボタンは、UIView と UIButton のサブクラス化されたバージョンです。これは、私が使用するボタン イニシエータの例です。ピクセル数は無視してください - それが悪い形であることはわかっていますが、現時点ではピンチです:

UIButton* createSpecialButton(CGRect frame, 
                                 NSString* imageName, 
                                 NSString* activeImageName,
                                 id target,
                                 SEL obClickHandler) 
{
    UIButton* b = [UIButton buttonWithType:UIButtonTypeCustom];
    [b setImage:[GlobalHelper nonCachedImage:imageName ofType:@"png"] 
       forState:UIControlStateNormal];
    [b setImage:[GlobalHelper nonCachedImage:activeImageName ofType:@"png"] 
       forState:UIControlStateHighlighted];
    [b addTarget:target action:obClickHandler forControlEvents:UIControlEventTouchUpInside];    
    b.frame= frame;
    return b;
}


- (UIButton *) createSendButton {
    CGFloat yMarker = 295;

    UIButton* b = createSpecialButton(CGRectMake(160, yMarker, 70, 45),
                                          @"Share_Btn",
                                          @"Share_Selected_Btn",
                                          self,
                                          @selector(sendAction));
    b.accessibilityHint = @"Send it!";
    b.accessibilityLabel = @"Stuff for voiceover to be added";
    [self.view addSubview:b];

    return b;
}
4

9 に答える 9

30

これに対する最も簡単な答えUIViewは、ボタンを含むサブクラスを作成することであり、システムからのアクセシビリティ呼び出しに対して異なる応答をします。これらの重要な呼び出しは次のとおりです。

-(NSInteger)accessibilityElementCount
-(id)accessibilityElementAtIndex:
-(NSInteger)indexOfAccessibilityElement:

私はこれらの質問のいくつかを見て、に1つ答えましたが、VoiceOverフォーカスを並べ替える方法の一般的な例を見ていません。UIViewそこで、アクセス可能なサブビューをタグでVoiceOverに公開するサブクラスを作成する方法の例を次に示します。

AccessibilitySubviewsOrderedByTag.h

#import <UIKit/UIKit.h>
@interface AccessibilitySubviewsOrderedByTag : UIView
@end

AccessibilitySubviewsOrderedByTag.m

#import "AccessibilityDirectional.h"
@implementation AccessibilitySubviewsOrderedByTag {
    NSMutableArray *_accessibilityElements;
}
    //Lazy loading accessor, avoids instantiating in initWithCoder, initWithFrame, or init.
-(NSMutableArray *)accessibilityElements{
    if (!_accessibilityElements){
        _accessibilityElements = [[NSMutableArray alloc] init];
    }
    return _accessibilityElements;
}
// Required accessibility methods...
-(BOOL)isAccessibilityElement{
    return NO;
}
-(NSInteger)accessibilityElementCount{
    return [self accessibilityElements].count;
}
-(id)accessibilityElementAtIndex:(NSInteger)index{
    return [[self accessibilityElements] objectAtIndex:index];
}
-(NSInteger)indexOfAccessibilityElement:(id)element{
    return [[self accessibilityElements] indexOfObject:element];
}
// Handle added and removed subviews...
-(void)didAddSubview:(UIView *)subview{
    [super didAddSubview:subview];
    if ([subview isAccessibilityElement]){
        // if the new subview is an accessibility element add it to the array and then sort the array.
        NSMutableArray *accessibilityElements = [self accessibilityElements];
        [accessibilityElements addObject:subview];
        [accessibilityElements sortUsingComparator:^NSComparisonResult(id obj1, id obj2){
            // Here we'll sort using the tag, but really any sort is possible.
            NSInteger one = [(UIView *)obj1 tag];
            NSInteger two = [(UIView *)obj2 tag];
            if (one < two) return NSOrderedAscending;
            if (one > two) return NSOrderedDescending;
            return NSOrderedSame;
        }];
    }
}
-(void)willRemoveSubview:(UIView *)subview{
    [super willRemoveSubview:subview];
    // Clean up the array. No check since removeObject: is a safe call.
    [[self accessibilityElements] removeObject:subview];
}
@end

次に、このビューのインスタンスでボタンを囲み、ボタンのタグプロパティを基本的にフォーカスの順序に設定します。

于 2012-11-15T22:41:08.277 に答える
5

これが古いスレッドであることは知っていますが、それを行う最も簡単な方法は、UIView をそのままサブクラス化することです (Swift 3)。次に、ストーリーボードのメイン UIView タイプを変更してAccessibiltySubviewsOrderedByTag、順番に読み取りたい各サブビューのタグを更新します。

class AccessibilitySubviewsOrderedByTag: UIView {
    
    override func layoutSubviews() {
        
        self.accessibilityElements = [UIView]()
        for accessibilitySubview in self.subviews {
            if accessibilitySubview.isAccessibilityElement {
                self.accessibilityElements?.append(accessibilitySubview)
            }
        }
        self.accessibilityElements?.sort(by: {($0 as AnyObject).tag < ($1 as AnyObject).tag})
    }
}
于 2018-02-09T16:27:04.063 に答える
3

の配列を設定するウェズリーの答えを試しましたaccessibilityElementsが、うまくいきませんでした。

Apple には、コード内の例を含むいくつかのドキュメントがあります。基本的に、セル (親ビュー) のアクセシビリティ ラベルを子ビューのアクセシビリティ ラベルの値に設定します。

[cell setAccessibilityLabel:[NSString stringWithFormat:@"%@, %@", cityLabel, temperatureLabel]];

これが私のために働いたものです。

于 2015-12-22T18:44:05.240 に答える
1

ストーリーボードでできると思います。VoiceOver の順序は、ドキュメント アウトライン内のビューの順序によって決まります。

ビュー階層内のビューを正しい順序でドラッグ アンド ドロップするだけです。

編集:

申し訳ありませんが、評判が 10 になるまでスクリーンショットを投稿できません。ストーリーボードでは、ドキュメント アウトラインは、サブビューを含むシーンがリストされている左側の領域です。ここでは、サブビューは互いに下に並べられています。この順序を変更すると、VoiceOver の読み上げ順序が変更されます。

于 2015-02-16T13:06:43.920 に答える