From 1c95cf315bc59e40b1b89a9fb898b64fc26aeecb Mon Sep 17 00:00:00 2001 From: anton Shepetuha Date: Wed, 11 Apr 2018 15:32:29 +0300 Subject: [PATCH 1/2] tap action for shout banner --- Source/Message.swift | 1 + Source/ShoutFactory.swift | 512 ++++++++++++++++++++------------------ Source/Showing.swift | 4 +- 3 files changed, 267 insertions(+), 250 deletions(-) diff --git a/Source/Message.swift b/Source/Message.swift index 53d1fad..f267e40 100644 --- a/Source/Message.swift +++ b/Source/Message.swift @@ -21,6 +21,7 @@ public struct Announcement { public var subtitle: String? public var image: UIImage? public var duration: TimeInterval + public var notifData: [AnyHashable : Any]? public var action: (() -> Void)? public init(title: String, subtitle: String? = nil, image: UIImage? = nil, duration: TimeInterval = 2, action: (() -> Void)? = nil) { diff --git a/Source/ShoutFactory.swift b/Source/ShoutFactory.swift index 37b99c6..8311625 100644 --- a/Source/ShoutFactory.swift +++ b/Source/ShoutFactory.swift @@ -3,266 +3,282 @@ import UIKit let shoutView = ShoutView() open class ShoutView: UIView { - - public struct Dimensions { - public static let indicatorHeight: CGFloat = 6 - public static let indicatorWidth: CGFloat = 50 - public static let imageSize: CGFloat = 48 - public static let imageOffset: CGFloat = 18 - public static var textOffset: CGFloat = 75 - public static var touchOffset: CGFloat = 40 - } - - open fileprivate(set) lazy var backgroundView: UIView = { - let view = UIView() - view.backgroundColor = ColorList.Shout.background - view.alpha = 0.98 - view.clipsToBounds = true - - return view - }() - - open fileprivate(set) lazy var indicatorView: UIView = { - let view = UIView() - view.backgroundColor = ColorList.Shout.dragIndicator - view.layer.cornerRadius = Dimensions.indicatorHeight / 2 - view.isUserInteractionEnabled = true - - return view - }() - - open fileprivate(set) lazy var imageView: UIImageView = { - let imageView = UIImageView() - imageView.layer.cornerRadius = Dimensions.imageSize / 2 - imageView.clipsToBounds = true - imageView.contentMode = .scaleAspectFill - - return imageView + + public struct Dimensions { + public static let indicatorHeight: CGFloat = 6 + public static let indicatorWidth: CGFloat = 50 + public static let imageSize: CGFloat = 48 + public static let imageOffset: CGFloat = 18 + public static var textOffset: CGFloat = 75 + public static var touchOffset: CGFloat = 40 + } + + open fileprivate(set) lazy var backgroundView: UIView = { + let view = UIView() + view.backgroundColor = ColorList.Shout.background + view.alpha = 0.98 + view.clipsToBounds = true + + return view }() - - open fileprivate(set) lazy var titleLabel: UILabel = { - let label = UILabel() - label.font = FontList.Shout.title - label.textColor = ColorList.Shout.title - label.numberOfLines = 2 - - return label + + open fileprivate(set) lazy var indicatorView: UIView = { + let view = UIView() + view.backgroundColor = ColorList.Shout.dragIndicator + view.layer.cornerRadius = Dimensions.indicatorHeight / 2 + view.isUserInteractionEnabled = true + + return view }() - - open fileprivate(set) lazy var subtitleLabel: UILabel = { - let label = UILabel() - label.font = FontList.Shout.subtitle - label.textColor = ColorList.Shout.subtitle - label.numberOfLines = 2 - - return label + + open fileprivate(set) lazy var imageView: UIImageView = { + let imageView = UIImageView() + imageView.layer.cornerRadius = Dimensions.imageSize / 2 + imageView.clipsToBounds = true + imageView.contentMode = .scaleAspectFill + + return imageView }() - - open fileprivate(set) lazy var tapGestureRecognizer: UITapGestureRecognizer = { [unowned self] in - let gesture = UITapGestureRecognizer() - gesture.addTarget(self, action: #selector(ShoutView.handleTapGestureRecognizer)) - - return gesture + + open fileprivate(set) lazy var titleLabel: UILabel = { + let label = UILabel() + label.font = FontList.Shout.title + label.textColor = ColorList.Shout.title + label.numberOfLines = 2 + + return label }() - - open fileprivate(set) lazy var panGestureRecognizer: UIPanGestureRecognizer = { [unowned self] in - let gesture = UIPanGestureRecognizer() - gesture.addTarget(self, action: #selector(ShoutView.handlePanGestureRecognizer)) - - return gesture + + open fileprivate(set) lazy var subtitleLabel: UILabel = { + let label = UILabel() + label.font = FontList.Shout.subtitle + label.textColor = ColorList.Shout.subtitle + label.numberOfLines = 2 + + return label }() - - open fileprivate(set) var announcement: Announcement? - open fileprivate(set) var displayTimer = Timer() - open fileprivate(set) var panGestureActive = false - open fileprivate(set) var shouldSilent = false - open fileprivate(set) var completion: (() -> ())? - - private var subtitleLabelOriginalHeight: CGFloat = 0 - private var internalHeight: CGFloat = 0 - - // MARK: - Initializers - - public override init(frame: CGRect) { - super.init(frame: frame) - - addSubview(backgroundView) - [imageView, titleLabel, subtitleLabel, indicatorView].forEach { - $0.autoresizingMask = [] - backgroundView.addSubview($0) + + open fileprivate(set) lazy var tapGestureRecognizer: UITapGestureRecognizer = { [unowned self] in + let gesture = UITapGestureRecognizer() + gesture.addTarget(self, action: #selector(ShoutView.handleTapGestureRecognizer)) + + return gesture + }() + + open fileprivate(set) lazy var panGestureRecognizer: UIPanGestureRecognizer = { [unowned self] in + let gesture = UIPanGestureRecognizer() + gesture.addTarget(self, action: #selector(ShoutView.handlePanGestureRecognizer)) + + return gesture + }() + + open fileprivate(set) var announcement: Announcement? + open fileprivate(set) var displayTimer = Timer() + open fileprivate(set) var panGestureActive = false + open fileprivate(set) var shouldSilent = false + open fileprivate(set) var completion: (() -> ())? + open fileprivate(set) var tapAction: (([AnyHashable: Any]?) -> Void)? + + private var subtitleLabelOriginalHeight: CGFloat = 0 + private var internalHeight: CGFloat = 0 + + // MARK: - Initializers + + public override init(frame: CGRect) { + super.init(frame: frame) + + addSubview(backgroundView) + [imageView, titleLabel, subtitleLabel, indicatorView].forEach { + $0.autoresizingMask = [] + backgroundView.addSubview($0) + } + + clipsToBounds = false + isUserInteractionEnabled = true + layer.shadowColor = UIColor.black.cgColor + layer.shadowOffset = CGSize(width: 0, height: 0.5) + layer.shadowOpacity = 0.1 + layer.shadowRadius = 0.5 + + backgroundView.addGestureRecognizer(tapGestureRecognizer) + addGestureRecognizer(panGestureRecognizer) + + NotificationCenter.default.addObserver(self, selector: #selector(ShoutView.orientationDidChange), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) } - - clipsToBounds = false - isUserInteractionEnabled = true - layer.shadowColor = UIColor.black.cgColor - layer.shadowOffset = CGSize(width: 0, height: 0.5) - layer.shadowOpacity = 0.1 - layer.shadowRadius = 0.5 - - backgroundView.addGestureRecognizer(tapGestureRecognizer) - addGestureRecognizer(panGestureRecognizer) - - NotificationCenter.default.addObserver(self, selector: #selector(ShoutView.orientationDidChange), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) - } - - public required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - deinit { - NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) - } - - // MARK: - Configuration - - open func craft(_ announcement: Announcement, to: UIViewController, completion: (() -> ())?) { - panGestureActive = false - shouldSilent = false - configureView(announcement) - shout(to: to) - - self.completion = completion - } - - open func configureView(_ announcement: Announcement) { - self.announcement = announcement - imageView.image = announcement.image - titleLabel.text = announcement.title - subtitleLabel.text = announcement.subtitle - - displayTimer.invalidate() - displayTimer = Timer.scheduledTimer(timeInterval: announcement.duration, - target: self, selector: #selector(ShoutView.displayTimerDidFire), userInfo: nil, repeats: false) - - setupFrames() - } - - open func shout(to controller: UIViewController) { - controller.view.addSubview(self) - - frame.size.height = 0 - UIView.animate(withDuration: 0.35, animations: { - self.frame.size.height = self.internalHeight + Dimensions.touchOffset - }) - } - - // MARK: - Setup - - public func setupFrames() { - internalHeight = (UIApplication.shared.isStatusBarHidden ? 55 : 65) - - let totalWidth = UIScreen.main.bounds.width - let offset: CGFloat = UIApplication.shared.isStatusBarHidden ? 2.5 : 5 - let textOffsetX: CGFloat = imageView.image != nil ? Dimensions.textOffset : 18 - let imageSize: CGFloat = imageView.image != nil ? Dimensions.imageSize : 0 - - [titleLabel, subtitleLabel].forEach { - $0.frame.size.width = totalWidth - imageSize - (Dimensions.imageOffset * 2) - $0.sizeToFit() + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") } - - internalHeight += subtitleLabel.frame.height - - imageView.frame = CGRect(x: Dimensions.imageOffset, y: (internalHeight - imageSize) / 2 + offset, - width: imageSize, height: imageSize) - - let textOffsetY = imageView.image != nil ? imageView.frame.origin.x + 3 : textOffsetX + 5 - - titleLabel.frame.origin = CGPoint(x: textOffsetX, y: textOffsetY) - subtitleLabel.frame.origin = CGPoint(x: textOffsetX, y: titleLabel.frame.maxY + 2.5) - - if subtitleLabel.text?.isEmpty ?? true { - titleLabel.center.y = imageView.center.y - 2.5 + + deinit { + NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) } - - frame = CGRect(x: 0, y: safeYCoordinate, - width: totalWidth, height: internalHeight + Dimensions.touchOffset) - } - - // MARK: - Frame - - open override var frame: CGRect { - didSet { - backgroundView.frame = CGRect(x: 0, y: safeYCoordinate, - width: frame.size.width, - height: frame.size.height - Dimensions.touchOffset) - - indicatorView.frame = CGRect(x: (backgroundView.frame.size.width - Dimensions.indicatorWidth) / 2, - y: backgroundView.frame.height - Dimensions.indicatorHeight - 5, - width: Dimensions.indicatorWidth, - height: Dimensions.indicatorHeight) + + // MARK: - Configuration + + open func craft(_ announcement: Announcement, to: UIViewController, completion: (() -> ())?, tapAction: (([AnyHashable: Any]?) -> Void)?) { + panGestureActive = false + shouldSilent = false + configureView(announcement) + shout(to: to) + self.tapAction = tapAction + self.completion = completion } - } - - // MARK: - Actions - - open func silent() { - UIView.animate(withDuration: 0.35, animations: { - self.frame.size.height = 0 - }, completion: { finished in - self.completion?() - self.displayTimer.invalidate() - self.removeFromSuperview() - }) - } - - // MARK: - Timer methods - - @objc open func displayTimerDidFire() { - shouldSilent = true - - if panGestureActive { return } - silent() - } - - // MARK: - Gesture methods - - @objc fileprivate func handleTapGestureRecognizer() { - guard let announcement = announcement else { return } - announcement.action?() - silent() - } - - @objc private func handlePanGestureRecognizer() { - let translation = panGestureRecognizer.translation(in: self) - - if panGestureRecognizer.state == .began { - subtitleLabelOriginalHeight = subtitleLabel.bounds.size.height - subtitleLabel.numberOfLines = 0 - subtitleLabel.sizeToFit() - } else if panGestureRecognizer.state == .changed { - panGestureActive = true - - let maxTranslation = subtitleLabel.bounds.size.height - subtitleLabelOriginalHeight - - if translation.y >= maxTranslation { - frame.size.height = internalHeight + maxTranslation - + (translation.y - maxTranslation) / 25 + Dimensions.touchOffset - } else { - frame.size.height = internalHeight + translation.y + Dimensions.touchOffset - } - } else { - panGestureActive = false - let height = translation.y < -5 || shouldSilent ? 0 : internalHeight - - subtitleLabel.numberOfLines = 2 - subtitleLabel.sizeToFit() - - UIView.animate(withDuration: 0.2, animations: { - self.frame.size.height = height + Dimensions.touchOffset - }, completion: { _ in - if translation.y < -5 { + + open func configureView(_ announcement: Announcement) { + self.announcement = announcement + imageView.image = announcement.image + titleLabel.text = announcement.title + subtitleLabel.text = announcement.subtitle + + displayTimer.invalidate() + displayTimer = Timer.scheduledTimer(timeInterval: announcement.duration, + target: self, selector: #selector(ShoutView.displayTimerDidFire), userInfo: nil, repeats: false) + + setupFrames() + let button = UIButton() + button.translatesAutoresizingMaskIntoConstraints = false + button.addTarget(self, action: #selector(tapGestureAction), for: .touchUpInside) + button.backgroundColor = .clear + self.addSubview(button) + button.topAnchor.constraint(equalTo: self.topAnchor).isActive = true + button.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true + button.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true + button.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true + } + + @objc func tapGestureAction() { + if let tapAction = self.tapAction, let announcement = self.announcement { + tapAction(announcement.notifData) + } + } + + open func shout(to controller: UIViewController) { + controller.view.addSubview(self) + + frame.size.height = 0 + UIView.animate(withDuration: 0.35, animations: { + self.frame.size.height = self.internalHeight + Dimensions.touchOffset + }) + } + + // MARK: - Setup + + public func setupFrames() { + internalHeight = (UIApplication.shared.isStatusBarHidden ? 55 : 65) + + let totalWidth = UIScreen.main.bounds.width + let offset: CGFloat = UIApplication.shared.isStatusBarHidden ? 2.5 : 5 + let textOffsetX: CGFloat = imageView.image != nil ? Dimensions.textOffset : 18 + let imageSize: CGFloat = imageView.image != nil ? Dimensions.imageSize : 0 + + [titleLabel, subtitleLabel].forEach { + $0.frame.size.width = totalWidth - imageSize - (Dimensions.imageOffset * 2) + $0.sizeToFit() + } + + internalHeight += subtitleLabel.frame.height + + imageView.frame = CGRect(x: Dimensions.imageOffset, y: (internalHeight - imageSize) / 2 + offset, + width: imageSize, height: imageSize) + + let textOffsetY = imageView.image != nil ? imageView.frame.origin.x + 3 : textOffsetX + 5 + + titleLabel.frame.origin = CGPoint(x: textOffsetX, y: textOffsetY) + subtitleLabel.frame.origin = CGPoint(x: textOffsetX, y: titleLabel.frame.maxY + 2.5) + + if subtitleLabel.text?.isEmpty ?? true { + titleLabel.center.y = imageView.center.y - 2.5 + } + + frame = CGRect(x: 0, y: safeYCoordinate, + width: totalWidth, height: internalHeight + Dimensions.touchOffset) + } + + // MARK: - Frame + + open override var frame: CGRect { + didSet { + backgroundView.frame = CGRect(x: 0, y: safeYCoordinate, + width: frame.size.width, + height: frame.size.height - Dimensions.touchOffset) + + indicatorView.frame = CGRect(x: (backgroundView.frame.size.width - Dimensions.indicatorWidth) / 2, + y: backgroundView.frame.height - Dimensions.indicatorHeight - 5, + width: Dimensions.indicatorWidth, + height: Dimensions.indicatorHeight) + } + } + + // MARK: - Actions + + open func silent() { + UIView.animate(withDuration: 0.35, animations: { + self.frame.size.height = 0 + }, completion: { finished in self.completion?() + self.displayTimer.invalidate() self.removeFromSuperview() + }) + } + + // MARK: - Timer methods + + @objc open func displayTimerDidFire() { + shouldSilent = true + + if panGestureActive { return } + silent() + } + + // MARK: - Gesture methods + + @objc fileprivate func handleTapGestureRecognizer() { + guard let announcement = announcement else { return } + announcement.action?() + silent() + } + + @objc private func handlePanGestureRecognizer() { + let translation = panGestureRecognizer.translation(in: self) + + if panGestureRecognizer.state == .began { + subtitleLabelOriginalHeight = subtitleLabel.bounds.size.height + subtitleLabel.numberOfLines = 0 + subtitleLabel.sizeToFit() + } else if panGestureRecognizer.state == .changed { + panGestureActive = true + + let maxTranslation = subtitleLabel.bounds.size.height - subtitleLabelOriginalHeight + + if translation.y >= maxTranslation { + frame.size.height = internalHeight + maxTranslation + + (translation.y - maxTranslation) / 25 + Dimensions.touchOffset + } else { + frame.size.height = internalHeight + translation.y + Dimensions.touchOffset + } + } else { + panGestureActive = false + let height = translation.y < -5 || shouldSilent ? 0 : internalHeight + + subtitleLabel.numberOfLines = 2 + subtitleLabel.sizeToFit() + + UIView.animate(withDuration: 0.2, animations: { + self.frame.size.height = height + Dimensions.touchOffset + }, completion: { _ in + if translation.y < -5 { + self.completion?() + self.removeFromSuperview() + } + }) } - }) } - } - - - // MARK: - Handling screen orientation - + + + // MARK: - Handling screen orientation + @objc func orientationDidChange() { - setupFrames() - } + setupFrames() + } } diff --git a/Source/Showing.swift b/Source/Showing.swift index 9bec63d..28b0afc 100644 --- a/Source/Showing.swift +++ b/Source/Showing.swift @@ -4,8 +4,8 @@ public func show(whisper message: Message, to: UINavigationController, action: W whisperFactory.craft(message, navigationController: to, action: action) } -public func show(shout announcement: Announcement, to: UIViewController, completion: (() -> Void)? = nil) { - shoutView.craft(announcement, to: to, completion: completion) +public func show(shout announcement: Announcement, to: UIViewController, completion: (() -> Void)? = nil, tapAction: (([AnyHashable: Any]?) -> Void)? = nil) { + shoutView.craft(announcement, to: to, completion: completion, tapAction: tapAction) } public func show(whistle murmur: Murmur, action: WhistleAction = .show(1.5)) { From caa24c87cd23f4217ef44d851f8351b62c16fffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D0=BB=D0=B8=D0=BA=20=D0=9C=D1=8F=D0=BB=D0=B8?= =?UTF-8?q?=D0=BD?= Date: Mon, 1 Apr 2019 11:20:42 +0300 Subject: [PATCH 2/2] migration to swift 5 --- Source/ShoutFactory.swift | 28 ++++++++++++++++++++++------ Source/WhisperFactory.swift | 14 +++++++------- Source/WhistleFactory.swift | 10 +++++----- Whisper.xcodeproj/project.pbxproj | 9 ++++++--- 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/Source/ShoutFactory.swift b/Source/ShoutFactory.swift index 8311625..e49ccb8 100644 --- a/Source/ShoutFactory.swift +++ b/Source/ShoutFactory.swift @@ -103,7 +103,7 @@ open class ShoutView: UIView { backgroundView.addGestureRecognizer(tapGestureRecognizer) addGestureRecognizer(panGestureRecognizer) - NotificationCenter.default.addObserver(self, selector: #selector(ShoutView.orientationDidChange), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(ShoutView.orientationDidChange), name: UIDevice.orientationDidChangeNotification, object: nil) } public required init?(coder aDecoder: NSCoder) { @@ -111,7 +111,7 @@ open class ShoutView: UIView { } deinit { - NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) + NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil) } // MARK: - Configuration @@ -141,10 +141,26 @@ open class ShoutView: UIView { button.addTarget(self, action: #selector(tapGestureAction), for: .touchUpInside) button.backgroundColor = .clear self.addSubview(button) - button.topAnchor.constraint(equalTo: self.topAnchor).isActive = true - button.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true - button.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true - button.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true + if #available(iOS 9.0, *) { + button.topAnchor.constraint(equalTo: self.topAnchor).isActive = true + } else { + // Fallback on earlier versions + } + if #available(iOS 9.0, *) { + button.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true + } else { + // Fallback on earlier versions + } + if #available(iOS 9.0, *) { + button.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true + } else { + // Fallback on earlier versions + } + if #available(iOS 9.0, *) { + button.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true + } else { + // Fallback on earlier versions + } } @objc func tapGestureAction() { diff --git a/Source/WhisperFactory.swift b/Source/WhisperFactory.swift index 380fe43..5799d95 100644 --- a/Source/WhisperFactory.swift +++ b/Source/WhisperFactory.swift @@ -28,11 +28,11 @@ class WhisperFactory: NSObject { override init() { super.init() - NotificationCenter.default.addObserver(self, selector: #selector(WhisperFactory.orientationDidChange), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(WhisperFactory.orientationDidChange), name: UIDevice.orientationDidChangeNotification, object: nil) } deinit { - NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) + NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil) } func craft(_ message: Message, navigationController: UINavigationController, action: WhisperAction) { @@ -237,14 +237,14 @@ class WhisperFactory: NSObject { if let tableView = viewController.view as? UITableView , viewController is UITableViewController { - tableView.contentInset = UIEdgeInsetsMake(tableView.contentInset.top + edgeInsetHeight, tableView.contentInset.left, tableView.contentInset.bottom, tableView.contentInset.right) + tableView.contentInset = UIEdgeInsets.init(top: tableView.contentInset.top + edgeInsetHeight, left: tableView.contentInset.left, bottom: tableView.contentInset.bottom, right: tableView.contentInset.right) } else if let collectionView = viewController.view as? UICollectionView , viewController is UICollectionViewController { - collectionView.contentInset = UIEdgeInsetsMake(collectionView.contentInset.top + edgeInsetHeight, collectionView.contentInset.left, collectionView.contentInset.bottom, collectionView.contentInset.right) + collectionView.contentInset = UIEdgeInsets.init(top: collectionView.contentInset.top + edgeInsetHeight, left: collectionView.contentInset.left, bottom: collectionView.contentInset.bottom, right: collectionView.contentInset.right) } else { for view in viewController.view.subviews { if let scrollView = view as? UIScrollView { - scrollView.contentInset = UIEdgeInsetsMake(scrollView.contentInset.top + edgeInsetHeight, scrollView.contentInset.left, scrollView.contentInset.bottom, scrollView.contentInset.right) + scrollView.contentInset = UIEdgeInsets.init(top: scrollView.contentInset.top + edgeInsetHeight, left: scrollView.contentInset.left, bottom: scrollView.contentInset.bottom, right: scrollView.contentInset.right) } } } @@ -280,7 +280,7 @@ extension WhisperFactory: UINavigationControllerDelegate { var maximumY = navigationController.navigationBar.frame.maxY - UIApplication.shared.statusBarFrame.height for subview in navigationController.navigationBar.subviews { - if subview is WhisperView { navigationController.navigationBar.bringSubview(toFront: subview) } + if subview is WhisperView { navigationController.navigationBar.bringSubviewToFront(subview) } if subview.frame.maxY > maximumY && !(subview is WhisperView) { maximumY = subview.frame.maxY @@ -295,7 +295,7 @@ extension WhisperFactory: UINavigationControllerDelegate { for subview in navigationController.navigationBar.subviews where subview is WhisperView { moveControllerViews(true) - if let index = navigationController.viewControllers.index(of: viewController) , index > 0 { + if let index = navigationController.viewControllers.firstIndex(of: viewController) , index > 0 { edgeInsetHeight = -WhisperView.Dimensions.height performControllerMove(navigationController.viewControllers[Int(index) - 1]) break diff --git a/Source/WhistleFactory.swift b/Source/WhistleFactory.swift index 679ba2b..d3dad51 100644 --- a/Source/WhistleFactory.swift +++ b/Source/WhistleFactory.swift @@ -55,7 +55,7 @@ open class WhistleFactory: UIViewController { view.addGestureRecognizer(tapGestureRecognizer) - NotificationCenter.default.addObserver(self, selector: #selector(WhistleFactory.orientationDidChange), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(WhistleFactory.orientationDidChange), name: UIDevice.orientationDidChangeNotification, object: nil) } public required init?(coder aDecoder: NSCoder) { @@ -63,7 +63,7 @@ open class WhistleFactory: UIViewController { } deinit { - NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) + NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil) } // MARK: - Configuration @@ -96,7 +96,7 @@ open class WhistleFactory: UIViewController { } func moveWindowToFront() { - whistleWindow.windowLevel = view.isiPhoneX ? UIWindowLevelNormal : UIWindowLevelStatusBar + whistleWindow.windowLevel = view.isiPhoneX ? UIWindow.Level.normal : UIWindow.Level.statusBar setNeedsStatusBarAppearanceUpdate() } @@ -117,7 +117,7 @@ open class WhistleFactory: UIViewController { NSString(string: text).boundingRect( with: CGSize(width: labelWidth, height: CGFloat.infinity), options: NSStringDrawingOptions.usesLineFragmentOrigin, - attributes: [NSAttributedStringKey.font: titleLabel.font], + attributes: [NSAttributedString.Key.font: titleLabel.font], context: nil ) titleLabelHeight = CGFloat(neededDimensions.size.height) @@ -172,7 +172,7 @@ open class WhistleFactory: UIViewController { }, completion: { _ in if let window = self.previousKeyWindow { window.isHidden = false - self.whistleWindow.windowLevel = UIWindowLevelNormal - 1 + self.whistleWindow.windowLevel = UIWindow.Level.normal - 1 self.previousKeyWindow = nil window.rootViewController?.setNeedsStatusBarAppearanceUpdate() } diff --git a/Whisper.xcodeproj/project.pbxproj b/Whisper.xcodeproj/project.pbxproj index aa0a8d6..9943c1c 100644 --- a/Whisper.xcodeproj/project.pbxproj +++ b/Whisper.xcodeproj/project.pbxproj @@ -138,7 +138,7 @@ TargetAttributes = { 290530F81C20511C00FB382C = { CreatedOnToolsVersion = 7.2; - LastSwiftMigration = 0800; + LastSwiftMigration = 1020; }; }; }; @@ -147,6 +147,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = 290530EF1C20511C00FB382C; @@ -240,7 +241,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -290,7 +291,7 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -313,6 +314,7 @@ PRODUCT_BUNDLE_IDENTIFIER = no.hyper.Whisper; PRODUCT_NAME = Whisper; SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -331,6 +333,7 @@ PRODUCT_BUNDLE_IDENTIFIER = no.hyper.Whisper; PRODUCT_NAME = Whisper; SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; }; name = Release; };