2016-10-21 2 views
0

В настоящее время наше приложение для iPhone поддерживает IOS 8/9/10. У меня возникают трудности с поддержкой доступа к голосовым сообщениям для пользовательского UITableViewCell. Я прошел следующие SO-сообщения, но ни одно из предложений не сработало. Я хочу, чтобы отдельные компоненты были доступны.Невозможно настроить голосовую доступность для пользовательского UITableViewCell

  1. Custom UITableview cell accessibility not working correctly
  2. Custom UITableViewCell trouble with UIAccessibility elements
  3. Accessibility in custom drawn UITableViewCell
  4. https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/iPhoneAccessibility/Making_Application_Accessible/Making_Application_Accessible.html#//apple_ref/doc/uid/TP40008785-CH102-SW10
  5. http://useyourloaf.com/blog/voiceover-accessibility/

К сожалению для меня, клетка не обнаруживается доступности инспектора. Есть ли способ озвучить возможность доступа к отдельным элементам в ячейке просмотра таблицы? При отладке этой проблемы на обоих устройствах и в симуляторе я обнаружил, что XCode вызывает функцию isAccessibleElement. Когда функция возвращает NO, остальные методы пропускаются. Я тестирую IOS 9.3 в XCode.

Моя пользовательская ячейка просмотра таблицы состоит из ярлыка и переключателя, как показано ниже.

Custom UITableView Cell with a label and a switch

Метка добавляется к просмотру контента, в то время как переключатель добавляется вид пользовательских аксессуаров.

Определение интерфейса приводится ниже

@interface MyCustomTableViewCell : UITableViewCell 

///Designated initializer 
- (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier; 


///Property that determines if the switch displayed in the cell is ON or OFF. 
@property (nonatomic, assign) BOOL switchIsOn; 

///The label to be displayed for the alert 
@property (nonatomic, strong) UILabel *alertLabel; 

@property (nonatomic, strong) UISwitch *switch; 

#pragma mark - Accessibility 
// Used for setting up accessibility values. This is used to generate accessibility labels of 
// individual elements. 
@property (nonatomic, strong) NSString* accessibilityPrefix; 

-(void)setAlertHTMLText:(NSString*)title; 


@end 

Блок реализации приведен ниже

@interface MyCustomTableViewCell() 

    @property (nonatomic, strong) UIView *customAccessoryView; 
    @property (nonatomic, strong) NSString *alertTextString; 
    @property (nonatomic, strong) NSMutableArray* accessibleElements; 
@end 

@implementation MyCustomTableViewCell 


    - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier 
    { 
     if(self = [super initWithStyle:UITableViewCellStyleDefault   
      reuseIdentifier:reuseIdentifier]) { 
      [self configureTableCell]; 
     } 
     return self; 
    } 


    - (void)configureTableCell 
    { 
     if (!_accessibleElements) { 
      _accessibleElements = [[NSMutableArray alloc] init]; 
     } 


    //Alert label 
    self.alertLabel = [[self class] makeAlertLabel]; 
    [self.contentView setIsAccessibilityElement:YES]; 
// 
    [self.contentView addSubview:self.alertLabel]; 

    // Custom AccessoryView for easy styling. 
    self.customAccessoryView = [[UIView alloc] initWithFrame:CGRectZero]; 
    [self.customAccessoryView setIsAccessibilityElement:YES]; 
    [self.contentView addSubview:self.customAccessoryView]; 

//switch 
    self.switch = [[BAUISwitch alloc] initWithFrame:CGRectZero]; 
    [self.switch addTarget:self action:@selector(switchWasFlipped:) forControlEvents:UIControlEventValueChanged]; 
[self.switch setIsAccessibilityElement:YES]; 
[self.switch setAccessibilityTraits:UIAccessibilityTraitButton]; 
[self.switch setAccessibilityLabel:@""]; 
[self.switch setAccessibilityHint:@""]; 
self.switch.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; 
[self.customAccessoryView addSubview:self.switch]; 
} 

+ (UILabel *)makeAlertLabel 
{ 
    UILabel *alertLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 
    alertLabel.backgroundColor = [UIColor clearColor]; 
    alertLabel.HTMLText = @""; 
    alertLabel.numberOfLines = 0; 
    alertLabel.lineBreakMode = LINE_BREAK_WORD_WRAP 
    [alertLabel setIsAccessibilityElement:YES]; 
    return alertLabel; 
} 

-(void)setAlertHTMLText:(NSString*)title{ 
    _alertTextString = [NSString stringWithString:title]; 
    [self.alertLabel setText:_alertTextString]; 
} 


- (BOOL)isAccessibilityElement { 
    return NO; 
} 

    // The view encapsulates the following elements for the purposes of  
// accessibility. 
-(NSArray*) accessibleElements { 
    if (_accessibleElements && [_accessibleElements count] > 0) { 
     [_accessibleElements removeAllObjects]; 
    } 
    // Fetch a new copy as the values may have changed. 
    _accessibleElements = [[NSMutableArray alloc] init]; 
    UIAccessibilityElement* alertLabelElement = 
    [[UIAccessibilityElement alloc] initWithAccessibilityContainer:self]; 
    //alertLabelElement.accessibilityFrame = [self convertRect:self.contentView.frame toView:nil]; 
    alertLabelElement.accessibilityLabel = _alertTextString; 
    alertLabelElement.accessibilityTraits = UIAccessibilityTraitStaticText; 
    [_accessibleElements addObject:alertLabelElement]; 


    UIAccessibilityElement* switchElement = 
     [[UIAccessibilityElement alloc] initWithAccessibilityContainer:self]; 
    // switchElement.accessibilityFrame = [self convertRect:self.customAccessoryView.frame toView:nil]; 
    switchElement.accessibilityTraits = UIAccessibilityTraitButton; 
    // If you want custom values, just override it in the invoking function. 
    NSMutableString* accessibilityString = 
     [NSMutableString stringWithString:self.accessibilityPrefix]; 
    [accessibilityString appendString:@" Switch "]; 
    if (self.switchh.isOn) { 
     [accessibilityString appendString:@"On"]; 
    } else { 
     [accessibilityString appendString:@"Off"]; 
    } 
    switchElement.accessibilityLabel = [accessibilityString copy]; 

    [_accessibleElements addObject:switchElement]; 
    } 
    return _accessibleElements; 
} 

