Skip to content

Commit

Permalink
Merge pull request #19 from Orderella/development
Browse files Browse the repository at this point in the history
Automatic dialog repositioning
  • Loading branch information
mwfire authored Aug 7, 2016
2 parents d5961d7 + 511275c commit 07fda64
Show file tree
Hide file tree
Showing 18 changed files with 409 additions and 123 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Changelog

* **0.3.2** Dialog repositioning when interacting with keyboard<br>Non dismissable buttons option<br>Additional completion handler when dialog is dismissed
* **0.3.1** Fixed Carthage issues
* **0.3.0** Objective-C compatibility
* **0.2.2** Turned off liveBlur by default to increase performance
Expand Down
4 changes: 2 additions & 2 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PODS:
- PopupDialog (0.3.0)
- PopupDialog (0.3.2)

DEPENDENCIES:
- PopupDialog (from `../`)
Expand All @@ -9,7 +9,7 @@ EXTERNAL SOURCES:
:path: "../"

SPEC CHECKSUMS:
PopupDialog: b2d1dc31f81c0705189110a66a8f6e9cfc64f87d
PopupDialog: 8575b6974bfe39be1735011ea3e8c72efc28e9e1

PODFILE CHECKSUM: d8495001123cc68c0f614ef520d9741b67defd8d

Expand Down
4 changes: 2 additions & 2 deletions Example/Pods/Local Podspecs/PopupDialog.podspec.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Example/Pods/Manifest.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

176 changes: 91 additions & 85 deletions Example/Pods/Pods.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Example/Pods/Target Support Files/PopupDialog/Info.plist

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 18 additions & 1 deletion Example/PopupDialog/RatingViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,30 @@ import UIKit
class RatingViewController: UIViewController {

@IBOutlet weak var cosmosStarRating: CosmosView!

@IBOutlet weak var commentTextField: UITextField!

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.

commentTextField.delegate = self
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(endEditing)))
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

func endEditing() {
view.endEditing(true)
}
}

