Skip to content

Commit

Permalink
Make dimmer a close button in VO mode (#8)
Browse files Browse the repository at this point in the history
* Make dimmer a close button in VO mode

* Apply Mark suggestion

* Fix unit test

* Tweak VO implementation

---------

Co-authored-by: Mark Pospesel <[email protected]>
  • Loading branch information
CaioCoanYML and Mark Pospesel authored May 5, 2023
1 parent ae8495d commit d3e6d7f
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 6 deletions.
1 change: 1 addition & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import PackageDescription

let package = Package(
name: "YSideMenu",
defaultLocalization: "en",
platforms: [
.iOS(.v14)
],
Expand Down
7 changes: 5 additions & 2 deletions Sources/YSideMenu/Animation/SideMenuDismissAnimator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,16 @@ class SideMenuDismissAnimator: SideMenuAnimator {
menu.dimmerView.alpha = 0
}

UIView.animate(with: menu.appearance.dismissAnimation) {
UIView.animate(
with: menu.appearance.dismissAnimation
) {
if self.isReduceMotionEnabled {
menu.contentView.alpha = 0
} else {
menu.contentView.frame = menuFrame
}
} completion: { _ in
}
completion: { _ in
if !transitionContext.transitionWasCancelled {
fromViewController.view.removeFromSuperview()
}
Expand Down
7 changes: 5 additions & 2 deletions Sources/YSideMenu/Animation/SideMenuPresentAnimator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,16 @@ class SideMenuPresentAnimator: SideMenuAnimator {
menu.dimmerView.alpha = 1
}

UIView.animate(with: menu.appearance.presentAnimation) {
UIView.animate(
with: menu.appearance.presentAnimation
) {
if self.isReduceMotionEnabled {
menu.view.alpha = 1
} else {
menu.view.layoutIfNeeded()
}
} completion: { _ in
}
completion: { _ in
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
}
Expand Down
9 changes: 9 additions & 0 deletions Sources/YSideMenu/Assets/Strings/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
Localizable.strings
YSideMenu

Created by Caio Coan on 05/03/23.
Copyright © 2023 Y Media Labs. All rights reserved.
*/

"Menu_Dimmer_Close" = "Dismiss";
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// SideMenuController+AccessibilityIdentifiers.swift
// YSideMenu
//
// Created by Caio Coan on 05/03/23.
// Copyright © 2023 Y Media Labs. All rights reserved.
//

extension SideMenuController {
enum AccessibilityIdentifiers {
static let dimmerId = "Menu_Dimmer_Close"
}
}
18 changes: 18 additions & 0 deletions Sources/YSideMenu/Enums/SideMenuController+Strings.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// YSideMenuController+Strings.swift
// YSideMenu
//
// Created by Caio Coan on 05/03/23.
// Copyright © 2023 Y Media Labs. All rights reserved.
//

import Foundation
import YCoreUI

extension SideMenuController {
enum Strings: String, Localizable, CaseIterable {
case dimmerAccessibilityLabel = "Menu_Dimmer_Close"

static var bundle: Bundle { .module }
}
}
15 changes: 14 additions & 1 deletion Sources/YSideMenu/SideMenuController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ public class SideMenuController: UIViewController {
}
private var idealWidthAnchor: NSLayoutConstraint?
private var maximumWidthAnchor: NSLayoutConstraint?
/// Dimmer tap view
internal let dimmerTapView: UIView = {
let view = UIView()
view.accessibilityTraits = .button
view.accessibilityLabel = Strings.dimmerAccessibilityLabel.localized
view.accessibilityIdentifier = AccessibilityIdentifiers.dimmerId
return view
}()

/// :nodoc:
@available(*, unavailable)
Expand Down Expand Up @@ -62,6 +70,7 @@ public class SideMenuController: UIViewController {

internal func didDismiss() {
guard appearance.isDismissAllowed else { return }
dimmerTapView.isAccessibilityElement = false
dismiss(animated: true)
}
}
Expand All @@ -79,6 +88,7 @@ private extension SideMenuController {
}

func updateAppearance() {
dimmerTapView.isAccessibilityElement = appearance.isDismissAllowed
dimmerView.backgroundColor = appearance.dimmerColor
idealWidthAnchor?.isActive = false
idealWidthAnchor = contentView.constrain(
Expand All @@ -97,6 +107,7 @@ private extension SideMenuController {

func buildViews() {
view.addSubview(dimmerView)
view.addSubview(dimmerTapView)
view.addSubview(contentView)

addChild(rootViewController)
Expand All @@ -106,12 +117,14 @@ private extension SideMenuController {

func buildConstraints() {
dimmerView.constrainEdges()
dimmerTapView.constrainEdges(.notLeading)
dimmerTapView.constrain(.leadingAnchor, to: contentView.trailingAnchor)
rootViewController.view.constrainEdges()
contentView.constrainEdges(.notTrailing)
}

func configureViews() {
dimmerView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTapDimmerView)))
dimmerTapView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTapDimmerView)))
updateAppearance()

contentView.backgroundColor = .systemBackground
Expand Down
24 changes: 24 additions & 0 deletions Tests/YSideMenuTests/Enums/SideMenuController+StringsTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// SideMenuController+StringsTests.swift
// YSideMenu
//
// Created by Caio Coan on 03/05/23.
// Copyright © 2023 Y Media Labs. All rights reserved.
//

import XCTest
import YCoreUI
@testable import YSideMenu

final class SideMenuControllerStringsTests: XCTestCase {
func testLoad() {
SideMenuController.Strings.allCases.forEach {
// Given a localized string constant
let string = $0.localized
// it should not be empty
XCTAssertFalse(string.isEmpty)
// and it should not equal its key
XCTAssertNotEqual($0.rawValue, string)
}
}
}
15 changes: 14 additions & 1 deletion Tests/YSideMenuTests/SideMenuControllerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,17 @@ final class SideMenuControllerTests: XCTestCase {

func test_onDimmer() {
let sut = makeSpy(rootViewController: UIViewController())

sut.loadViewIfNeeded()

XCTAssertFalse(sut.onDimmerTapped)
XCTAssertFalse(sut.isDismissed)
XCTAssertTrue(sut.dimmerTapView.isAccessibilityElement)

sut.simulateOnDimmerTap()

XCTAssertTrue(sut.onDimmerTapped)
XCTAssertTrue(sut.isDismissed)
XCTAssertFalse(sut.dimmerTapView.isAccessibilityElement)
}

func test_onSwipeLeft() {
Expand All @@ -120,6 +123,7 @@ final class SideMenuControllerTests: XCTestCase {
sut.appearance.isDismissAllowed = false
sut.loadViewIfNeeded()

XCTAssertFalse(sut.dimmerTapView.isAccessibilityElement)
XCTAssertFalse(sut.onMenuSwiped)
XCTAssertFalse(sut.onDimmerTapped)
XCTAssertFalse(sut.isDismissed)
Expand All @@ -131,6 +135,15 @@ final class SideMenuControllerTests: XCTestCase {
XCTAssertFalse(sut.onMenuSwiped)
XCTAssertFalse(sut.onDimmerTapped)
}

func test_accessibility() {
let sut = makeSUT(rootViewController: UIViewController())
sut.loadViewIfNeeded()

XCTAssertTrue(sut.dimmerTapView.isAccessibilityElement)
XCTAssertEqual(sut.dimmerTapView.accessibilityIdentifier, SideMenuController.AccessibilityIdentifiers.dimmerId)
XCTAssertEqual(sut.dimmerTapView.accessibilityTraits, .button)
}
}

private extension SideMenuControllerTests {
Expand Down

0 comments on commit d3e6d7f

Please sign in to comment.