Skip to content

Commit

Permalink
Merge pull request #75 from iZettle/fix-double-dismiss-item-setup
Browse files Browse the repository at this point in the history
Fix double dismiss item setup
  • Loading branch information
nataliq-pp authored Jan 18, 2021
2 parents 6f05074 + f29a1df commit 39d09ba
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 6 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# 1.13.4
- [Bug fix] Fix bug introduced in 1.13.3 where a view controller might be configured with dismiss twice when passed to `modalPresentationDismissalSetup`.

# 1.13.3
- [Bug fix] Fix bug related to presenting a `UINavigationController` modally without an explicit root `UIViewController`, resulting in unexpected behaviour of `UITextField` input cursors.

Expand Down
4 changes: 4 additions & 0 deletions Presentation.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
5B5111792357143500128609 /* FlowIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5111782357143500128609 /* FlowIntegrationTests.swift */; };
722FE3B622EA357A00EB04A7 /* CustomAdaptivePresentationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 722FE3B522EA357A00EB04A7 /* CustomAdaptivePresentationDelegate.swift */; };
728711A2229818B700A086DF /* PresentationEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 728711A1229818B700A086DF /* PresentationEvent.swift */; };
8737457225B58D3700F1AA0A /* PresentationStyleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8737457125B58D3700F1AA0A /* PresentationStyleTests.swift */; };
F617E3991C197D7600B567FB /* UIViewController+Presentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = F617E3981C197D7600B567FB /* UIViewController+Presentation.swift */; };
F646BEDB1C85CF5400AA7526 /* Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = F646BEDA1C85CF5400AA7526 /* Alert.swift */; };
F65D5DC11C58C421002B5D95 /* DualNavigationControllersSplitDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F65D5DC01C58C421002B5D95 /* DualNavigationControllersSplitDelegate.swift */; };
Expand Down Expand Up @@ -50,6 +51,7 @@
5B5111782357143500128609 /* FlowIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowIntegrationTests.swift; sourceTree = "<group>"; };
722FE3B522EA357A00EB04A7 /* CustomAdaptivePresentationDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomAdaptivePresentationDelegate.swift; sourceTree = "<group>"; };
728711A1229818B700A086DF /* PresentationEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationEvent.swift; sourceTree = "<group>"; };
8737457125B58D3700F1AA0A /* PresentationStyleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresentationStyleTests.swift; sourceTree = "<group>"; };
B38092B720A9B718009D8302 /* Flow.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flow.framework; path = Carthage/Build/iOS/Flow.framework; sourceTree = "<group>"; };
F617E3751C197D5E00B567FB /* Presentation.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Presentation.framework; sourceTree = BUILT_PRODUCTS_DIR; };
F617E37A1C197D5E00B567FB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -157,6 +159,7 @@
F6CB32A01F2F399600CA56C2 /* Info.plist */,
1C0656EC1F8393C100E60465 /* MemoryUtilsTests.swift */,
5B5111782357143500128609 /* FlowIntegrationTests.swift */,
8737457125B58D3700F1AA0A /* PresentationStyleTests.swift */,
);
path = PresentationTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -339,6 +342,7 @@
files = (
5B5111792357143500128609 /* FlowIntegrationTests.swift in Sources */,
F6B3B74F1F39977000188409 /* KeepSelectionTests.swift in Sources */,
8737457225B58D3700F1AA0A /* PresentationStyleTests.swift in Sources */,
1C0656ED1F8393C100E60465 /* MemoryUtilsTests.swift in Sources */,
F6B3B7501F39977000188409 /* MasterDetailSelectionTests.swift in Sources */,
);
Expand Down
2 changes: 1 addition & 1 deletion Presentation/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.13.3</string>
<string>1.13.4</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
16 changes: 13 additions & 3 deletions Presentation/PresentationStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,18 @@ public extension PresentationStyle {
}
}

/// Creates a future that will setup all dismiss functionality needed for modal presentations.
/// Creates a future that completes when `viewController` is dismissed.
/// Handles dismiss button configurations as well as swipe dismissal depending on the provided `options` and popover dismissal.
///
/// - Parameters:
/// - viewController: The presented view controller.
/// - customPresentationController: Optional custom presentation controller that will be used for the presentation. Defaults to `nil`.
/// - options: Presentation options.
///
/// - Note: Special case when `viewController` is a `UINavigationController`: If it doesn't have its own `dismissBarItem` configured
/// but its presented view controller does, the presented view controller dismissal will be configured too. If both `viewController` and its presented one
/// have dismiss items configured, only the one for `viewController` will be used.
///
static func modalPresentationDismissalSetup(for viewController: UIViewController, customPresentationController: UIPresentationController? = nil, options: PresentationOptions) -> Future<Void> {
return Future { completion in
let bag = DisposeBag()
Expand All @@ -124,8 +131,11 @@ public extension PresentationStyle {
bag += viewController.installDismissButton().onValue {
completion(.failure(PresentError.dismissed))
}
bag += presented.installDismissButton().onValue {
completion(.failure(PresentError.dismissed))

if viewController.dismissBarItem == nil && presented.dismissBarItem != nil {
bag += presented.installDismissButton().onValue {
completion(.failure(PresentError.dismissed))
}
}

if viewController.modalPresentationStyle == .popover, let popover = viewController.popoverPresentationController {
Expand Down
2 changes: 1 addition & 1 deletion PresentationFramework.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "PresentationFramework"
s.version = "1.13.3"
s.version = "1.13.4"
s.module_name = "Presentation"
s.summary = "Driving presentations from model to result"
s.description = <<-DESC
Expand Down
2 changes: 1 addition & 1 deletion PresentationTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.13.3</string>
<string>1.13.4</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
Expand Down
77 changes: 77 additions & 0 deletions PresentationTests/PresentationStyleTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//
// Copyright © 2021 PayPal Inc. All rights reserved.
//

import XCTest
import Flow
@testable import Presentation

class PresentationStyleTests: XCTestCase {

// MARK: - Dismissal Setup

func testModalPresentationDismissalSetup_forNavigationController_rootWithDismiss() {
let viewController = UIViewController()
viewController.dismissBarItem = .dummy
let navigationController = UINavigationController(rootViewController: viewController)

_ = PresentationStyle.modalPresentationDismissalSetup(for: navigationController, options: .defaults)

waitForNextrunLoop()

XCTAssertNil(navigationController.navigationItem.leftBarButtonItems)
XCTAssertEqual(viewController.navigationItem.leftBarButtonItems?.count, 1)
}

func testModalPresentationDismissalSetup_forNavigationController_withDismiss() {
let viewController = UIViewController()
let navigationController = UINavigationController(rootViewController: viewController)
navigationController.dismissBarItem = .dummy

_ = PresentationStyle.modalPresentationDismissalSetup(for: navigationController, options: .defaults)

waitForNextrunLoop()

XCTAssertNil(navigationController.navigationItem.leftBarButtonItems)
XCTAssertEqual(viewController.navigationItem.leftBarButtonItems?.count, 1)
}

func testModalPresentationDismissalSetup_forVCInNavController_withDismiss() {
let viewController = UIViewController()
viewController.dismissBarItem = .dummy
let navigationController = UINavigationController(rootViewController: viewController)

_ = PresentationStyle.modalPresentationDismissalSetup(for: viewController, options: .defaults)

waitForNextrunLoop()

XCTAssertNil(navigationController.navigationItem.leftBarButtonItems)
XCTAssertEqual(viewController.navigationItem.leftBarButtonItems?.count, 1)
}

func testModalPresentationDismissalSetup_forVCInNavController_withoutDismiss() {
let viewController = UIViewController()
let navigationController = UINavigationController(rootViewController: viewController)

_ = PresentationStyle.modalPresentationDismissalSetup(for: viewController, options: .defaults)

waitForNextrunLoop()

XCTAssertNil(navigationController.navigationItem.leftBarButtonItems)
XCTAssertNil(viewController.navigationItem.leftBarButtonItems)
}

private func waitForNextrunLoop() {
let nextRunLoop = expectation(description: "nextRunLoop")
Future().delay(by: 0).onValue {
nextRunLoop.fulfill()
}
wait(for: [nextRunLoop], timeout: 0.1)
}
}

extension UIBarButtonItem {
fileprivate static var dummy: UIBarButtonItem {
UIBarButtonItem(title: "Close", style: .plain, target: nil, action: nil)
}
}

0 comments on commit 39d09ba

Please sign in to comment.