mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-07 09:20:08 +00:00
Fix scrolling
This commit is contained in:
parent
19bc67c9d3
commit
e732ec44a7
@ -2932,7 +2932,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
|||||||
if let index = itemNode.index, index == scrollToItem.index {
|
if let index = itemNode.index, index == scrollToItem.index {
|
||||||
let insets = self.insets// updateSizeAndInsets?.insets ?? self.insets
|
let insets = self.insets// updateSizeAndInsets?.insets ?? self.insets
|
||||||
|
|
||||||
let offset: CGFloat
|
var offset: CGFloat
|
||||||
switch scrollToItem.position {
|
switch scrollToItem.position {
|
||||||
case let .bottom(additionalOffset):
|
case let .bottom(additionalOffset):
|
||||||
offset = (self.visibleSize.height - insets.bottom) - itemNode.apparentFrame.maxY + itemNode.scrollPositioningInsets.bottom + additionalOffset
|
offset = (self.visibleSize.height - insets.bottom) - itemNode.apparentFrame.maxY + itemNode.scrollPositioningInsets.bottom + additionalOffset
|
||||||
@ -2948,6 +2948,13 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
|||||||
offset = insets.top - itemNode.apparentFrame.minY
|
offset = insets.top - itemNode.apparentFrame.minY
|
||||||
case .bottom:
|
case .bottom:
|
||||||
offset = (self.visibleSize.height - insets.bottom) - itemNode.apparentFrame.maxY
|
offset = (self.visibleSize.height - insets.bottom) - itemNode.apparentFrame.maxY
|
||||||
|
case let .custom(getOverflow):
|
||||||
|
let overflow = getOverflow(itemNode)
|
||||||
|
offset = (self.visibleSize.height - insets.bottom) - itemNode.apparentFrame.maxY
|
||||||
|
offset += floor(overflow - (self.visibleSize.height - insets.bottom - insets.top) * 0.5)
|
||||||
|
//offset += 100.0
|
||||||
|
|
||||||
|
//offset = (self.visibleSize.height - insets.bottom) - itemNode.apparentFrame.maxY + getOverflow(itemNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case .visible:
|
case .visible:
|
||||||
|
|||||||
@ -2,9 +2,33 @@ import Foundation
|
|||||||
import UIKit
|
import UIKit
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
|
|
||||||
public enum ListViewCenterScrollPositionOverflow {
|
public enum ListViewCenterScrollPositionOverflow: Equatable {
|
||||||
case top
|
case top
|
||||||
case bottom
|
case bottom
|
||||||
|
case custom((ListViewItemNode) -> CGFloat)
|
||||||
|
|
||||||
|
public static func ==(lhs: ListViewCenterScrollPositionOverflow, rhs: ListViewCenterScrollPositionOverflow) -> Bool {
|
||||||
|
switch lhs {
|
||||||
|
case .top:
|
||||||
|
if case .top = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case .bottom:
|
||||||
|
if case .bottom = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case .custom:
|
||||||
|
if case .custom = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ListViewScrollPosition: Equatable {
|
public enum ListViewScrollPosition: Equatable {
|
||||||
@ -303,7 +327,7 @@ struct ListViewState {
|
|||||||
switch overflow {
|
switch overflow {
|
||||||
case .top:
|
case .top:
|
||||||
offset = self.insets.top - node.frame.minY
|
offset = self.insets.top - node.frame.minY
|
||||||
case .bottom:
|
case .bottom, .custom:
|
||||||
offset = (self.visibleSize.height - self.insets.bottom) - node.frame.maxY
|
offset = (self.visibleSize.height - self.insets.bottom) - node.frame.maxY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4955,6 +4955,17 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func getQuoteRect(quote: String) -> CGRect? {
|
||||||
|
for contentNode in self.contentNodes {
|
||||||
|
if let contentNode = contentNode as? ChatMessageTextBubbleContentNode {
|
||||||
|
if let result = contentNode.getQuoteRect(quote: quote) {
|
||||||
|
return contentNode.view.convert(result, to: self.view)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
public func hasExpandedAudioTranscription() -> Bool {
|
public func hasExpandedAudioTranscription() -> Bool {
|
||||||
for contentNode in self.contentNodes {
|
for contentNode in self.contentNodes {
|
||||||
if let contentNode = contentNode as? ChatMessageFileBubbleContentNode {
|
if let contentNode = contentNode as? ChatMessageFileBubbleContentNode {
|
||||||
|
|||||||
@ -978,6 +978,33 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func getQuoteRect(quote: String) -> CGRect? {
|
||||||
|
var rectsSet: [CGRect] = []
|
||||||
|
if !quote.isEmpty, let cachedLayout = self.textNode.textNode.cachedLayout, let string = cachedLayout.attributedString?.string {
|
||||||
|
let nsString = string as NSString
|
||||||
|
let range = nsString.range(of: quote)
|
||||||
|
if range.location != NSNotFound {
|
||||||
|
if let rects = cachedLayout.rangeRects(in: range)?.rects, !rects.isEmpty {
|
||||||
|
rectsSet = rects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !rectsSet.isEmpty {
|
||||||
|
var currentRect = CGRect()
|
||||||
|
for rect in rectsSet {
|
||||||
|
if currentRect.isEmpty {
|
||||||
|
currentRect = rect
|
||||||
|
} else {
|
||||||
|
currentRect = currentRect.union(rect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentRect.offsetBy(dx: self.textNode.textNode.frame.minX, dy: self.textNode.textNode.frame.minY)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
public func updateQuoteTextHighlightState(text: String?, color: UIColor, animated: Bool) {
|
public func updateQuoteTextHighlightState(text: String?, color: UIColor, animated: Bool) {
|
||||||
var rectsSet: [CGRect] = []
|
var rectsSet: [CGRect] = []
|
||||||
if let text = text, !text.isEmpty, let cachedLayout = self.textNode.textNode.cachedLayout, let string = cachedLayout.attributedString?.string {
|
if let text = text, !text.isEmpty, let cachedLayout = self.textNode.textNode.cachedLayout, let string = cachedLayout.attributedString?.string {
|
||||||
|
|||||||
@ -32,7 +32,6 @@ private func generateTemplateImage(isMonochrome: Bool) -> UIImage {
|
|||||||
return generateImage(CGSize(width: radius * 2.0 + 4.0, height: radius * 2.0 + 8.0), rotatedContext: { size, context in
|
return generateImage(CGSize(width: radius * 2.0 + 4.0, height: radius * 2.0 + 8.0), rotatedContext: { size, context in
|
||||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||||
|
|
||||||
//context.addPath(UIBezierPath(roundedRect: CGRect(origin: CGPoint(), size: size), cornerRadius: radius).cgPath)
|
|
||||||
addRoundedRectPath(context: context, rect: CGRect(origin: CGPoint(), size: size), radius: radius)
|
addRoundedRectPath(context: context, rect: CGRect(origin: CGPoint(), size: size), radius: radius)
|
||||||
context.clip()
|
context.clip()
|
||||||
|
|
||||||
@ -408,7 +407,7 @@ public final class MessageInlineBlockBackgroundView: UIView {
|
|||||||
patternContentLayer.frame = CGRect(origin: CGPoint(x: size.width - placement.position.x / 3.0 - itemSize.width * 0.5, y: placement.position.y / 3.0 - itemSize.height * 0.5), size: itemSize)
|
patternContentLayer.frame = CGRect(origin: CGPoint(x: size.width - placement.position.x / 3.0 - itemSize.width * 0.5, y: placement.position.y / 3.0 - itemSize.height * 0.5), size: itemSize)
|
||||||
var alphaFraction = abs(placement.position.x) / 400.0
|
var alphaFraction = abs(placement.position.x) / 400.0
|
||||||
alphaFraction = min(1.0, max(0.0, alphaFraction))
|
alphaFraction = min(1.0, max(0.0, alphaFraction))
|
||||||
patternContentLayer.opacity = 0.5 * Float(1.0 - alphaFraction)
|
patternContentLayer.opacity = 0.3 * Float(1.0 - alphaFraction)
|
||||||
|
|
||||||
maxIndex += 1
|
maxIndex += 1
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import MergeLists
|
|||||||
import AccountContext
|
import AccountContext
|
||||||
import ChatControllerInteraction
|
import ChatControllerInteraction
|
||||||
import ChatHistoryEntry
|
import ChatHistoryEntry
|
||||||
|
import ChatMessageBubbleItemNode
|
||||||
|
|
||||||
func preparedChatHistoryViewTransition(from fromView: ChatHistoryView?, to toView: ChatHistoryView, reason: ChatHistoryViewTransitionReason, reverse: Bool, chatLocation: ChatLocation, controllerInteraction: ChatControllerInteraction, scrollPosition: ChatHistoryViewScrollPosition?, scrollAnimationCurve: ListViewAnimationCurve?, initialData: InitialMessageHistoryData?, keyboardButtonsMessage: Message?, cachedData: CachedPeerData?, cachedDataMessages: [MessageId: Message]?, readStateData: [PeerId: ChatHistoryCombinedInitialReadStateData]?, flashIndicators: Bool, updatedMessageSelection: Bool, messageTransitionNode: ChatMessageTransitionNodeImpl?, allUpdated: Bool) -> ChatHistoryViewTransition {
|
func preparedChatHistoryViewTransition(from fromView: ChatHistoryView?, to toView: ChatHistoryView, reason: ChatHistoryViewTransitionReason, reverse: Bool, chatLocation: ChatLocation, controllerInteraction: ChatControllerInteraction, scrollPosition: ChatHistoryViewScrollPosition?, scrollAnimationCurve: ListViewAnimationCurve?, initialData: InitialMessageHistoryData?, keyboardButtonsMessage: Message?, cachedData: CachedPeerData?, cachedDataMessages: [MessageId: Message]?, readStateData: [PeerId: ChatHistoryCombinedInitialReadStateData]?, flashIndicators: Bool, updatedMessageSelection: Bool, messageTransitionNode: ChatMessageTransitionNodeImpl?, allUpdated: Bool) -> ChatHistoryViewTransition {
|
||||||
var mergeResult: (deleteIndices: [Int], indicesAndItems: [(Int, ChatHistoryEntry, Int?)], updateIndices: [(Int, ChatHistoryEntry, Int)])
|
var mergeResult: (deleteIndices: [Int], indicesAndItems: [(Int, ChatHistoryEntry, Int?)], updateIndices: [(Int, ChatHistoryEntry, Int)])
|
||||||
@ -195,8 +196,19 @@ func preparedChatHistoryViewTransition(from fromView: ChatHistoryView?, to toVie
|
|||||||
}
|
}
|
||||||
case let .index(scrollSubject, position, directionHint, animated, highlight, displayLink):
|
case let .index(scrollSubject, position, directionHint, animated, highlight, displayLink):
|
||||||
let scrollIndex = scrollSubject
|
let scrollIndex = scrollSubject
|
||||||
|
var position = position
|
||||||
if case .center = position, highlight {
|
if case .center = position, highlight {
|
||||||
scrolledToIndex = scrollSubject
|
scrolledToIndex = scrollSubject
|
||||||
|
if let quote = scrollSubject.quote {
|
||||||
|
position = .center(.custom({ itemNode in
|
||||||
|
if let itemNode = itemNode as? ChatMessageBubbleItemNode {
|
||||||
|
if let quoteRect = itemNode.getQuoteRect(quote: quote) {
|
||||||
|
return quoteRect.midY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0.0
|
||||||
|
}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var index = toView.filteredEntries.count - 1
|
var index = toView.filteredEntries.count - 1
|
||||||
for entry in toView.filteredEntries {
|
for entry in toView.filteredEntries {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user