diff --git a/DatePickerDialog.podspec b/DatePickerDialog.podspec index fbe14d7..82f3f89 100644 --- a/DatePickerDialog.podspec +++ b/DatePickerDialog.podspec @@ -11,5 +11,6 @@ Pod::Spec.new do |s| s.source = { :git => "https://github.com/squimer/DatePickerDialog-iOS-Swift.git", :tag => s.version } s.source_files = "Sources/*.swift" s.requires_arc = true + s.swift_version = '4.2' end diff --git a/DatePickerDialog.xcodeproj/project.pbxproj b/DatePickerDialog.xcodeproj/project.pbxproj index b9e981f..7249680 100644 --- a/DatePickerDialog.xcodeproj/project.pbxproj +++ b/DatePickerDialog.xcodeproj/project.pbxproj @@ -205,7 +205,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0800; - LastUpgradeCheck = 0900; + LastUpgradeCheck = 1010; ORGANIZATIONNAME = squimer; TargetAttributes = { 4B1E9F361D8F3C9A00C1EF25 = { @@ -321,7 +321,7 @@ PRODUCT_BUNDLE_IDENTIFIER = squimer.DatePickerDialogExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.2; }; name = Debug; }; @@ -336,7 +336,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = squimer.DatePickerDialogExample; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.2; }; name = Release; }; @@ -353,6 +353,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -360,6 +361,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -394,6 +396,7 @@ SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -413,6 +416,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -420,6 +424,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -446,6 +451,7 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -471,7 +477,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = Debug; }; @@ -492,7 +498,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = Release; }; @@ -505,7 +511,7 @@ PRODUCT_BUNDLE_IDENTIFIER = squimer.DatePickerDialogTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = Debug; }; @@ -518,7 +524,7 @@ PRODUCT_BUNDLE_IDENTIFIER = squimer.DatePickerDialogTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = Release; }; diff --git a/DatePickerDialog.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/DatePickerDialog.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/DatePickerDialog.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/DatePickerDialog.xcodeproj/xcshareddata/xcschemes/DatePickerDialog.xcscheme b/DatePickerDialog.xcodeproj/xcshareddata/xcschemes/DatePickerDialog.xcscheme index 1c82d44..7ce9016 100644 --- a/DatePickerDialog.xcodeproj/xcshareddata/xcschemes/DatePickerDialog.xcscheme +++ b/DatePickerDialog.xcodeproj/xcshareddata/xcschemes/DatePickerDialog.xcscheme @@ -1,6 +1,6 @@ @@ -46,7 +45,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/Sources/DatePickerDialog.swift b/Sources/DatePickerDialog.swift index 880479d..493349f 100644 --- a/Sources/DatePickerDialog.swift +++ b/Sources/DatePickerDialog.swift @@ -24,14 +24,16 @@ open class DatePickerDialog: UIView { // MARK: - Variables private var defaultDate: Date? - private var datePickerMode: UIDatePickerMode? + private var datePickerMode: UIDatePicker.Mode? private var callback: DatePickerCallback? var showCancelButton: Bool = false + open var allowBackgroundTapDismiss: Bool = false var locale: Locale? private var textColor: UIColor! private var buttonColor: UIColor! private var font: UIFont! + private var tapRecognizer:UITapGestureRecognizer? // MARK: - Dialog initialization public init(textColor: UIColor = UIColor.black, @@ -86,7 +88,7 @@ open class DatePickerDialog: UIView { cancelButtonTitle: String = "Cancel", defaultDate: Date = Date(), minimumDate: Date? = nil, maximumDate: Date? = nil, - datePickerMode: UIDatePickerMode = .dateAndTime, + datePickerMode: UIDatePicker.Mode = .dateAndTime, callback: @escaping DatePickerCallback) { self.titleLabel.text = title self.doneButton.setTitle(doneButtonTitle, for: .normal) @@ -96,23 +98,32 @@ open class DatePickerDialog: UIView { self.datePickerMode = datePickerMode self.callback = callback self.defaultDate = defaultDate - self.datePicker.datePickerMode = self.datePickerMode ?? UIDatePickerMode.date - self.datePicker.date = self.defaultDate ?? Date() + self.datePicker.datePickerMode = self.datePickerMode ?? UIDatePicker.Mode.date self.datePicker.maximumDate = maximumDate self.datePicker.minimumDate = minimumDate + + // This needs to be set after the `minimumDate` or you end up with the minimumDate displayed. You *could* do this in the calling/client code (i.e., self.datePicker is public), but you may get scrolling while the picker is displayed. Which is less than good UX. + self.datePicker.date = self.defaultDate ?? Date() + if let locale = self.locale { self.datePicker.locale = locale } /* Add dialog to main window */ guard let appDelegate = UIApplication.shared.delegate else { fatalError() } guard let window = appDelegate.window else { fatalError() } + + if allowBackgroundTapDismiss { + tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapAction)) + window?.addGestureRecognizer(tapRecognizer!) + } + window?.addSubview(self) - window?.bringSubview(toFront: self) + window?.bringSubviewToFront(self) window?.endEditing(true) NotificationCenter.default.addObserver(self, selector: .deviceOrientationDidChange, - name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) + name: UIDevice.orientationDidChangeNotification, object: nil) /* Anim */ UIView.animate( @@ -126,9 +137,25 @@ open class DatePickerDialog: UIView { } ) } + + @objc private func tapAction(tapGesture: UITapGestureRecognizer) { + guard let appDelegate = UIApplication.shared.delegate else { fatalError() } + guard let window = appDelegate.window else { fatalError() } + + let location = tapGesture.location(in: nil) + if let convertedLocation = window?.convert(location, to: dialogView!) { + if !dialogView!.bounds.contains(convertedLocation) { + close() + } + } + } /// Dialog close animation then cleaning and removing the view from the parent private func close() { + if let tapRecognizer = tapRecognizer { + tapRecognizer.view!.removeGestureRecognizer(tapRecognizer) + } + let currentTransform = self.dialogView.layer.transform let startRotation = (self.value(forKeyPath: "layer.transform.rotation.z") as? NSNumber) as? Double ?? 0.0