// In case accessibleElements is not initialized. 
- (void) initializeAccessibleElements { 
    _accessibleElements = [self accessibleElements]; 
} 

- (NSInteger)accessibilityElementCount 
{ 
    return [_accessibleElements count] 
} 

- (id)accessibilityElementAtIndex:(NSInteger)index 
    { 
    [self initializeAccessibleElements]; 
    return [_accessibleElements objectAtIndex:index]; 
} 

- (NSInteger)indexOfAccessibilityElement:(id)element 
{ 
    [self initializeAccessibleElements]; 
    return [_accessibleElements indexOfObject:element]; 
} 
@end 
+0

сделал и установить доступность для представления таблицы и ячейки? Покажите код, связанный с этим. –

+0

также вам не нужно переопределить accessibleElements, вы можете просто передать массив accessibleElements собственности. –

+0

@TejaNandamuri Я установил доступность ячейки контейнера табличного представления к «Нет» в «isAccessibleElement», поскольку это представление контейнера. Этот блок кода предоставляется в блоке кода. К вашему второму комментарию я должен каждый раз вычислять доступные элементы, так как пользователь может переключать переключатель. Я отражу значение, если это произойдет. – Kartik

ответ

4

Прежде всего, от картины, которую вы описали, я не знаю, почему вы хотели бы различать различные элементы в ячейке. Как правило, Apple сохраняет каждую ячейку единым элементом доступности. Отличное место для просмотра ожидаемого поведения IOS VO для ячеек с ярлыками и переключателями в приложении «Настройки».

Если вы по-прежнему считаете, что лучший способ обработки ваших ячеек состоит в том, чтобы они содержали отдельные элементы, то это фактически поведение по умолчанию ячейки , когда сам UITableViewCell не имеет метки доступности. Итак, я изменил ваш код ниже и запустил его на своем устройстве iOS (работает с 9.3), и он работает так, как вам было описано.

Вы заметите несколько вещей.

  1. Я удалил все пользовательские коды accessibilityElements. Это не обязательно.
  2. Я удалил переопределение isAccessibilityElement в подклассе UITableViewCell. Мы хотим поведение по умолчанию.
  3. Я прокомментировал настройку представления содержимого как элемента accessibilityElement - мы хотим, чтобы это было НЕТ, чтобы дерево-строитель выглядел внутри него для элементов.
  4. Я установил customAccessoryView isAccessibilityElement в NO, а также по той же причине, что и выше. Как правило, НЕТ говорит: «Продолжайте смотреть вниз по дереву», и ДА говорит: «Остановитесь здесь, это мой лист в отношении доступности."