extension RatingViewController: UITextFieldDelegate {

func textFieldShouldReturn(textField: UITextField) -> Bool {
endEditing()
return true
}
}
35 changes: 25 additions & 10 deletions Example/PopupDialog/RatingViewController.xib
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10116" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10116" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="RatingViewController" customModule="PopupDialog_Example" customModuleProvider="target">
<connections>
<outlet property="commentTextField" destination="5b1-lD-vmU" id="Fup-iS-pXW"/>
<outlet property="cosmosStarRating" destination="TCC-HX-zVh" id="bov-99-E1X"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="290" height="168"/>
<rect key="frame" x="0.0" y="0.0" width="290" height="182"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IS1-mO-qkH">
<rect key="frame" x="0.0" y="0.0" width="300" height="168"/>
<rect key="frame" x="0.0" y="0.0" width="300" height="182"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="TCC-HX-zVh" customClass="CosmosView" customModule="PopupDialog_Example" customModuleProvider="target">
<rect key="frame" x="54" y="102" width="192" height="38"/>
<rect key="frame" x="54" y="129" width="192" height="38"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="38" id="eTp-yD-1Xd"/>
Expand All @@ -41,7 +43,7 @@
</userDefinedRuntimeAttributes>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="RATE THIS APP" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XLW-Lu-VBj">
<rect key="frame" x="75" y="25" width="138" height="21"/>
<rect key="frame" x="75" y="25" width="138" height="19.5"/>
<constraints>
<constraint firstAttribute="width" constant="138" id="AeL-Uh-bdN"/>
</constraints>
Expand All @@ -50,26 +52,39 @@
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="This is a custom view controller" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QQn-L7-aw4">
<rect key="frame" x="33" y="54" width="223" height="21"/>
<rect key="frame" x="33" y="52" width="223" height="21"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="1Da-sS-Bkc"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" verticalCompressionResistancePriority="749" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Comment" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="5b1-lD-vmU">
<rect key="frame" x="51" y="82" width="198" height="36"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
</textField>
</subviews>
<constraints>
<constraint firstItem="QQn-L7-aw4" firstAttribute="leading" secondItem="IS1-mO-qkH" secondAttribute="leading" constant="33" id="1Ax-Mn-I1S"/>
<constraint firstItem="TCC-HX-zVh" firstAttribute="top" secondItem="QQn-L7-aw4" secondAttribute="bottom" constant="27" id="3H8-jg-t34"/>
<constraint firstItem="5b1-lD-vmU" firstAttribute="width" secondItem="IS1-mO-qkH" secondAttribute="width" multiplier="0.66" id="CtN-60-UKG"/>
<constraint firstItem="5b1-lD-vmU" firstAttribute="top" secondItem="TCC-HX-zVh" secondAttribute="bottom" id="Ki7-N1-dj7"/>
<constraint firstItem="TCC-HX-zVh" firstAttribute="centerX" secondItem="IS1-mO-qkH" secondAttribute="centerX" id="TIm-QW-CTz"/>
<constraint firstAttribute="trailing" secondItem="QQn-L7-aw4" secondAttribute="trailing" constant="44" id="Z2x-jm-vQB"/>
<constraint firstItem="TCC-HX-zVh" firstAttribute="top" secondItem="QQn-L7-aw4" secondAttribute="bottom" constant="27" id="f59-NF-XlK"/>
<constraint firstItem="TCC-HX-zVh" firstAttribute="top" secondItem="5b1-lD-vmU" secondAttribute="bottom" constant="11" id="cCH-3e-jLc"/>
<constraint firstItem="QQn-L7-aw4" firstAttribute="top" secondItem="XLW-Lu-VBj" secondAttribute="bottom" constant="8" id="j2I-LU-dmi"/>
<constraint firstItem="XLW-Lu-VBj" firstAttribute="top" secondItem="IS1-mO-qkH" secondAttribute="top" constant="25" id="mf9-b7-p4a"/>
<constraint firstItem="XLW-Lu-VBj" firstAttribute="centerX" secondItem="IS1-mO-qkH" secondAttribute="centerX" constant="-6" id="pR8-bb-Q05"/>
<constraint firstAttribute="bottom" secondItem="TCC-HX-zVh" secondAttribute="bottom" constant="28" id="y97-Nt-sO7"/>
<constraint firstItem="5b1-lD-vmU" firstAttribute="top" secondItem="QQn-L7-aw4" secondAttribute="bottom" constant="9" id="rhS-hN-ufO"/>
<constraint firstItem="5b1-lD-vmU" firstAttribute="centerX" secondItem="IS1-mO-qkH" secondAttribute="centerX" id="tD7-9G-0Fc"/>
<constraint firstAttribute="bottom" secondItem="TCC-HX-zVh" secondAttribute="bottom" constant="15" id="y97-Nt-sO7"/>
</constraints>
<variation key="default">
<mask key="constraints">
<exclude reference="Ki7-N1-dj7"/>
</mask>
</variation>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
Expand All @@ -80,7 +95,7 @@
<constraint firstAttribute="trailing" secondItem="IS1-mO-qkH" secondAttribute="trailing" constant="-10" id="rlD-9w-zuN"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="263" y="273"/>
<point key="canvasLocation" x="263" y="268"/>
</view>
</objects>
</document>
6 changes: 4 additions & 2 deletions Example/PopupDialog/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ class ViewController: UIViewController {
let message = "If you don't pass an image to the default dialog, it will display just as a regular dialog. Moreover, this features the zoom transition"

// Create the dialog
let popup = PopupDialog(title: title, message: message, transitionStyle: .ZoomIn, buttonAlignment: .Horizontal)
let popup = PopupDialog(title: title, message: message, transitionStyle: .ZoomIn, buttonAlignment: .Horizontal) {
print("Completed")
}

// Create first button
let buttonOne = CancelButton(title: "CANCEL") {
Expand Down Expand Up @@ -122,7 +124,7 @@ class ViewController: UIViewController {
let ratingVC = RatingViewController(nibName: "RatingViewController", bundle: nil)

// Create the dialog
let popup = PopupDialog(viewController: ratingVC, transitionStyle: .BounceDown, buttonAlignment: .Horizontal, gestureDismissal: false)
let popup = PopupDialog(viewController: ratingVC, transitionStyle: .BounceDown, buttonAlignment: .Horizontal, gestureDismissal: true)

// Create first button
let buttonOne = CancelButton(title: "CANCEL") {
Expand Down
2 changes: 1 addition & 1 deletion PopupDialog.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'PopupDialog'
s.version = '0.3.1'
s.version = '0.3.2'
s.summary = 'A simple custom popup dialog view controller'
s.homepage = 'https://github.com/orderella/PopupDialog'
s.license = { :type => 'MIT', :file => 'LICENSE' }
Expand Down
133 changes: 133 additions & 0 deletions PopupDialog/Classes/PopupDialog+Keyboard.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
//
// PopupDialog+Keyboard.swift
//
// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
// Author - Martin Wildfeuer (http://www.mwfire.de)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

import Foundation
import UIKit

/// This extension is designed to handle dialog positioning
/// if a keyboard is displayed while the popup is on top
internal extension PopupDialog {

// MARK: - Keyboard & orientation observers

/*! Add obserservers for UIKeyboard notifications */
internal func addObservers() {
NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(orientationChanged),
name: UIDeviceOrientationDidChangeNotification,
object: nil)

NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(keyboardWillShow),
name: UIKeyboardWillShowNotification,
object: nil)

NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(keyboardWillHide),
name: UIKeyboardWillHideNotification,
object: nil)

NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(keyboardWillChangeFrame),
name: UIKeyboardWillChangeFrameNotification,
object: nil)
}

/*! Remove observers */
internal func removeObservers() {
NSNotificationCenter.defaultCenter().removeObserver(self,
name: UIDeviceOrientationDidChangeNotification,
object: nil)

NSNotificationCenter.defaultCenter().removeObserver(self,
name: UIKeyboardWillShowNotification,
object: nil)

NSNotificationCenter.defaultCenter().removeObserver(self,
name: UIKeyboardWillHideNotification,
object: nil)

NSNotificationCenter.defaultCenter().removeObserver(self,
name: UIKeyboardWillChangeFrameNotification,
object: nil)
}

// MARK: - Actions

/*!
Keyboard will show notification listener
- parameter notification: NSNotification
*/
@objc private func keyboardWillShow(notification: NSNotification) {
guard isTopAndVisible else { return }
keyboardShown = true
centerPopup()
}

/*!
Keyboard will hide notification listener
- parameter notification: NSNotification
*/
@objc private func keyboardWillHide(notification: NSNotification) {
guard isTopAndVisible else { return }
keyboardShown = false
centerPopup()
}

/*!
Keyboard will change frame notification listener
- parameter notification: NSNotification
*/
@objc private func keyboardWillChangeFrame(notification: NSNotification) {
guard let keyboardRect = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else {
return
}
keyboardHeight = keyboardRect.CGRectValue().height
}

/*!
Listen to orientation changes
- parameter notification: NSNotification
*/
@objc private func orientationChanged(notification: NSNotification) {
if keyboardShown { centerPopup() }
}

private func centerPopup() {

// Make sure keyboard should reposition on keayboard notifications
guard keyboardShiftsView else { return }

// Make sure a valid keyboard height is available
guard let keyboardHeight = keyboardHeight else { return }

// Calculate new center of shadow background
let popupCenter = keyboardShown ? keyboardHeight / -2 : 0

// Reposition and animate
popupContainerView.centerYConstraint?.constant = popupCenter
popupContainerView.pv_layoutIfNeededAnimated()
}
}
Loading

0 comments on commit 07fda64

Please sign in to comment.