Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add accessibility support #3

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions ISMessages/Classes/ISMessages.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ @interface ISMessages ()
// Content
@property (nonatomic, copy) NSString* titleString;
@property (nonatomic, copy) NSString* messageString;
@property (nonatomic, copy) NSString* alertTypeAcessibilityLabel;
@property (strong, nonatomic) UIImage* iconImage;

// Interaction
Expand Down Expand Up @@ -165,6 +166,10 @@ - (void)viewDidLoad {
self.view.alpha = 0.7f;
self.view.layer.cornerRadius = 0.f;
self.view.layer.masksToBounds = YES;

// Make sure accessibility focus stays within the ISMessage.
self.view.accessibilityViewIsModal = true;

[self constructAlertCardView];

}
Expand All @@ -175,6 +180,11 @@ - (void)viewWillAppear:(BOOL)animated {
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
}

- (bool)accessibilityPerformEscape {
[self hide:@(YES)];
return true;
}

- (void)deviceOrientationDidChange:(NSNotification *)notification {
[self hide:@(YES)];
}
Expand All @@ -198,6 +208,9 @@ - (void)constructAlertCardView {
UIImageView* iconImage = [[UIImageView alloc] initWithFrame:CGRectMake(kDefaultInset, (_alertViewHeight - _iconImageSize.height + heightCorrection + insetCorrection) / 2.f, _iconImageSize.width, _iconImageSize.height)];
iconImage.contentMode = UIViewContentModeScaleAspectFit;
iconImage.image = _iconImage;
iconImage.isAccessibilityElement = true;
iconImage.accessibilityTraits = UIAccessibilityTraitButton;
iconImage.accessibilityLabel = NSLocalizedString(@"OK", comment: "");
[alertView addSubview:iconImage];

heightCorrection = heightCorrection + (_alertPosition == ISAlertPositionBottom ? 10.0f : insetCorrection + (_statusBarHeight > 0.f ? (_statusBarHeight / 4) : 0.f));
Expand All @@ -210,6 +223,9 @@ - (void)constructAlertCardView {
titleLabel.textColor = _titleLabelTextColor;
titleLabel.font = _titleLabelFont;
titleLabel.text = _titleString;
if (self.alertTypeAcessibilityLabel != nil) {
titleLabel.accessibilityLabel = [NSString stringWithFormat:@"%@, %@", self.alertTypeAcessibilityLabel, _titleString];
}
[alertView addSubview:titleLabel];

UILabel* messageLabel = [UILabel new];
Expand All @@ -222,6 +238,9 @@ - (void)constructAlertCardView {
messageLabel.text = _messageString;
[alertView addSubview:messageLabel];

// Sets custom order of accessibility elements.
alertView.accessibilityElements = @[titleLabel, messageLabel, iconImage];

if (_hideOnSwipe) {
UISwipeGestureRecognizer* swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(gestureAction)];
swipeGesture.direction = UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown;
Expand Down Expand Up @@ -283,8 +302,11 @@ - (void)showInMain {
}];

[currentAlertArray addObject:self];

if (_duration > 0.5f) {

UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, self.view);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, just noticed this was LayoutChanged, instead of ScreenChanged. ScreenChanged emits a helpful sound for the user, like with default UIAlerts.

@EddyVerbruggen want me to fix this in another PR?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea, thank you! I'm just about to test your PR 👍


// Auto-hide if significant duration is set and VoiceOver is off.
if (_duration > 0.5f && !UIAccessibilityIsVoiceOverRunning()) {
[self performSelector:@selector(hide:) withObject:@(NO) afterDelay:_duration];
}
}
Expand Down Expand Up @@ -342,6 +364,7 @@ - (void)hideInMain {
self.view.alpha = 0.7;
self.view.frame = CGRectMake(0, alertYPosition, self.view.frame.size.width, self.view.frame.size.height);
[self.view removeFromSuperview];
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil);
}];

}
Expand All @@ -364,6 +387,7 @@ - (void)forceHideInMain {
} completion:^(BOOL finished) {
[activeAlert.view removeFromSuperview];
[activeAlert removeFromParentViewController];
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil);
}];

}
Expand Down Expand Up @@ -443,27 +467,31 @@ - (void)configureViewForAlertType:(ISAlertType)alertType iconImage:(UIImage*)ico

switch (alertType) {
case ISAlertTypeSuccess: {
self.alertTypeAcessibilityLabel = NSLocalizedString(@"Success", comment: "");
self.alertViewBackgroundColor = [UIColor colorWithRed:31.f/255.f green:177.f/255.f blue:138.f/255.f alpha:1.f];
if (!_iconImage) {
self.iconImage = [self imageNamed:@"isSuccessIcon"];
}
break;
}
case ISAlertTypeError: {
self.alertTypeAcessibilityLabel = NSLocalizedString(@"Error", comment: "");
self.alertViewBackgroundColor = [UIColor colorWithRed:255.f/255.f green:91.f/255.f blue:65.f/255.f alpha:1.f];
if (!_iconImage) {
self.iconImage = [self imageNamed:@"isErrorIcon"];
}
break;
}
case ISAlertTypeWarning: {
self.alertTypeAcessibilityLabel = NSLocalizedString(@"Warning", comment: "");
self.alertViewBackgroundColor = [UIColor colorWithRed:255.f/255.f green:134.f/255.f blue:0.f/255.f alpha:1.f];
if (!_iconImage) {
self.iconImage = [self imageNamed:@"isWarningIcon"];
}
break;
}
case ISAlertTypeInfo: {
self.alertTypeAcessibilityLabel = NSLocalizedString(@"Info", comment: "");
self.alertViewBackgroundColor = [UIColor colorWithRed:75.f/255.f green:107.f/255.f blue:122.f/255.f alpha:1.f];
if (!_iconImage) {
self.iconImage = [self imageNamed:@"isInfoIcon"];
Expand Down