Я надеюсь, что это полезно. Еще раз, я действительно призываю вас, чтобы имитировать модели VO Apple, при проектировании для доступности. Я думаю, что это удивительное, что вы делаете, что ваше приложение доступно!

#import "MyCustomTableViewCell.h" 
 

 
@interface MyCustomTableViewCell() 
 

 
@property (nonatomic, strong) UIView *customAccessoryView; 
 
@property (nonatomic, strong) NSString *alertTextString; 
 
@property (nonatomic, strong) NSMutableArray* accessibleElements; 
 
@end 
 

 
@implementation MyCustomTableViewCell 
 

 
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
 
{ 
 
    if(self = [super initWithStyle:UITableViewCellStyleDefault 
 
        reuseIdentifier:reuseIdentifier]) { 
 
     [self configureTableCell]; 
 
    } 
 
    return self; 
 
} 
 

 
// just added this here to get the cell to lay out for myself 
 
- (void)layoutSubviews { 
 
    [super layoutSubviews]; 
 
    
 
    const CGFloat margin = 8; 
 
    
 
    CGRect b = self.bounds; 
 
    
 
    CGSize labelSize = [self.alertLabel sizeThatFits:b.size]; 
 
    CGFloat maxX = CGRectGetMaxX(b); 
 
    self.alertLabel.frame = CGRectMake(margin, margin, labelSize.width, labelSize.height); 
 
    
 
    CGSize switchSize = [self.mySwitch sizeThatFits:b.size]; 
 
    self.customAccessoryView.frame = CGRectMake(maxX - switchSize.width - margin * 2, b.origin.y + margin, switchSize.width + margin * 2, switchSize.height); 
 
    self.mySwitch.frame = CGRectMake(margin, 0, switchSize.width, switchSize.height); 
 
} 
 

 

 
- (void)configureTableCell 
 
{ 
 
    //Alert label 
 
    self.alertLabel = [[self class] makeAlertLabel]; 
 
    //[self.contentView setIsAccessibilityElement:YES]; 
 
    // 
 
    [self.contentView addSubview:self.alertLabel]; 
 
    
 
    // Custom AccessoryView for easy styling. 
 
    self.customAccessoryView = [[UIView alloc] initWithFrame:CGRectZero]; 
 
    [self.customAccessoryView setIsAccessibilityElement:NO]; // Setting this to NO tells the the hierarchy builder to look inside 
 
    [self.contentView addSubview:self.customAccessoryView]; 
 
    self.customAccessoryView.backgroundColor = [UIColor purpleColor]; 
 
    
 
    //switch 
 
    self.mySwitch = [[UISwitch alloc] initWithFrame:CGRectZero]; 
 
    //[self.mySwitch addTarget:self action:@selector(switchWasFlipped:) forControlEvents:UIControlEventValueChanged]; 
 
    [self.mySwitch setIsAccessibilityElement:YES]; // This is default behavior 
 
    [self.mySwitch setAccessibilityTraits:UIAccessibilityTraitButton]; // No tsure why this is here 
 
    [self.mySwitch setAccessibilityLabel:@"my swich"]; 
 
    [self.mySwitch setAccessibilityHint:@"Tap to do something."]; 
 
    self.mySwitch.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; 
 
    [self.customAccessoryView addSubview:self.mySwitch]; 
 
} 
 

 
+ (UILabel *)makeAlertLabel 
 
{ 
 
    UILabel *alertLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 
 
    alertLabel.backgroundColor = [UIColor clearColor]; 
 
    alertLabel.text = @""; 
 
    alertLabel.numberOfLines = 0; 
 
    [alertLabel setIsAccessibilityElement:YES]; 
 
    return alertLabel; 
 
} 
 

 
-(void)setAlertHTMLText:(NSString*)title{ 
 
    _alertTextString = [NSString stringWithString:title]; 
 
    [self.alertLabel setText:_alertTextString]; 
 
} 
 

 
@end

+1

Привет, Соммер, прошу прощения. для задержки. Ваше предложение работало чудесно. – Kartik