Skip to content

Commit

Permalink
Update 1.2.0
Browse files Browse the repository at this point in the history
- updated rounding angle calculation for new devices
- added 2 closures: popupWillClose & popupDidClose
- superellipse rounding has been moved to the native method in iOS 13
  • Loading branch information
alxrguz committed Dec 5, 2023
1 parent aecd460 commit f9e88d0
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 59 deletions.
2 changes: 1 addition & 1 deletion ALPopup.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = 'ALPopup'
s.version = '1.1.0'
s.version = '1.2.0'
s.summary = 'Native card controller like AirPods or Wi-Fi password sharing'

s.homepage = 'https://github.com/alxrguz/ALPopup'
Expand Down
18 changes: 9 additions & 9 deletions ExampleApp/ALPopup Example.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
BB3C5BD626C9CBAF000C7B24 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3C5BD526C9CBAF000C7B24 /* SettingsViewController.swift */; };
BB3C5BDC26CA5BE0000C7B24 /* HorizontallScrollController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3C5BDB26CA5BE0000C7B24 /* HorizontallScrollController.swift */; };
BB3C5BDE26CA62E1000C7B24 /* MixedScrollViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3C5BDD26CA62E1000C7B24 /* MixedScrollViewController.swift */; };
BBA76B99276115EF004B75A1 /* ALPopup in Frameworks */ = {isa = PBXBuildFile; productRef = BBA76B98276115EF004B75A1 /* ALPopup */; };
BBC5A33B262824B60000ADDA /* ALDevKit in Frameworks */ = {isa = PBXBuildFile; productRef = BBC5A33A262824B60000ADDA /* ALDevKit */; };
BBDBFBF42705B44200EBD725 /* ALPopup in Frameworks */ = {isa = PBXBuildFile; productRef = BBDBFBF32705B44200EBD725 /* ALPopup */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -44,15 +44,15 @@
BB3C5BD526C9CBAF000C7B24 /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = "<group>"; };
BB3C5BDB26CA5BE0000C7B24 /* HorizontallScrollController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HorizontallScrollController.swift; sourceTree = "<group>"; };
BB3C5BDD26CA62E1000C7B24 /* MixedScrollViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MixedScrollViewController.swift; sourceTree = "<group>"; };
BB8E4EC1271814EF00D58888 /* ALPopup */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ALPopup; path = ..; sourceTree = "<group>"; };
BBA76B97276115E5004B75A1 /* ALPopup */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ALPopup; path = ..; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
BB3959F024EA71EE00B965F5 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
BBDBFBF42705B44200EBD725 /* ALPopup in Frameworks */,
BBA76B99276115EF004B75A1 /* ALPopup in Frameworks */,
BB3C5BC126C9B821000C7B24 /* ALRadioButtons in Frameworks */,
BBC5A33B262824B60000ADDA /* ALDevKit in Frameworks */,
BB3C5BCB26C9C4DC000C7B24 /* ALProgressView in Frameworks */,
Expand Down Expand Up @@ -201,7 +201,7 @@
BB8E4EC0271814EF00D58888 /* Packages */ = {
isa = PBXGroup;
children = (
BB8E4EC1271814EF00D58888 /* ALPopup */,
BBA76B97276115E5004B75A1 /* ALPopup */,
);
name = Packages;
sourceTree = "<group>";
Expand Down Expand Up @@ -233,7 +233,7 @@
BBC5A33A262824B60000ADDA /* ALDevKit */,
BB3C5BC026C9B821000C7B24 /* ALRadioButtons */,
BB3C5BCA26C9C4DC000C7B24 /* ALProgressView */,
BBDBFBF32705B44200EBD725 /* ALPopup */,
BBA76B98276115EF004B75A1 /* ALPopup */,
);
productName = "Panda School";
productReference = BB3959F324EA71EE00B965F5 /* ALPopup Example.app */;
Expand Down Expand Up @@ -538,15 +538,15 @@
package = BB3C5BC926C9C4DB000C7B24 /* XCRemoteSwiftPackageReference "ALProgressView" */;
productName = ALProgressView;
};
BBA76B98276115EF004B75A1 /* ALPopup */ = {
isa = XCSwiftPackageProductDependency;
productName = ALPopup;
};
BBC5A33A262824B60000ADDA /* ALDevKit */ = {
isa = XCSwiftPackageProductDependency;
package = BBC5A339262824B60000ADDA /* XCRemoteSwiftPackageReference "ALDevKit" */;
productName = ALDevKit;
};
BBDBFBF32705B44200EBD725 /* ALPopup */ = {
isa = XCSwiftPackageProductDependency;
productName = ALPopup;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = BB3959EB24EA71EE00B965F5 /* Project object */;
Expand Down
2 changes: 1 addition & 1 deletion Sources/ALPopup/ALPopup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public class ALPopup {

if controller is UINavigationController {
let offset: CGFloat = isPhone ? 12 : 8
controller.additionalSafeAreaInsets = .init(top: offset, left: 0, bottom: 0, right: 0)
controller.additionalSafeAreaInsets = .init(top: offset, left: 8, bottom: 0, right: 8)
}

return vc
Expand Down
44 changes: 32 additions & 12 deletions Sources/ALPopup/Controllers/ALBaseOverlayController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ open class ALBaseOverlayController: UIViewController {

// MARK: Open Proporties

/**
Dimmed card background color
*/
public var dimmedBackgroudColor: UIColor? {
didSet {
backgroundView.backgroundColor = dimmedBackgroudColor ?? .black.alpha(0.5)
}
}

/**
Is Close Button show on controller
*/
Expand All @@ -58,12 +67,16 @@ open class ALBaseOverlayController: UIViewController {
}
}

/// Rounding corners in superellipse for `contentView`. Gives nicer and more correct rounding, but does not work well with frame animations. Default is `true`
public var superellipticRounding = true {
didSet {
contentView.superellipticRounding = superellipticRounding
}
}
/**
Popup started to close
*/
public var popupWillClose: (() -> Void)?


/**
Popup closed
*/
public var popupDidClose: (() -> Void)?

// MARK: Private Proporties

Expand Down Expand Up @@ -91,6 +104,7 @@ open class ALBaseOverlayController: UIViewController {
open override func viewDidLoad() {
super.viewDidLoad()
setupActions()
setupView()
setupConstraints()
}

Expand Down Expand Up @@ -182,12 +196,9 @@ extension ALBaseOverlayController: UIGestureRecognizerDelegate {

let translate = panGesture.translation(in: contentView).y
guard translate > 0 else { return false }

if -scrollView.contentInset.top >= scrollView.contentOffset.y {
return true
} else {
return false
}
let scrollTopPosition = scrollView.contentOffset.y + scrollView.safeAreaInsets.top
let scrollTopOffset = -scrollView.contentInset.top
return scrollTopOffset >= scrollTopPosition
}
}

Expand Down Expand Up @@ -269,6 +280,15 @@ private extension ALBaseOverlayController {
// MARK: - Layout Setup

private extension ALBaseOverlayController {
func setupView() {
if #available(iOS 13.4, *) {
closeButton.pointerStyleProvider = { button, effect, shape in
let preview = UITargetedPreview(view: button)
return UIPointerStyle(effect: .lift(preview))
}
}
}

func setupConstraints() {
contentView.addSubview(closeButton)

Expand Down
28 changes: 22 additions & 6 deletions Sources/ALPopup/Controllers/Card/ALCardController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ open class ALCardController: ALBaseOverlayController {
private var bottomConstraint: NSLayoutConstraint?
private var centerConstraint: NSLayoutConstraint?
private var isPresented = false


// MARK: UIViewController

Expand Down Expand Up @@ -65,19 +66,22 @@ open class ALCardController: ALBaseOverlayController {

open override func dismissAnimation(competion: @escaping () -> Void) {
let height = contentView.frame.maxY

popupWillClose?()
ALAnimate.spring(time: 0.6) {
self.backgroundView.alpha = 0
self.contentView.transform = .init(translationX: 0, y: height)
} completion: {
} completion: { [weak self] in
competion()
self?.popupDidClose?()
}
}

open override func resetAnimation() {
ALAnimate.spring(time: 0.4, damping: 1) {
self.backgroundView.alpha = 1
}

ALAnimate.spring(time: 0.5, damping: 0.85, velocity: 0.8) {
self.contentView.transform = .identity
}
Expand All @@ -89,7 +93,7 @@ open class ALCardController: ALBaseOverlayController {
private extension ALCardController {
func setupView() {
backgroundView.alpha = 0
backgroundView.backgroundColor = UIColor.black.alpha(0.6)
backgroundView.backgroundColor = dimmedBackgroudColor ?? .black.alpha(0.4)

contentView.alpha = 0
}
Expand All @@ -98,7 +102,7 @@ private extension ALCardController {
view.addSubview(backgroundView)
view.addSubview(contentView)

let cardOffset: CGFloat = 5
let cardOffset: CGFloat = 4

backgroundView.translatesAutoresizingMaskIntoConstraints = false
backgroundView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
Expand All @@ -122,6 +126,8 @@ private extension ALCardController {
}

func updateContentCorners() {
let cornerRadius = UIScreen.main.displayCornerRadius

var isRoundDisplay: Bool {
view.safeAreaInsets.bottom > 0
}
Expand All @@ -131,9 +137,19 @@ private extension ALCardController {
}

var isIpad: Bool {
UIDevice.current.userInterfaceIdiom == .pad
let idiom = UIDevice.current.userInterfaceIdiom
if #available(iOS 14.0, *) {
return idiom == .pad || idiom == .mac
} else {
return idiom == .pad
}
}

contentView.cornerRadius = isIpad ? 12 : (isRoundDisplay ? 36 : 18)
let shiftCompensator: CGFloat = 3
let iphoneCornerRadius = cornerRadius > 0 ? cornerRadius - shiftCompensator : 18
let ipadCornerRadius = cornerRadius > 0 ? cornerRadius : 12

contentView.cornerRadius = isIpad ? ipadCornerRadius : iphoneCornerRadius
contentView.layer.masksToBounds = true
}
}
12 changes: 5 additions & 7 deletions Sources/ALPopup/Controllers/Popup/ALPopupController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,14 @@ open class ALPopupController: ALBaseOverlayController {
}
}()

popupWillClose?()
ALAnimate.spring(time: 0.4) {
self.backgroundView.alpha = 0
self.contentView.alpha = 0
self.contentView.transform = .init(translationX: 0, y: translationY)
} completion: {
} completion: { [weak self] in
competion()
self?.popupDidClose?()
}
}

Expand All @@ -98,8 +100,7 @@ open class ALPopupController: ALBaseOverlayController {
private extension ALPopupController {
func setupView() {
backgroundView.alpha = 0
backgroundView.backgroundColor = UIColor.black.alpha(0.6)

backgroundView.backgroundColor = dimmedBackgroudColor ?? .black.alpha(0.6)
contentView.alpha = 0
}

Expand Down Expand Up @@ -130,10 +131,7 @@ private extension ALPopupController {
}

func updateContentCorners() {
var isIpad: Bool {
UIDevice.current.userInterfaceIdiom == .pad
}

contentView.cornerRadius = 24
contentView.layer.masksToBounds = true
}
}
40 changes: 40 additions & 0 deletions Sources/ALPopup/Extensions/UIScreenExtension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// The MIT License (MIT)
//
// Copyright (c) 2021 Alexandr Guzenko ([email protected])
//
// 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 UIKit

extension UIScreen {
private static let cornerRadiusKey: String = {
let components = ["Radius", "Corner", "display", "_"]
return components.reversed().joined()
}()

/// The corner radius of the display. Uses a private property of `UIScreen`,
/// and may report 0 if the API changes.
public var displayCornerRadius: CGFloat {
guard let cornerRadius = self.value(forKey: Self.cornerRadiusKey) as? CGFloat else {
return 0
}

return cornerRadius
}
}
28 changes: 15 additions & 13 deletions Sources/ALPopup/Extensions/UIViewExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,21 @@
import UIKit

extension UIView {
func makeRoundCorners(_ corners: UIRectCorner = .allCorners, radius: CGFloat, superelliptic: Bool = false) {
if superelliptic {
let maskPath = UIBezierPath(
roundedRect: bounds,
byRoundingCorners: corners,
cornerRadii: CGSize(width: radius, height: radius)
)
let shape = CAShapeLayer()
shape.path = maskPath.cgPath
layer.mask = shape
} else {
layer.cornerRadius = radius
layer.masksToBounds = true
/**
ALPopup: Correct rounded corners by current frame.

- important:
Need call after changed frame. Better leave it in `layoutSubviews` method.

- parameter corners: Case of `CACornerMask`
- parameter radius: Amount of radius.
*/
public func roundCorners(_ corners: CACornerMask = [.layerMaxXMaxYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMinXMinYCorner], radius: CGFloat, continuous: Bool = false) {
layer.cornerRadius = radius
layer.maskedCorners = corners

if #available(iOS 13, *), continuous {
layer.cornerCurve = .continuous
}
}
}
4 changes: 3 additions & 1 deletion Sources/ALPopup/Helpers/ALAnimate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ enum ALAnimate {
delay: delay,
usingSpringWithDamping: damping,
initialSpringVelocity: velocity,
options: [.curveEaseInOut, .allowUserInteraction],
options: [.curveEaseInOut,
.allowUserInteraction,
.preferredFramesPerSecond60],
animations: {
animate()
}, completion: { _ in })
Expand Down
2 changes: 1 addition & 1 deletion Sources/ALPopup/UIElements/Controls/ALActionButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ open class ALActionButton: ALBasicButton {

open override func layoutSubviews() {
super.layoutSubviews()
makeRoundCorners(radius: roundCorners)
roundCorners(radius: roundCorners, continuous: true)
}

open override func applyDefaultAppearance(with colorise: ALBasicButton.Colorise? = nil) {
Expand Down
Loading

0 comments on commit f9e88d0

Please sign in to comment.