From 5017e7e7b7f39c281ca5b95239d6b765aa16db48 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Fri, 23 Dec 2022 11:09:55 +0300 Subject: [PATCH] feat: URLInteractiveTextView for terms and conditions hints in login flow --- CHANGELOG.md | 4 ++ LeadKit.podspec | 2 +- TIAppleMapUtils/TIAppleMapUtils.podspec | 2 +- TIAuth/TIAuth.podspec | 2 +- TIEcommerce/TIEcommerce.podspec | 2 +- TIFoundationUtils/TIFoundationUtils.podspec | 2 +- TIGoogleMapUtils/TIGoogleMapUtils.podspec | 2 +- TIKeychainUtils/TIKeychainUtils.podspec | 2 +- TILogging/TILogging.podspec | 2 +- TIMapUtils/TIMapUtils.podspec | 2 +- TIMoyaNetworking/TIMoyaNetworking.podspec | 2 +- TINetworking/TINetworking.podspec | 2 +- TINetworkingCache/TINetworkingCache.podspec | 2 +- TIPagination/TIPagination.podspec | 2 +- TISwiftUICore/TISwiftUICore.podspec | 2 +- TISwiftUtils/TISwiftUtils.podspec | 2 +- TITableKitUtils/TITableKitUtils.podspec | 2 +- TITransitions/TITransitions.podspec | 2 +- .../Views/BaseInitializeableTextView.swift | 60 +++++++++++++++++ ...faultUITextViewURLInteractionHandler.swift | 42 ++++++++++++ .../UITextView+InteractiveParts.swift | 64 +++++++++++++++++++ .../UITextViewURLInteractionHandler.swift | 28 ++++++++ .../URLInteractiveTextView.swift | 53 +++++++++++++++ .../URLInteractiveTextViewModel.swift | 59 +++++++++++++++++ TIUIElements/TIUIElements.podspec | 2 +- TIUIKitCore/TIUIKitCore.podspec | 2 +- TIYandexMapUtils/TIYandexMapUtils.podspec | 2 +- 27 files changed, 330 insertions(+), 20 deletions(-) create mode 100644 TIUIElements/Sources/Views/BaseInitializeableTextView.swift create mode 100644 TIUIElements/Sources/Views/URLInteractiveTextView/DefaultUITextViewURLInteractionHandler.swift create mode 100644 TIUIElements/Sources/Views/URLInteractiveTextView/UITextView+InteractiveParts.swift create mode 100644 TIUIElements/Sources/Views/URLInteractiveTextView/UITextViewURLInteractionHandler.swift create mode 100644 TIUIElements/Sources/Views/URLInteractiveTextView/URLInteractiveTextView.swift create mode 100644 TIUIElements/Sources/Views/URLInteractiveTextView/URLInteractiveTextViewModel.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e303738..547b2094 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +### 1.31.0 + +- **Added**: `URLInteractiveTextView` for terms and conditions hints in login flow + ### 1.30.0 - **Added**: Base classes for encryption and decryption user token with pin code or biometry diff --git a/LeadKit.podspec b/LeadKit.podspec index 77369e54..28681540 100644 --- a/LeadKit.podspec +++ b/LeadKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "LeadKit" - s.version = "1.30.0" + s.version = "1.31.0" s.summary = "iOS framework with a bunch of tools for rapid development" s.homepage = "https://github.com/TouchInstinct/LeadKit" s.license = "Apache License, Version 2.0" diff --git a/TIAppleMapUtils/TIAppleMapUtils.podspec b/TIAppleMapUtils/TIAppleMapUtils.podspec index 80a3f947..bb40275c 100644 --- a/TIAppleMapUtils/TIAppleMapUtils.podspec +++ b/TIAppleMapUtils/TIAppleMapUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIAppleMapUtils' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Set of helpers for map objects clustering and interacting using Apple MapKit.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIAuth/TIAuth.podspec b/TIAuth/TIAuth.podspec index 75915749..61653f55 100644 --- a/TIAuth/TIAuth.podspec +++ b/TIAuth/TIAuth.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIAuth' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Login, registration, confirmation and other related actions' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIEcommerce/TIEcommerce.podspec b/TIEcommerce/TIEcommerce.podspec index e65a3a19..37550a6c 100644 --- a/TIEcommerce/TIEcommerce.podspec +++ b/TIEcommerce/TIEcommerce.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIEcommerce' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Cart, products, promocodes, bonuses and other related actions' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIFoundationUtils/TIFoundationUtils.podspec b/TIFoundationUtils/TIFoundationUtils.podspec index 63f45a58..bbac7668 100644 --- a/TIFoundationUtils/TIFoundationUtils.podspec +++ b/TIFoundationUtils/TIFoundationUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIFoundationUtils' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Set of helpers for Foundation framework classes.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIGoogleMapUtils/TIGoogleMapUtils.podspec b/TIGoogleMapUtils/TIGoogleMapUtils.podspec index 99e30625..187cac21 100644 --- a/TIGoogleMapUtils/TIGoogleMapUtils.podspec +++ b/TIGoogleMapUtils/TIGoogleMapUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIGoogleMapUtils' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Set of helpers for map objects clustering and interacting using Google Maps SDK.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIKeychainUtils/TIKeychainUtils.podspec b/TIKeychainUtils/TIKeychainUtils.podspec index b0a6525e..84abca4e 100644 --- a/TIKeychainUtils/TIKeychainUtils.podspec +++ b/TIKeychainUtils/TIKeychainUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIKeychainUtils' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Set of helpers for Keychain classes.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TILogging/TILogging.podspec b/TILogging/TILogging.podspec index 20b9d4b6..63ab9d9a 100644 --- a/TILogging/TILogging.podspec +++ b/TILogging/TILogging.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TILogging' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Logging API' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIMapUtils/TIMapUtils.podspec b/TIMapUtils/TIMapUtils.podspec index 578a4eb3..d55b1741 100644 --- a/TIMapUtils/TIMapUtils.podspec +++ b/TIMapUtils/TIMapUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIMapUtils' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Set of helpers for map objects clustering and interacting.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIMoyaNetworking/TIMoyaNetworking.podspec b/TIMoyaNetworking/TIMoyaNetworking.podspec index 867865d6..3f6c548d 100644 --- a/TIMoyaNetworking/TIMoyaNetworking.podspec +++ b/TIMoyaNetworking/TIMoyaNetworking.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIMoyaNetworking' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Moya + Swagger network service.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TINetworking/TINetworking.podspec b/TINetworking/TINetworking.podspec index 8f92f73a..1465c72c 100644 --- a/TINetworking/TINetworking.podspec +++ b/TINetworking/TINetworking.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TINetworking' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Swagger-frendly networking layer helpers.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TINetworkingCache/TINetworkingCache.podspec b/TINetworkingCache/TINetworkingCache.podspec index 3131de4f..3273b93d 100644 --- a/TINetworkingCache/TINetworkingCache.podspec +++ b/TINetworkingCache/TINetworkingCache.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TINetworkingCache' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Caching results of EndpointRequests.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIPagination/TIPagination.podspec b/TIPagination/TIPagination.podspec index 1df31c1f..3c5091ce 100644 --- a/TIPagination/TIPagination.podspec +++ b/TIPagination/TIPagination.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIPagination' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Generic pagination component.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TISwiftUICore/TISwiftUICore.podspec b/TISwiftUICore/TISwiftUICore.podspec index f9a4a99a..803f5ae1 100644 --- a/TISwiftUICore/TISwiftUICore.podspec +++ b/TISwiftUICore/TISwiftUICore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TISwiftUICore' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Core UI elements: protocols, views and helpers.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TISwiftUtils/TISwiftUtils.podspec b/TISwiftUtils/TISwiftUtils.podspec index fc9189e6..8e5af467 100644 --- a/TISwiftUtils/TISwiftUtils.podspec +++ b/TISwiftUtils/TISwiftUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TISwiftUtils' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Bunch of useful helpers for Swift development.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TITableKitUtils/TITableKitUtils.podspec b/TITableKitUtils/TITableKitUtils.podspec index fe06f081..b7e7787e 100644 --- a/TITableKitUtils/TITableKitUtils.podspec +++ b/TITableKitUtils/TITableKitUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TITableKitUtils' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Set of helpers for TableKit classes.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TITransitions/TITransitions.podspec b/TITransitions/TITransitions.podspec index e27da747..20a90230 100644 --- a/TITransitions/TITransitions.podspec +++ b/TITransitions/TITransitions.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TITransitions' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Set of custom transitions to present controller. ' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIUIElements/Sources/Views/BaseInitializeableTextView.swift b/TIUIElements/Sources/Views/BaseInitializeableTextView.swift new file mode 100644 index 00000000..b34711c9 --- /dev/null +++ b/TIUIElements/Sources/Views/BaseInitializeableTextView.swift @@ -0,0 +1,60 @@ +// +// 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. +// + +import UIKit.UITextView +import TIUIKitCore + +open class BaseInitializeableTextView: UITextView, InitializableViewProtocol { + public override init(frame: CGRect, textContainer: NSTextContainer?) { + super.init(frame: frame, textContainer: textContainer) + + initializeView() + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + initializeView() + } + + // MARK: - InitializableView + + open func addViews() { + // override in subclass + } + + open func configureLayout() { + // override in subclass + } + + open func bindViews() { + // override in subclass + } + + open func configureAppearance() { + // override in subclass + } + + open func localize() { + // override in subclass + } +} diff --git a/TIUIElements/Sources/Views/URLInteractiveTextView/DefaultUITextViewURLInteractionHandler.swift b/TIUIElements/Sources/Views/URLInteractiveTextView/DefaultUITextViewURLInteractionHandler.swift new file mode 100644 index 00000000..1b3546d9 --- /dev/null +++ b/TIUIElements/Sources/Views/URLInteractiveTextView/DefaultUITextViewURLInteractionHandler.swift @@ -0,0 +1,42 @@ +// +// 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. +// + +import UIKit.UITextView +import TISwiftUtils + +open class DefaultUITextViewURLInteractionHandler: NSObject, UITextViewURLInteractionHandler { + public var urlInteractionHandler: ParameterClosure? + + public init(urlInteractionHandler: ParameterClosure?) { + self.urlInteractionHandler = urlInteractionHandler + } + + open func textView(_ textView: UITextView, + shouldInteractWith URL: URL, + in characterRange: NSRange, + interaction: UITextItemInteraction) -> Bool { + + urlInteractionHandler?(URL) + + return false + } +} diff --git a/TIUIElements/Sources/Views/URLInteractiveTextView/UITextView+InteractiveParts.swift b/TIUIElements/Sources/Views/URLInteractiveTextView/UITextView+InteractiveParts.swift new file mode 100644 index 00000000..9300b12c --- /dev/null +++ b/TIUIElements/Sources/Views/URLInteractiveTextView/UITextView+InteractiveParts.swift @@ -0,0 +1,64 @@ +// +// 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. +// + +import UIKit.UITextView +import TIUIKitCore + +public extension UITextView { + private typealias InteractiveRange = (range: Range, url: URL) + + struct InteractivePart { + public let text: String + public let url: URL? + + public init(text: String, url: URL?) { + self.text = text + self.url = url + } + } + + func set(text: String, + primaryTextStyle: BaseTextAttributes, + interactiveParts: [InteractivePart], + interactivePartsStyle: BaseTextAttributes) { + + let mutableAttributedText = NSMutableAttributedString(string: text, attributes: primaryTextStyle.attributedStringAttributes) + + let interactiveAttributes = interactivePartsStyle.attributedStringAttributes + + interactiveParts + .compactMap { interactivePart -> InteractiveRange? in + guard let range = text.range(of: interactivePart.text), + let url = interactivePart.url + else { + return nil + } + + return InteractiveRange(range: range, url: url) + } + .forEach { range, url in + mutableAttributedText.addAttributes(interactiveAttributes, range: NSRange(range, in: text)) + } + + attributedText = mutableAttributedText + } +} diff --git a/TIUIElements/Sources/Views/URLInteractiveTextView/UITextViewURLInteractionHandler.swift b/TIUIElements/Sources/Views/URLInteractiveTextView/UITextViewURLInteractionHandler.swift new file mode 100644 index 00000000..6108d0e0 --- /dev/null +++ b/TIUIElements/Sources/Views/URLInteractiveTextView/UITextViewURLInteractionHandler.swift @@ -0,0 +1,28 @@ +// +// 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. +// + +import UIKit.UITextView +import TISwiftUtils + +public protocol UITextViewURLInteractionHandler: UITextViewDelegate { + var urlInteractionHandler: ParameterClosure? { get set } +} diff --git a/TIUIElements/Sources/Views/URLInteractiveTextView/URLInteractiveTextView.swift b/TIUIElements/Sources/Views/URLInteractiveTextView/URLInteractiveTextView.swift new file mode 100644 index 00000000..324d8ada --- /dev/null +++ b/TIUIElements/Sources/Views/URLInteractiveTextView/URLInteractiveTextView.swift @@ -0,0 +1,53 @@ +// +// 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. +// + +import UIKit.UIGeometry +import TIUIKitCore + +open class URLInteractiveTextView: BaseInitializeableTextView, ConfigurableView { + public var interactionHandler: UITextViewURLInteractionHandler? { + didSet { + delegate = interactionHandler + } + } + + open override func configureAppearance() { + super.configureAppearance() + + isEditable = false + + textContainerInset = UIEdgeInsets(top: .zero, + left: -textContainer.lineFragmentPadding, + bottom: .zero, + right: -textContainer.lineFragmentPadding) + } + + public func configure(with viewModel: URLInteractiveTextViewModel) { + set(text: viewModel.text, + primaryTextStyle: viewModel.primaryTextStyle, + interactiveParts: viewModel.interactiveParts, + interactivePartsStyle: viewModel.interactivePartsStyle) + + interactionHandler = viewModel.interactionHandler + } + +} diff --git a/TIUIElements/Sources/Views/URLInteractiveTextView/URLInteractiveTextViewModel.swift b/TIUIElements/Sources/Views/URLInteractiveTextView/URLInteractiveTextViewModel.swift new file mode 100644 index 00000000..5ddad386 --- /dev/null +++ b/TIUIElements/Sources/Views/URLInteractiveTextView/URLInteractiveTextViewModel.swift @@ -0,0 +1,59 @@ +// +// 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. +// + +import TISwiftUtils +import TIUIKitCore +import UIKit.UITextView + +open class URLInteractiveTextViewModel { + public var text: String + public var primaryTextStyle: BaseTextAttributes + public var interactiveParts: [UITextView.InteractivePart] + public var interactivePartsStyle: BaseTextAttributes + public var interactionHandler: UITextViewURLInteractionHandler? + + public init(text: String, + primaryTextStyle: BaseTextAttributes, + interactiveParts: [UITextView.InteractivePart], + interactivePartsStyle: BaseTextAttributes, + interactionHandler: UITextViewURLInteractionHandler?) { + + self.text = text + self.primaryTextStyle = primaryTextStyle + self.interactiveParts = interactiveParts + self.interactivePartsStyle = interactivePartsStyle + self.interactionHandler = interactionHandler + } + + convenience init(text: String, + primaryTextStyle: BaseTextAttributes, + interactiveParts: [UITextView.InteractivePart], + interactivePartsStyle: BaseTextAttributes, + urlInteractionHandler: ParameterClosure?) { + + self.init(text: text, + primaryTextStyle: primaryTextStyle, + interactiveParts: interactiveParts, + interactivePartsStyle: interactivePartsStyle, + interactionHandler: DefaultUITextViewURLInteractionHandler(urlInteractionHandler: urlInteractionHandler)) + } +} diff --git a/TIUIElements/TIUIElements.podspec b/TIUIElements/TIUIElements.podspec index bb4eadba..f71b2b97 100644 --- a/TIUIElements/TIUIElements.podspec +++ b/TIUIElements/TIUIElements.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIUIElements' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Bunch of useful protocols and views.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIUIKitCore/TIUIKitCore.podspec b/TIUIKitCore/TIUIKitCore.podspec index 533371cd..ccdab3b8 100644 --- a/TIUIKitCore/TIUIKitCore.podspec +++ b/TIUIKitCore/TIUIKitCore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIUIKitCore' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Core UI elements: protocols, views and helpers.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIYandexMapUtils/TIYandexMapUtils.podspec b/TIYandexMapUtils/TIYandexMapUtils.podspec index ff7ea34a..7ba1b0ea 100644 --- a/TIYandexMapUtils/TIYandexMapUtils.podspec +++ b/TIYandexMapUtils/TIYandexMapUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIYandexMapUtils' - s.version = '1.30.0' + s.version = '1.31.0' s.summary = 'Set of helpers for map objects clustering and interacting using Yandex Maps SDK.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' }