diff --git a/LNPopupController/LNPopupController.xcodeproj/project.pbxproj b/LNPopupController/LNPopupController.xcodeproj/project.pbxproj index e6593b7d..cc6f23d9 100644 --- a/LNPopupController/LNPopupController.xcodeproj/project.pbxproj +++ b/LNPopupController/LNPopupController.xcodeproj/project.pbxproj @@ -85,10 +85,10 @@ 3947E1B01B61CE4A0001178B /* LNPopupController.h */, 3947E1B11B61CE4A0001178B /* LNPopupController.m */, 394A85BB1B6306AE004FFC61 /* LNPopupItem+Private.h */, + 394A85B81B6304F5004FFC61 /* LNPopupItem.m */, 394A85C71B63FB96004FFC61 /* UIViewController+LNPopupSupportPrivate.h */, 394A85C81B63FE52004FFC61 /* UIViewController+LNPopupSupportPrivate.m */, 3947E1A01B61CD1F0001178B /* UIViewController+LNPopupSupport.m */, - 394A85B81B6304F5004FFC61 /* LNPopupItem.m */, ); name = "Private Implementation"; path = Private; diff --git a/LNPopupController/LNPopupController/LNPopupItem.h b/LNPopupController/LNPopupController/LNPopupItem.h index 6d706fa8..01d41514 100644 --- a/LNPopupController/LNPopupController/LNPopupItem.h +++ b/LNPopupController/LNPopupController/LNPopupItem.h @@ -46,4 +46,18 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface LNPopupItem (Accessibility) + +/** + * The accessibility label of the progress, in a localized string. + */ +@property (nonatomic, copy, nullable) NSString* accessibilityProgressLabel; + +/** + * The accessibility value of the progress, in a localized string. + */ +@property (nonatomic, copy, nullable) NSString* accessibilityProgressValue; + +@end + NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/LNPopupController/LNPopupController/Private/LNPopupBar+Private.h b/LNPopupController/LNPopupController/Private/LNPopupBar+Private.h index e57625b6..42cd37d5 100644 --- a/LNPopupController/LNPopupController/Private/LNPopupBar+Private.h +++ b/LNPopupController/LNPopupController/Private/LNPopupBar+Private.h @@ -36,6 +36,11 @@ extern const CGFloat LNPopupBarHeight; @property (nonatomic, strong) UIProgressView* progressView; +@property (nonatomic, copy) NSString* accessibilityCenterLabel; +@property (nonatomic, copy) NSString* accessibilityCenterHint; +@property (nonatomic, copy) NSString* accessibilityProgressLabel; +@property (nonatomic, copy) NSString* accessibilityProgressValue; + - (void)_delayBarButtonLayout; - (void)_layoutBarButtonItems; diff --git a/LNPopupController/LNPopupController/Private/LNPopupBar.m b/LNPopupController/LNPopupController/Private/LNPopupBar.m index 9522b676..1363026b 100644 --- a/LNPopupController/LNPopupController/Private/LNPopupBar.m +++ b/LNPopupController/LNPopupController/Private/LNPopupBar.m @@ -53,13 +53,6 @@ - (nonnull instancetype)initWithFrame:(CGRect)frame _toolbar.layer.masksToBounds = YES; [self addSubview:_toolbar]; - _progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault]; - _progressView.translatesAutoresizingMaskIntoConstraints = NO; - _progressView.trackImage = [UIImage alloc]; - [_toolbar addSubview:_progressView]; - [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_progressView(1)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_progressView)]]; - [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_progressView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_progressView)]]; - _highlightView = [[UIView alloc] initWithFrame:self.bounds]; _highlightView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; _highlightView.userInteractionEnabled = NO; @@ -70,10 +63,23 @@ - (nonnull instancetype)initWithFrame:(CGRect)frame _titlesView = [[UIView alloc] initWithFrame:fullFrame]; _titlesView.userInteractionEnabled = NO; _titlesView.autoresizingMask = UIViewAutoresizingNone; + + _titlesView.accessibilityTraits = UIAccessibilityTraitButton; + _titlesView.isAccessibilityElement = YES; + [self _layoutTitles]; [self.toolbar addSubview:_titlesView]; + _progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault]; + _progressView.translatesAutoresizingMaskIntoConstraints = NO; + _progressView.trackImage = [UIImage alloc]; + [_toolbar addSubview:_progressView]; + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_progressView(1)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_progressView)]]; + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_progressView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_progressView)]]; + _needsLabelsLayout = YES; + + self.accessibilityLabel = @"Popup Asshole"; } return self; @@ -224,6 +230,34 @@ - (void)setSubtitle:(NSString *)subtitle [self _setNeedsTitleLayout]; } +- (void)setAccessibilityCenterHint:(NSString *)accessibilityCenterHint +{ + _accessibilityCenterHint = accessibilityCenterHint; + + [self _setNeedsAccessibilityUpdate]; +} + +- (void)setAccessibilityCenterLabel:(NSString *)accessibilityCenterLabel +{ + _accessibilityCenterLabel = accessibilityCenterLabel; + + [self _setNeedsAccessibilityUpdate]; +} + +- (void)setAccessibilityProgressLabel:(NSString *)accessibilityProgressLabel +{ + _accessibilityProgressLabel = accessibilityProgressLabel; + + _progressView.accessibilityLabel = accessibilityProgressLabel; +} + +- (void)setAccessibilityProgressValue:(NSString *)accessibilityProgressValue +{ + _accessibilityProgressValue = accessibilityProgressValue; + + _progressView.accessibilityValue = accessibilityProgressValue; +} + - (__MarqueeLabel*)_newMarqueeLabel { __MarqueeLabel* rv = [[__MarqueeLabel alloc] initWithFrame:_titlesView.bounds rate:20 andFadeLength:10]; @@ -313,21 +347,6 @@ - (void)_layoutTitles titleLabelFrame.origin.y -= _titleLabel.font.lineHeight / 2; subtitleLabelFrame.origin.y += _subtitleLabel.font.lineHeight / 2; - if(_needsLabelsLayout == YES) - { -// NSTimeInterval titleDuration = [_titleLabel animationDuration]; -// NSTimeInterval subtitleDuration = [_subtitleLabel animationDuration]; -// -// if(_titleLabel.animationDuration < _subtitleLabel.animationDuration) -// { -// _titleLabel.animationDelayAfter = -20; //(subtitleDuration - titleDuration); -// } -// else -// { -// _subtitleLabel.animationDelayAfter = - 20;//(subtitleDuration - titleDuration); -// } - } - _subtitleLabel.frame = subtitleLabelFrame; _subtitleLabel.hidden = NO; @@ -349,12 +368,45 @@ - (void)_layoutTitles } } + [self _setNeedsAccessibilityUpdate]; + _titleLabel.frame = titleLabelFrame; _needsLabelsLayout = NO; }); } +- (void)_setNeedsAccessibilityUpdate +{ + if(_accessibilityCenterLabel.length > 0) + { + _titlesView.accessibilityLabel = _accessibilityCenterLabel; + } + else + { + NSMutableString* accessibilityLabel = [NSMutableString new]; + if(_title.length > 0) + { + [accessibilityLabel appendString:_title]; + [accessibilityLabel appendString:@"\n"]; + } + if(_subtitle.length > 0) + { + [accessibilityLabel appendString:_subtitle]; + } + _titlesView.accessibilityLabel = accessibilityLabel; + } + + if(_accessibilityCenterHint.length > 0) + { + _titlesView.accessibilityHint = _accessibilityCenterHint; + } + else + { + _titlesView.accessibilityHint = NSLocalizedString(@"Double tap to open.", @""); + } +} + - (void)_setNeedsTitleLayout { _needsLabelsLayout = YES; diff --git a/LNPopupController/LNPopupController/Private/LNPopupCloseButton.m b/LNPopupController/LNPopupController/Private/LNPopupCloseButton.m index 9796bead..f56e9aa7 100644 --- a/LNPopupController/LNPopupController/Private/LNPopupCloseButton.m +++ b/LNPopupController/LNPopupController/Private/LNPopupCloseButton.m @@ -56,6 +56,8 @@ - (nonnull instancetype)initWithFrame:(CGRect)frame [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [self setImage:[UIImage imageNamed:@"DismissChevron" inBundle:[NSBundle bundleForClass:self.class] compatibleWithTraitCollection:nil] forState:UIControlStateNormal]; + + self.accessibilityLabel = NSLocalizedString(@"Close", @""); } return self; diff --git a/LNPopupController/LNPopupController/Private/LNPopupController.m b/LNPopupController/LNPopupController/Private/LNPopupController.m index b2e56b90..1e36b873 100644 --- a/LNPopupController/LNPopupController/Private/LNPopupController.m +++ b/LNPopupController/LNPopupController/Private/LNPopupController.m @@ -345,10 +345,16 @@ - (void)_transitionToState:(LNPopupPresentationState)state animated:(BOOL)animat [_popupBar addGestureRecognizer:self.popupContentView.popupInteractionGestureRecognizer]; [_popupBar _setTitleViewMarqueesPaused:NO]; + + _popupContentView.accessibilityViewIsModal = NO; + UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil); } else if(state == LNPopupPresentationStateOpen) { [_popupBar _setTitleViewMarqueesPaused:YES]; + + _popupContentView.accessibilityViewIsModal = YES; + UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, _popupContentView.popupCloseButton); } _popupControllerState = state; @@ -480,6 +486,26 @@ - (void)_reconfigure_progress }]; } +- (void)_reconfigure_accessibilityLavel +{ + _popupBar.accessibilityCenterLabel = _currentPopupItem.accessibilityLabel; +} + +- (void)_reconfigure_accessibilityHint +{ + _popupBar.accessibilityCenterHint = _currentPopupItem.accessibilityHint; +} + +- (void)_reconfigure_accessibilityProgressLabel +{ + _popupBar.accessibilityProgressLabel = _currentPopupItem.accessibilityProgressLabel; +} + +- (void)_reconfigure_accessibilityProgressValue +{ + _popupBar.accessibilityProgressValue = _currentPopupItem.accessibilityProgressValue; +} + - (void)_reconfigureBarItems { [_popupBar _delayBarButtonLayout]; @@ -534,9 +560,14 @@ - (void)_reconfigureContent [_currentContentController endAppearanceTransition]; _currentContentController = newContentController; + + if(_popupControllerState == LNPopupPresentationStateOpen) + { + UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil); + } } - NSArray* keys = @[@"title", @"subtitle", @"progress", @"leftBarButtonItems"]; + NSArray* keys = @[@"title", @"subtitle", @"progress", @"leftBarButtonItems", @"accessibilityLavel", @"accessibilityHint", @"accessibilityProgressLabel", @"accessibilityProgressValue"]; [keys enumerateObjectsUsingBlock:^(NSString * __nonnull key, NSUInteger idx, BOOL * __nonnull stop) { [self _popupItem:_currentPopupItem didChangeValueForKey:key]; }]; diff --git a/LNPopupController/LNPopupController/Private/LNPopupItem+Private.h b/LNPopupController/LNPopupController/Private/LNPopupItem+Private.h index 18c0e2d1..4909e7be 100644 --- a/LNPopupController/LNPopupController/Private/LNPopupItem+Private.h +++ b/LNPopupController/LNPopupController/Private/LNPopupItem+Private.h @@ -19,6 +19,16 @@ @interface LNPopupItem () +/** + * The accessibility label of the progress, in a localized string. + */ +@property (nonatomic, copy) NSString* accessibilityProgressLabel; + +/** + * The accessibility value of the progress, in a localized string. + */ +@property (nonatomic, copy) NSString* accessibilityProgressValue; + @property (nonatomic, weak, setter=_setItemDelegate:, getter=_itemDelegate) id<_LNPopupItemDelegate> itemDelegate; @property (nonatomic, weak, setter=_setContainerController:, getter=_containerController) __kindof UIViewController* containerController; diff --git a/LNPopupController/LNPopupController/Private/LNPopupItem.m b/LNPopupController/LNPopupController/Private/LNPopupItem.m index 706d06ca..875b8d25 100644 --- a/LNPopupController/LNPopupController/Private/LNPopupItem.m +++ b/LNPopupController/LNPopupController/Private/LNPopupItem.m @@ -13,6 +13,9 @@ @implementation LNPopupItem +@synthesize accessibilityProgressLabel = _accessibilityProgressLabel; +@synthesize accessibilityProgressValue = _accessibilityProgressValue; + - (instancetype)init { self = [super init]; @@ -24,6 +27,10 @@ - (instancetype)init [self addObserver:self forKeyPath:NSStringFromSelector(@selector(progress)) options:0 context:_LNPopupItemObservationContext]; [self addObserver:self forKeyPath:NSStringFromSelector(@selector(leftBarButtonItems)) options:0 context:_LNPopupItemObservationContext]; [self addObserver:self forKeyPath:NSStringFromSelector(@selector(rightBarButtonItems)) options:0 context:_LNPopupItemObservationContext]; + [self addObserver:self forKeyPath:NSStringFromSelector(@selector(accessibilityLabel)) options:0 context:_LNPopupItemObservationContext]; + [self addObserver:self forKeyPath:NSStringFromSelector(@selector(accessibilityHint)) options:0 context:_LNPopupItemObservationContext]; + [self addObserver:self forKeyPath:NSStringFromSelector(@selector(accessibilityProgressLabel)) options:0 context:_LNPopupItemObservationContext]; + [self addObserver:self forKeyPath:NSStringFromSelector(@selector(accessibilityProgressValue)) options:0 context:_LNPopupItemObservationContext]; } return self; @@ -36,6 +43,10 @@ - (void)dealloc [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(progress)) context:_LNPopupItemObservationContext]; [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(leftBarButtonItems)) context:_LNPopupItemObservationContext]; [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(rightBarButtonItems)) context:_LNPopupItemObservationContext]; + [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(accessibilityLabel)) context:_LNPopupItemObservationContext]; + [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(accessibilityHint)) context:_LNPopupItemObservationContext]; + [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(accessibilityProgressLabel)) context:_LNPopupItemObservationContext]; + [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(accessibilityProgressValue)) context:_LNPopupItemObservationContext]; } - (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary *)change context:(nullable void *)context diff --git a/LNPopupControllerExample/LNPopupControllerExample.xcodeproj/project.pbxproj b/LNPopupControllerExample/LNPopupControllerExample.xcodeproj/project.pbxproj index 261161c5..877aebaa 100644 --- a/LNPopupControllerExample/LNPopupControllerExample.xcodeproj/project.pbxproj +++ b/LNPopupControllerExample/LNPopupControllerExample.xcodeproj/project.pbxproj @@ -234,6 +234,7 @@ TargetAttributes = { 39277A031B58228000293F95 = { CreatedOnToolsVersion = 7.0; + DevelopmentTeam = 6Z9ASVU98Y; }; }; }; @@ -412,11 +413,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; INFOPLIST_FILE = LNPopupControllerExample/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.LeoNatan.LNPopupControllerExample; + PRODUCT_BUNDLE_IDENTIFIER = com.LeoNatan.LNPopupControllerExampleZZZZ; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; SWIFT_OBJC_BRIDGING_HEADER = "LNPopupControllerExample/LNPopupControllerExample-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; TARGETED_DEVICE_FAMILY = "1,2"; @@ -429,11 +433,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; INFOPLIST_FILE = LNPopupControllerExample/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.LeoNatan.LNPopupControllerExample; + PRODUCT_BUNDLE_IDENTIFIER = com.LeoNatan.LNPopupControllerExampleZZZZ; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; SWIFT_OBJC_BRIDGING_HEADER = "LNPopupControllerExample/LNPopupControllerExample-Bridging-Header.h"; TARGETED_DEVICE_FAMILY = "1,2"; }; diff --git a/LNPopupControllerExample/LNPopupControllerExample/DemoAlbumTableViewController.swift b/LNPopupControllerExample/LNPopupControllerExample/DemoAlbumTableViewController.swift index dc3b7af5..a29d3028 100644 --- a/LNPopupControllerExample/LNPopupControllerExample/DemoAlbumTableViewController.swift +++ b/LNPopupControllerExample/LNPopupControllerExample/DemoAlbumTableViewController.swift @@ -92,6 +92,9 @@ class DemoAlbumTableViewController: UITableViewController { popupContentController.songTitle = titles[indexPath.row] popupContentController.albumTitle = subtitles[indexPath.row] + popupContentController.popupItem.accessibilityHint = NSLocalizedString("Double Tap to Expand the Mini Player", comment: "") + tabBarController?.popupContentView.popupCloseButton?.accessibilityLabel = NSLocalizedString("Dismiss Now Playing Screen", comment: "") + tabBarController?.presentPopupBarWithContentViewController(popupContentController, animated: true, completion: nil) tableView.deselectRowAtIndexPath(indexPath, animated: true) diff --git a/LNPopupControllerExample/LNPopupControllerExample/DemoMusicPlayerController.swift b/LNPopupControllerExample/LNPopupControllerExample/DemoMusicPlayerController.swift index 40801539..22082e92 100644 --- a/LNPopupControllerExample/LNPopupControllerExample/DemoMusicPlayerController.swift +++ b/LNPopupControllerExample/LNPopupControllerExample/DemoMusicPlayerController.swift @@ -14,23 +14,36 @@ class DemoMusicPlayerController: UIViewController { @IBOutlet weak var albumNameLabel: UILabel! @IBOutlet weak var progressView: UIProgressView! + let accessibilityDateComponentsFormatter = NSDateComponentsFormatter() + var timer : NSTimer? required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) + + let pause = UIBarButtonItem(image: UIImage(named: "pause"), style: .Plain, target: nil, action: nil) + pause.accessibilityLabel = NSLocalizedString("Pause", comment: "") + let more = UIBarButtonItem(image: UIImage(named: "action"), style: .Plain, target: nil, action: nil) + more.accessibilityLabel = NSLocalizedString("More", comment: "") if UIScreen.mainScreen().traitCollection.userInterfaceIdiom == .Pad { - self.popupItem.leftBarButtonItems = [UIBarButtonItem(image: UIImage(named: "prev"), style: .Plain, target: nil, action: nil), - UIBarButtonItem(image: UIImage(named: "pause"), style: .Plain, target: nil, action: nil), - UIBarButtonItem(image: UIImage(named: "nextFwd"), style: .Plain, target: nil, action: nil)] - self.popupItem.rightBarButtonItems = [UIBarButtonItem(image: UIImage(named: "next"), style: .Plain, target: nil, action: nil), - UIBarButtonItem(image: UIImage(named: "action"), style: .Plain, target: nil, action: nil)] + let prev = UIBarButtonItem(image: UIImage(named: "prev"), style: .Plain, target: nil, action: nil) + prev.accessibilityLabel = NSLocalizedString("Previous Track", comment: "") + let next = UIBarButtonItem(image: UIImage(named: "nextFwd"), style: .Plain, target: nil, action: nil) + next.accessibilityLabel = NSLocalizedString("Next Track", comment: "") + let list = UIBarButtonItem(image: UIImage(named: "next"), style: .Plain, target: nil, action: nil) + list.accessibilityLabel = NSLocalizedString("Up Next", comment: "") + list.accessibilityHint = NSLocalizedString("Double Tap to Show Up Next List", comment: "") + + self.popupItem.leftBarButtonItems = [ prev, pause, next ] + self.popupItem.rightBarButtonItems = [ list, more ] } else { - self.popupItem.leftBarButtonItems = [UIBarButtonItem(image: UIImage(named: "pause"), style: .Plain, target: nil, action: nil)] - self.popupItem.rightBarButtonItems = [UIBarButtonItem(image: UIImage(named: "action"), style: .Plain, target: nil, action: nil)] + self.popupItem.leftBarButtonItems = [ pause ] + self.popupItem.rightBarButtonItems = [ more ] } + accessibilityDateComponentsFormatter.unitsStyle = .SpellOut timer = NSTimer.scheduledTimerWithTimeInterval(0.05, target: self, selector: #selector(DemoMusicPlayerController._timerTicked(_:)), userInfo: nil, repeats: true) } @@ -65,10 +78,15 @@ class DemoMusicPlayerController: UIViewController { } func _timerTicked(timer: NSTimer) { - popupItem.progress += 0.007; + popupItem.progress += 0.0002; + popupItem.accessibilityProgressLabel = NSLocalizedString("Playback Progress", comment: "") + + let totalTime = NSTimeInterval(250) + popupItem.accessibilityProgressValue = "\(accessibilityDateComponentsFormatter.stringFromTimeInterval(NSTimeInterval(popupItem.progress) * totalTime)!) \(NSLocalizedString("of", comment: "")) \(accessibilityDateComponentsFormatter.stringFromTimeInterval(totalTime)!)" + progressView.progress = popupItem.progress - if popupItem.progress == 1.0 { + if popupItem.progress >= 1.0 { timer.invalidate() popupPresentationContainerViewController?.dismissPopupBarAnimated(true, completion: nil) } diff --git a/LNPopupControllerExample/LNPopupControllerExample/FirstViewController.m b/LNPopupControllerExample/LNPopupControllerExample/FirstViewController.m index da8946ff..1e978b01 100644 --- a/LNPopupControllerExample/LNPopupControllerExample/FirstViewController.m +++ b/LNPopupControllerExample/LNPopupControllerExample/FirstViewController.m @@ -48,19 +48,30 @@ - (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection withT - (void)_setPopupItemButtonsWithTraitCollection:(UITraitCollection*)collection { + UIBarButtonItem* play = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"play"] style:UIBarButtonItemStylePlain target:nil action:NULL]; + play.accessibilityLabel = NSLocalizedString(@"Play", @""); + UIBarButtonItem* more = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"action"] style:UIBarButtonItemStylePlain target:nil action:NULL]; + more.accessibilityLabel = NSLocalizedString(@"More", @""); + if(collection.horizontalSizeClass == UIUserInterfaceSizeClassRegular) { - self.popupItem.leftBarButtonItems = @[ [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"prev"] style:UIBarButtonItemStylePlain target:nil action:NULL], - [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"play"] style:UIBarButtonItemStylePlain target:nil action:NULL], - [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"nextFwd"] style:UIBarButtonItemStylePlain target:nil action:NULL]]; + UIBarButtonItem* prev = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"prev"] style:UIBarButtonItemStylePlain target:nil action:NULL]; + prev.accessibilityLabel = NSLocalizedString(@"Previous Track", @""); + UIBarButtonItem* next = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"nextFwd"] style:UIBarButtonItemStylePlain target:nil action:NULL]; + next.accessibilityLabel = NSLocalizedString(@"Next Track", @""); + + self.popupItem.leftBarButtonItems = @[ prev, play, next ]; + + UIBarButtonItem* upnext = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"next"] style:UIBarButtonItemStylePlain target:nil action:NULL]; + upnext.accessibilityLabel = NSLocalizedString(@"Up Next", @""); + upnext.accessibilityHint = NSLocalizedString(@"Double Tap to Show Up Next List", @""); - self.popupItem.rightBarButtonItems = @[ [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"next"] style:UIBarButtonItemStylePlain target:nil action:NULL], - [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"action"] style:UIBarButtonItemStylePlain target:nil action:NULL]]; + self.popupItem.rightBarButtonItems = @[ upnext, more ]; } else { - self.popupItem.leftBarButtonItems = @[ [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"play"] style:UIBarButtonItemStylePlain target:nil action:NULL] ]; - self.popupItem.rightBarButtonItems = @[ [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"action"] style:UIBarButtonItemStylePlain target:nil action:NULL] ]; + self.popupItem.leftBarButtonItems = @[ play ]; + self.popupItem.rightBarButtonItems = @[ more ]; } } @@ -192,6 +203,12 @@ - (IBAction)_presentBar:(id)sender demoVC.popupItem.subtitle = [LoremIpsum sentence]; demoVC.popupItem.progress = (float) arc4random() / UINT32_MAX; + demoVC.popupItem.accessibilityLabel = NSLocalizedString(@"Custom popup bar accessibility label", @""); + demoVC.popupItem.accessibilityHint = NSLocalizedString(@"Custom popup bar accessibility hint", @""); + + targetVC.popupContentView.popupCloseButton.accessibilityLabel = NSLocalizedString(@"Custom popup button accessibility label", @""); + targetVC.popupContentView.popupCloseButton.accessibilityHint = NSLocalizedString(@"Custom popup button accessibility hint", @""); + [targetVC presentPopupBarWithContentViewController:demoVC animated:YES completion:nil]; } diff --git a/README.md b/README.md index f4530eae..3b5b0dbf 100644 --- a/README.md +++ b/README.md @@ -161,9 +161,44 @@ Customization can be achieved through the ```LNPopupBar``` and ```LNPopupContent **Note:** Be careful with modifying the popup interaction gesture recognizer. It is shared for interactively opening the popup by panning the popup bar (when it is closed), or interactively closing the popup interactively by panning the popup content view (when the popup is open). If you disable the gesture recognizer after opening the popup, you must monitor the state of the popup and reenable the gesture recognizer once closed by the user or through code. +###Accessibility + +The framework supports accessibility and will honor accessibility labels, hints and values. By default, the accessibility label of the popup bar is the title and subtitle provided by the popup item. + + + +To modify the accessibility label and hint of the popup bar, set the `accessibilityLabel` and `accessibilityHint` properties of the `LNPopupItem` object of the popup content view controller. + +```objc +demoVC.popupItem.accessibilityLabel = NSLocalizedString(@"Custom popup bar accessibility label", @""); +demoVC.popupItem.accessibilityHint = NSLocalizedString(@"Custom popup bar accessibility hint", @""); +``` + +To add accessibility labels and hints to buttons, set the `accessibilityLabel` and `accessibilityHint` properties of the `UIBarButtonItem` objects. + +```objc +UIBarButtonItem* upNext = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"next"] style:UIBarButtonItemStylePlain target:nil action:NULL]; +upNext.accessibilityLabel = NSLocalizedString(@"Up Next", @""); +upNext.accessibilityHint = NSLocalizedString(@"Double Tap to Show Up Next List", @""); +``` +To modify the accessibility label and hint of the popup close button, set the `accessibilityLabel` and `accessibilityHint` properties of the `LNPopupCloseButton` object of the popup container view controller. + +```objc +targetVC.popupContentView.popupCloseButton.accessibilityLabel = NSLocalizedString(@"Custom popup button accessibility label", @""); +targetVC.popupContentView.popupCloseButton.accessibilityHint = NSLocalizedString(@"Custom popup button accessibility hint", @""); +``` + +To modify the accessibility label and value of the popup bar progress view, set the `accessibilityProgressLabel` and `accessibilityProgressValue` properties of the `LNPopupItem` object of the popup content view controller. + +```swift +demoVC.popupItem.accessibilityProgressLabel = NSLocalizedString("Custom accessibility progress label", comment: "") +demoVC.popupItem.accessibilityProgressValue = "\(accessibilityDateComponentsFormatter.stringFromTimeInterval(NSTimeInterval(popupItem.progress) * totalTime)!) \(NSLocalizedString("of", comment: "")) \(accessibilityDateComponentsFormatter.stringFromTimeInterval(totalTime)!)" +``` + ##Known Limitations -* Navigation controller's `setToolbarHidden:` and `setToolbarHidden:animated:` are not supported +* Navigation controller's `setToolbarHidden:` and `setToolbarHidden:animated:` are not supported. +* Hidden tab bars are not supported by the framework, nor by Apple. **Do not hide the tab bar using `.hidden = YES`!** ##Acknowledgements diff --git a/Supplements/default_bar_accessibility_label.png b/Supplements/default_bar_accessibility_label.png new file mode 100644 index 00000000..5fc8e338 Binary files /dev/null and b/Supplements/default_bar_accessibility_label.png differ