Merge pull request #114 from diegosanchezr/accessory-view-revealer-enhacements
Enhancements for accessory view revealer
This commit is contained in:
commit
c2c2d307c7
|
|
@ -23,6 +23,7 @@
|
|||
C36281EB1BF0F62F004D6BCE /* DummyChatItemPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C36281EA1BF0F62F004D6BCE /* DummyChatItemPresenter.swift */; };
|
||||
C36281ED1BF10086004D6BCE /* SerialTaskQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = C36281EC1BF10086004D6BCE /* SerialTaskQueue.swift */; };
|
||||
C36281F21BF12A4B004D6BCE /* ChatCollectionViewLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C36281F11BF12A4B004D6BCE /* ChatCollectionViewLayoutTests.swift */; };
|
||||
C38352D11CC6514B006C359C /* BaseChatViewController+AccessoryViewRevealer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C38352D01CC6514B006C359C /* BaseChatViewController+AccessoryViewRevealer.swift */; };
|
||||
C3C7C3971CAC4BAC00A49929 /* AccessoryViewRevealer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C7C3921CAC4BAC00A49929 /* AccessoryViewRevealer.swift */; };
|
||||
C3C7C3981CAC4BAC00A49929 /* ChatCollectionViewLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C7C3931CAC4BAC00A49929 /* ChatCollectionViewLayout.swift */; };
|
||||
C3C7C3991CAC4BAC00A49929 /* ChatDataSourceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C7C3941CAC4BAC00A49929 /* ChatDataSourceProtocol.swift */; };
|
||||
|
|
@ -64,6 +65,7 @@
|
|||
C36281EA1BF0F62F004D6BCE /* DummyChatItemPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DummyChatItemPresenter.swift; sourceTree = "<group>"; };
|
||||
C36281EC1BF10086004D6BCE /* SerialTaskQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SerialTaskQueue.swift; sourceTree = "<group>"; };
|
||||
C36281F11BF12A4B004D6BCE /* ChatCollectionViewLayoutTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatCollectionViewLayoutTests.swift; sourceTree = "<group>"; };
|
||||
C38352D01CC6514B006C359C /* BaseChatViewController+AccessoryViewRevealer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BaseChatViewController+AccessoryViewRevealer.swift"; sourceTree = "<group>"; };
|
||||
C3C7C3921CAC4BAC00A49929 /* AccessoryViewRevealer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccessoryViewRevealer.swift; sourceTree = "<group>"; };
|
||||
C3C7C3931CAC4BAC00A49929 /* ChatCollectionViewLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatCollectionViewLayout.swift; sourceTree = "<group>"; };
|
||||
C3C7C3941CAC4BAC00A49929 /* ChatDataSourceProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatDataSourceProtocol.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -200,6 +202,7 @@
|
|||
C36281E61BF0F196004D6BCE /* BaseChatViewController+Scrolling.swift */,
|
||||
C36281E41BF0F0F0004D6BCE /* BaseChatViewController+Changes.swift */,
|
||||
C3E904B11BE0509E00C662A2 /* BaseChatViewController+Presenters.swift */,
|
||||
C38352D01CC6514B006C359C /* BaseChatViewController+AccessoryViewRevealer.swift */,
|
||||
);
|
||||
path = ChatController;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -340,6 +343,7 @@
|
|||
C36281ED1BF10086004D6BCE /* SerialTaskQueue.swift in Sources */,
|
||||
C321DDAE1BE9649F00DE88CC /* ChatItemProtocolDefinitions.swift in Sources */,
|
||||
C36281E51BF0F0F0004D6BCE /* BaseChatViewController+Changes.swift in Sources */,
|
||||
C38352D11CC6514B006C359C /* BaseChatViewController+AccessoryViewRevealer.swift in Sources */,
|
||||
C342D0BD1C638681008A4605 /* ChatItemCompanion.swift in Sources */,
|
||||
C36281E71BF0F196004D6BCE /* BaseChatViewController+Scrolling.swift in Sources */,
|
||||
C36281EB1BF0F62F004D6BCE /* DummyChatItemPresenter.swift in Sources */,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-present Badoo Trading Limited.
|
||||
|
||||
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
|
||||
|
||||
public extension BaseChatViewController { // Accessory view revealer
|
||||
|
||||
public final var accessoryViewRevealerIsEnabled: Bool {
|
||||
get {
|
||||
return self.accessoryViewRevealer.isEnabled
|
||||
} set {
|
||||
self.accessoryViewRevealer.isEnabled = newValue
|
||||
}
|
||||
}
|
||||
|
||||
public final var accessoryViewRevealerConfig: AccessoryViewRevealerConfig {
|
||||
get {
|
||||
return self.accessoryViewRevealer.config
|
||||
} set {
|
||||
self.accessoryViewRevealer.config = newValue
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -29,12 +29,12 @@ public class BaseChatViewController: UIViewController, UICollectionViewDataSourc
|
|||
public typealias ChatItemCompanionCollection = ReadOnlyOrderedDictionary<ChatItemCompanion>
|
||||
|
||||
public struct Constants {
|
||||
var updatesAnimationDuration: NSTimeInterval = 0.33
|
||||
var defaultContentInsets = UIEdgeInsets(top: 10, left: 0, bottom: 10, right: 0)
|
||||
var defaultScrollIndicatorInsets = UIEdgeInsetsZero
|
||||
var preferredMaxMessageCount: Int? = 500 // It not nil, will ask data source to reduce number of messages when limit is reached. @see ChatDataSourceDelegateProtocol
|
||||
var preferredMaxMessageCountAdjustment: Int = 400 // When the above happens, will ask to adjust with this value. It may be wise for this to be smaller to reduce number of adjustments
|
||||
var autoloadingFractionalThreshold: CGFloat = 0.05 // in [0, 1]
|
||||
public var updatesAnimationDuration: NSTimeInterval = 0.33
|
||||
public var defaultContentInsets = UIEdgeInsets(top: 10, left: 0, bottom: 10, right: 0)
|
||||
public var defaultScrollIndicatorInsets = UIEdgeInsetsZero
|
||||
public var preferredMaxMessageCount: Int? = 500 // It not nil, will ask data source to reduce number of messages when limit is reached. @see ChatDataSourceDelegateProtocol
|
||||
public var preferredMaxMessageCountAdjustment: Int = 400 // When the above happens, will ask to adjust with this value. It may be wise for this to be smaller to reduce number of adjustments
|
||||
public var autoloadingFractionalThreshold: CGFloat = 0.05 // in [0, 1]
|
||||
}
|
||||
|
||||
public var constants = Constants()
|
||||
|
|
@ -228,7 +228,6 @@ public class BaseChatViewController: UIViewController, UICollectionViewDataSourc
|
|||
|
||||
var layoutModel = ChatCollectionViewLayoutModel.createModel(0, itemsLayoutData: [])
|
||||
|
||||
|
||||
// MARK: Subclass overrides
|
||||
|
||||
public func createPresenterFactory() -> ChatItemPresenterFactoryProtocol {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,24 @@ public protocol AccessoryViewRevealable {
|
|||
func preferredOffsetToRevealAccessoryView() -> CGFloat? // This allows to sync size in case cells have different sizes for the accessory view. Nil -> no restriction
|
||||
}
|
||||
|
||||
public struct AccessoryViewRevealerConfig {
|
||||
public let angleThresholdInRads: CGFloat
|
||||
public let translationTransform: (rawTranslation: CGFloat) -> CGFloat
|
||||
public init(angleThresholdInRads: CGFloat, translationTransform: (rawTranslation: CGFloat) -> CGFloat) {
|
||||
self.angleThresholdInRads = angleThresholdInRads
|
||||
self.translationTransform = translationTransform
|
||||
}
|
||||
|
||||
public static func defaultConfig() -> AccessoryViewRevealerConfig {
|
||||
return self.init(
|
||||
angleThresholdInRads: 0.0872665, // ~5 degrees
|
||||
translationTransform: { (rawTranslation) -> CGFloat in
|
||||
let threshold: CGFloat = 30
|
||||
return max(0, rawTranslation - threshold) / 2
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
class AccessoryViewRevealer: NSObject, UIGestureRecognizerDelegate {
|
||||
|
||||
private let panRecognizer: UIPanGestureRecognizer = UIPanGestureRecognizer()
|
||||
|
|
@ -42,6 +60,19 @@ class AccessoryViewRevealer: NSObject, UIGestureRecognizerDelegate {
|
|||
self.panRecognizer.delegate = self
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.panRecognizer.delegate = nil
|
||||
self.collectionView.removeGestureRecognizer(self.panRecognizer)
|
||||
}
|
||||
|
||||
var isEnabled: Bool = true {
|
||||
didSet {
|
||||
self.panRecognizer.enabled = self.isEnabled
|
||||
}
|
||||
}
|
||||
|
||||
var config = AccessoryViewRevealerConfig.defaultConfig()
|
||||
|
||||
@objc
|
||||
private func handlePan(panRecognizer: UIPanGestureRecognizer) {
|
||||
switch panRecognizer.state {
|
||||
|
|
@ -49,7 +80,7 @@ class AccessoryViewRevealer: NSObject, UIGestureRecognizerDelegate {
|
|||
break
|
||||
case .Changed:
|
||||
let translation = panRecognizer.translationInView(self.collectionView)
|
||||
self.revealAccessoryView(atOffset: -translation.x)
|
||||
self.revealAccessoryView(atOffset: self.config.translationTransform(rawTranslation: -translation.x))
|
||||
case .Ended, .Cancelled, .Failed:
|
||||
self.revealAccessoryView(atOffset: 0)
|
||||
default:
|
||||
|
|
@ -69,8 +100,7 @@ class AccessoryViewRevealer: NSObject, UIGestureRecognizerDelegate {
|
|||
let translation = self.panRecognizer.translationInView(self.collectionView)
|
||||
let x = CGFloat.abs(translation.x), y = CGFloat.abs(translation.y)
|
||||
let angleRads = atan2(y, x)
|
||||
let threshold: CGFloat = 0.0872665 // ~5 degrees
|
||||
return angleRads < threshold
|
||||
return angleRads <= self.config.angleThresholdInRads
|
||||
}
|
||||
|
||||
private func revealAccessoryView(atOffset offset: CGFloat) {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -14,7 +14,7 @@
|
|||
buildForArchiving = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = 'primary'
|
||||
BlueprintIdentifier = '2133E105521160184E5F0F6E'
|
||||
BlueprintIdentifier = 'C7F4FA12B57EB8DE411C6300'
|
||||
BlueprintName = 'Chatto'
|
||||
ReferencedContainer = 'container:Pods.xcodeproj'
|
||||
BuildableName = 'Chatto.framework'>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
buildForArchiving = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = 'primary'
|
||||
BlueprintIdentifier = 'D1C1AA8A44CE62A4012C171C'
|
||||
BlueprintIdentifier = '956677222A94B70EC3140B77'
|
||||
BlueprintName = 'ChattoAdditions'
|
||||
ReferencedContainer = 'container:Pods.xcodeproj'
|
||||
BuildableName = 'ChattoAdditions.framework'>
|
||||
|
|
|
|||
Loading…
Reference in New Issue