Compare commits

..

1 Commits

8 changed files with 91 additions and 39 deletions

View File

@ -1,4 +1,4 @@
// swift-tools-version:5.0
// swift-tools-version:5.2
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription

View File

@ -2,12 +2,12 @@ Pod::Spec.new do |s|
s.name = 'TICoordinatorKit'
s.version = '1.1.7'
s.summary = 'A framework for performing navigation in iOS application.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/TICoordinatorKit/'
s.homepage = 'https://github.com/TouchInstinct/TICoordinatorKit'
s.license = 'Apache License, Version 2.0'
s.author = 'Touch Instinct'
s.source = { :git => 'https://git.svc.touchin.ru/TouchInstinct/TICoordinatorKit.git', :tag => s.version.to_s }
s.source = { :git => 'https://github.com/TouchInstinct/TICoordinatorKit.git', :tag => s.version.to_s }
s.ios.deployment_target = '9.0'
s.source_files = 'TICoordinatorKit/Classes/**/*'
s.frameworks = 'UIKit'
s.swift_versions = ['5.0']
s.swift_versions = ['5.2']
end

View File

@ -24,7 +24,7 @@ import UIKit
public final class ModalRouter: ModalRoutable {
private var childRootControllers: [UIViewController] = []
private var childRootControllers: WeakArray<UIViewController> = []
public private(set) weak var rootController: UIViewController?
public private(set) weak var topController: UIViewController?
@ -72,18 +72,11 @@ public final class ModalRouter: ModalRoutable {
}
public func dismissModule(animated: Bool, completion: (() -> ())?) {
let dismissCompletion = {
self.topController = self.rootController
self.childRootControllers = []
rootController?.dismiss(animated: animated) { [weak self] in
self?.topController = self?.rootController
self?.childRootControllers = []
completion?()
}
guard rootController?.presentedViewController != nil else {
dismissCompletion()
return
}
rootController?.dismiss(animated: animated, completion: dismissCompletion)
}
public func presentChild(_ module: Presentable?,

View File

@ -51,21 +51,3 @@ public protocol StackRoutable: ModalRoutable {
func pop(to module: Presentable?)
func pop(to module: Presentable?, animated: Bool)
}
public extension StackRoutable {
var headModuleInTheStack: Bool {
if let headModule = headModule, headModule.toPresent()?.parent === toPresent() {
return true
}
return false
}
func withAnimationCompletion(_ animationCompletion: (() -> Void)?,
routerActions: (StackRoutable) -> Void) {
CATransaction.begin()
CATransaction.setCompletionBlock(animationCompletion)
routerActions(self)
CATransaction.commit()
}
}

View File

@ -24,7 +24,7 @@ import UIKit
open class StackRouter: StackRoutable {
private var completions: [UIViewController: () -> ()]
private var completions: NSMapTable<UIViewController, CallbackWrapper> = NSMapTable.weakToStrongObjects()
private lazy var modalRouter: ModalRoutable? = { [weak self] in
guard let rootController = self?.rootController else {
@ -35,7 +35,7 @@ open class StackRouter: StackRoutable {
public private(set) weak var rootController: UINavigationController?
public var headModule: Presentable?
public weak var headModule: Presentable?
public var topModule: Presentable? {
return rootController?.topViewController
@ -44,7 +44,6 @@ open class StackRouter: StackRoutable {
public init(_ rootController: UINavigationController) {
self.rootController = rootController
self.headModule = rootController.topViewController
self.completions = [:]
}
// MARK: - StackRoutable
@ -78,7 +77,7 @@ open class StackRouter: StackRoutable {
configurationClosure?(controller)
if let completion = completion {
completions[controller] = completion
completions.setObject(CallbackWrapper(callback: completion), forKey: controller)
}
rootController?.pushViewController(controller, animated: animated)
}
@ -197,8 +196,8 @@ open class StackRouter: StackRoutable {
}
public func runCompletion(for controller: UIViewController) {
completions[controller]?()
completions.removeValue(forKey: controller)
completions.object(forKey: controller)?()
completions.removeObject(forKey: controller)
}
public func runCompletionsChain(of controllers: [UIViewController]) {

View File

@ -0,0 +1,11 @@
public final class CallbackWrapper {
private let callback: () -> ()
public init(callback: @escaping () -> ()) {
self.callback = callback
}
public func callAsFunction() {
callback()
}
}

View File

@ -0,0 +1,38 @@
struct WeakArray<Element>: RangeReplaceableCollection where Element: AnyObject {
private var boxedItems = [WeakRef<Element>]()
// MARK: - Collection
var startIndex: Int {
boxedItems.startIndex
}
var endIndex: Int {
boxedItems.endIndex
}
func index(after i: Int) -> Int {
boxedItems.index(after: i)
}
subscript(position: Int) -> Element? {
boxedItems[position].value
}
// MARK: - RangeReplaceableCollection
init() {
self.boxedItems = []
}
init(elements: [Element]) {
self.boxedItems = elements.map(WeakRef.init)
}
}
extension WeakArray: ExpressibleByArrayLiteral {
init(arrayLiteral elements: Element...) {
self.init(elements: elements)
}
}

View File

@ -0,0 +1,29 @@
//
// Copyright (c) 2022 Touch Instinct
//
// 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.
//
struct WeakRef<RefType: AnyObject> {
private(set) weak var value: RefType?
init(value: RefType?) {
self.value = value
}
}