mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-05 19:28:46 +02:00
InstantPage V2 table: flush frame, inset borders
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e8de87dc7b
commit
79bcc7bc34
3 changed files with 39 additions and 16 deletions
|
|
@ -1942,15 +1942,20 @@ final class InstantPageV2TableView: UIView, InstantPageItemView {
|
|||
self.backgroundColor = .clear
|
||||
|
||||
self.scrollView.frame = self.bounds
|
||||
self.scrollView.contentSize = item.contentSize
|
||||
// Scrollable tables clip to the full width with no inset on the clip; the inset lives inside
|
||||
// the scroll content width as a left margin only (see contentSize below).
|
||||
self.scrollView.clipsToBounds = true
|
||||
self.scrollView.contentSize = CGSize(width: item.contentSize.width + item.contentInset, height: item.contentSize.height)
|
||||
self.scrollView.alwaysBounceHorizontal = false
|
||||
self.scrollView.alwaysBounceVertical = false
|
||||
self.scrollView.showsHorizontalScrollIndicator = item.contentSize.width > item.frame.width
|
||||
self.scrollView.showsHorizontalScrollIndicator = item.contentSize.width + item.contentInset > item.frame.width
|
||||
self.scrollView.showsVerticalScrollIndicator = false
|
||||
self.scrollView.disablesInteractiveTransitionGestureRecognizer = true
|
||||
self.addSubview(self.scrollView)
|
||||
|
||||
self.contentView.frame = CGRect(origin: .zero, size: item.contentSize)
|
||||
// Grid container shifted right by the inset so the borders start at the body-text inset.
|
||||
// Its size stays the bare grid (item.contentSize); grid coords inside remain x=0-relative.
|
||||
self.contentView.frame = CGRect(x: item.contentInset, y: 0.0, width: item.contentSize.width, height: item.contentSize.height)
|
||||
self.scrollView.addSubview(self.contentView)
|
||||
|
||||
// Title sub-layout (above the grid, inside the scroll view's content).
|
||||
|
|
@ -2025,9 +2030,9 @@ final class InstantPageV2TableView: UIView, InstantPageItemView {
|
|||
self.item = item
|
||||
|
||||
self.scrollView.frame = CGRect(origin: .zero, size: item.frame.size)
|
||||
self.scrollView.contentSize = item.contentSize
|
||||
self.scrollView.showsHorizontalScrollIndicator = item.contentSize.width > item.frame.width
|
||||
self.contentView.frame = CGRect(origin: .zero, size: item.contentSize)
|
||||
self.scrollView.contentSize = CGSize(width: item.contentSize.width + item.contentInset, height: item.contentSize.height)
|
||||
self.scrollView.showsHorizontalScrollIndicator = item.contentSize.width + item.contentInset > item.frame.width
|
||||
self.contentView.frame = CGRect(x: item.contentInset, y: 0.0, width: item.contentSize.width, height: item.contentSize.height)
|
||||
|
||||
// Forward updates to nested V2 sub-layouts (title + each cell). Recursive update
|
||||
// propagation. Cell-count or title-presence changes fall back to rebuild via the
|
||||
|
|
@ -2145,7 +2150,7 @@ private func findTextItem(
|
|||
}
|
||||
case let .table(table):
|
||||
for cell in table.cells {
|
||||
let cellAbs = cell.frame.offsetBy(dx: f.minX, dy: f.minY)
|
||||
let cellAbs = cell.frame.offsetBy(dx: f.minX + table.contentInset, dy: f.minY)
|
||||
if !cellAbs.contains(point) { continue }
|
||||
if let sub = cell.subLayout {
|
||||
if let hit = findTextItem(in: sub, point: point,
|
||||
|
|
@ -2155,7 +2160,7 @@ private func findTextItem(
|
|||
}
|
||||
}
|
||||
if let titleLayout = table.titleSubLayout, let titleFrame = table.titleFrame {
|
||||
let titleAbs = titleFrame.offsetBy(dx: f.minX, dy: f.minY)
|
||||
let titleAbs = titleFrame.offsetBy(dx: f.minX + table.contentInset, dy: f.minY)
|
||||
if titleAbs.contains(point) {
|
||||
if let hit = findTextItem(in: titleLayout, point: point,
|
||||
accumulatedOffset: CGPoint(x: titleAbs.minX, y: titleAbs.minY)) {
|
||||
|
|
@ -2208,7 +2213,7 @@ private func collectSelectableTextItems(
|
|||
case let .table(table):
|
||||
if let titleLayout = table.titleSubLayout, let titleFrame = table.titleFrame {
|
||||
let titleOffset = CGPoint(
|
||||
x: accumulatedOffset.x + table.frame.minX + titleFrame.minX,
|
||||
x: accumulatedOffset.x + table.frame.minX + table.contentInset + titleFrame.minX,
|
||||
y: accumulatedOffset.y + table.frame.minY + titleFrame.minY
|
||||
)
|
||||
collectSelectableTextItems(in: titleLayout, accumulatedOffset: titleOffset, into: &result)
|
||||
|
|
@ -2216,7 +2221,7 @@ private func collectSelectableTextItems(
|
|||
for cell in table.cells {
|
||||
if let sub = cell.subLayout {
|
||||
let cellOffset = CGPoint(
|
||||
x: accumulatedOffset.x + table.frame.minX + cell.frame.minX,
|
||||
x: accumulatedOffset.x + table.frame.minX + table.contentInset + cell.frame.minX,
|
||||
y: accumulatedOffset.y + table.frame.minY + cell.frame.minY
|
||||
)
|
||||
collectSelectableTextItems(in: sub, accumulatedOffset: cellOffset, into: &result)
|
||||
|
|
|
|||
|
|
@ -320,6 +320,7 @@ public struct InstantPageV2TableItem {
|
|||
public let titleSubLayout: InstantPageV2Layout?
|
||||
public let titleFrame: CGRect?
|
||||
public let contentSize: CGSize // grid intrinsic size; may exceed frame.width → scroll
|
||||
public let contentInset: CGFloat // left inset (= page horizontalInset) baked into the scroll content width by the renderer
|
||||
public let cells: [InstantPageV2TableCell]
|
||||
public let horizontalLines: [CGRect]
|
||||
public let verticalLines: [CGRect]
|
||||
|
|
@ -1067,8 +1068,12 @@ private func layoutTable(
|
|||
setupStyleStack(styleStack, theme: context.theme, category: .paragraph, link: false)
|
||||
|
||||
let borderWidth = bordered ? v2TableBorderWidth : 0.0
|
||||
// Size columns against the inset content width (mirrors V1's `boundingWidth - horizontalInset*2`),
|
||||
// so a fitting table aligns with body text on both sides. The item frame stays full-width (flush)
|
||||
// and the renderer bakes the inset back in as a left margin on the scroll content.
|
||||
let contentBoundingWidth = boundingWidth - horizontalInset * 2.0
|
||||
let totalCellPadding = v2TableCellInsets.left + v2TableCellInsets.right
|
||||
let cellWidthLimit = boundingWidth - totalCellPadding
|
||||
let cellWidthLimit = contentBoundingWidth - totalCellPadding
|
||||
|
||||
var tableRows: [V2TableRow] = []
|
||||
var columnCount: Int = 0
|
||||
|
|
@ -1153,7 +1158,7 @@ private func layoutTable(
|
|||
}
|
||||
|
||||
// Aggregate column min/max across all rows.
|
||||
let maxContentWidth = boundingWidth - borderWidth
|
||||
let maxContentWidth = contentBoundingWidth - borderWidth
|
||||
var availableWidth = maxContentWidth
|
||||
var minColumnWidths: [Int: CGFloat] = [:]
|
||||
var maxColumnWidths: [Int: CGFloat] = [:]
|
||||
|
|
@ -1224,7 +1229,7 @@ private func layoutTable(
|
|||
distributedWidth -= growth
|
||||
finalColumnWidths[i] = width
|
||||
}
|
||||
totalWidth = boundingWidth
|
||||
totalWidth = contentBoundingWidth
|
||||
} else {
|
||||
totalWidth += borderWidth
|
||||
}
|
||||
|
|
@ -1530,10 +1535,11 @@ private func layoutTable(
|
|||
titleFrame = CGRect(x: 0.0, y: 0.0, width: totalWidth, height: titleHeight)
|
||||
}
|
||||
|
||||
// The table item frame spans the full boundingWidth slot in the bubble;
|
||||
// contentSize.width is the intrinsic grid width (may exceed frame.width → horizontal scroll).
|
||||
// The table item frame spans the full visible bubble interior (`boundingWidth`); the scroll
|
||||
// viewport equals what is actually visible. contentSize.width is the intrinsic grid width
|
||||
// (may exceed frame.width → horizontal scroll); the renderer adds the left inset on top.
|
||||
let tableFrame = CGRect(x: 0.0, y: 0.0,
|
||||
width: boundingWidth + horizontalInset * 2.0,
|
||||
width: boundingWidth,
|
||||
height: totalHeight + (titleFrame?.height ?? 0.0))
|
||||
let contentSize = CGSize(
|
||||
width: totalWidth,
|
||||
|
|
@ -1545,6 +1551,7 @@ private func layoutTable(
|
|||
titleSubLayout: titleSubLayout,
|
||||
titleFrame: titleFrame,
|
||||
contentSize: contentSize,
|
||||
contentInset: horizontalInset,
|
||||
cells: finalizedCells,
|
||||
horizontalLines: horizontalLines,
|
||||
verticalLines: verticalLines,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue