Skip to content

Commit 65082bf

Browse files
author
mac
committed
新增scroll to row
1 parent ee194f8 commit 65082bf

File tree

4 files changed

+74
-20
lines changed

4 files changed

+74
-20
lines changed

Sources/SwiftUIX/Intramodular/List/CocoaList-Initializers.swift

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,42 @@ extension CocoaList {
1212
_ data: Data,
1313
sectionHeader: @escaping (SectionType) -> SectionHeader,
1414
sectionFooter: @escaping (SectionType) -> SectionFooter,
15-
rowContent: @escaping (_Item) -> RowContent
15+
rowContent: @escaping (_Item) -> RowContent,
16+
scrollPosition: Binding<ListScrollPosition> = Binding.constant(ListScrollPosition())
1617
) where ItemType == _HashIdentifiableValue<_Item> {
1718
self.data = data
1819
self.sectionHeader = sectionHeader
1920
self.sectionFooter = sectionFooter
2021
self.rowContent = { rowContent($0.value) }
22+
self.scrollPosition = scrollPosition
2123
}
2224

2325
public init<_SectionType: Hashable, _Item: Hashable>(
2426
_ data: Data,
2527
sectionHeader: @escaping (_SectionType) -> SectionHeader,
2628
sectionFooter: @escaping (_SectionType) -> SectionFooter,
27-
rowContent: @escaping (_Item) -> RowContent
29+
rowContent: @escaping (_Item) -> RowContent,
30+
scrollPosition: Binding<ListScrollPosition> = Binding.constant(ListScrollPosition())
2831
) where SectionType == _HashIdentifiableValue<_SectionType>, ItemType == _HashIdentifiableValue<_Item> {
2932
self.data = data
3033
self.sectionHeader = { sectionHeader($0.value) }
3134
self.sectionFooter = { sectionFooter($0.value) }
3235
self.rowContent = { rowContent($0.value) }
36+
self.scrollPosition = scrollPosition
3337
}
3438

3539
public init<_SectionType: Hashable, _Item: Hashable>(
3640
_ data: [ListSection<_SectionType, _Item>],
3741
sectionHeader: @escaping (_SectionType) -> SectionHeader,
3842
sectionFooter: @escaping (_SectionType) -> SectionFooter,
39-
rowContent: @escaping (_Item) -> RowContent
43+
rowContent: @escaping (_Item) -> RowContent,
44+
scrollPosition: Binding<ListScrollPosition> = Binding.constant(ListScrollPosition())
4045
) where Data == Array<ListSection<SectionType, ItemType>>, SectionType == _HashIdentifiableValue<_SectionType>, ItemType == _HashIdentifiableValue<_Item> {
4146
self.data = data.map({ .init(model: .init($0.model), items: $0.items.map(_HashIdentifiableValue.init)) })
4247
self.sectionHeader = { sectionHeader($0.value) }
4348
self.sectionFooter = { sectionFooter($0.value) }
4449
self.rowContent = { rowContent($0.value) }
50+
self.scrollPosition = scrollPosition
4551
}
4652
}
4753

@@ -53,21 +59,24 @@ extension CocoaList where SectionType == _KeyPathHashIdentifiableValue<Int, Int>
5359
>(
5460
_ items: Items,
5561
id: KeyPath<_ItemType, _ItemID>,
56-
@ViewBuilder rowContent: @escaping (_ItemType) -> RowContent
62+
@ViewBuilder rowContent: @escaping (_ItemType) -> RowContent,
63+
scrollPosition: Binding<ListScrollPosition> = Binding.constant(ListScrollPosition())
5764
) where Data == AnyRandomAccessCollection<ListSection<SectionType, ItemType>>, Items.Element == _ItemType, ItemType == _KeyPathHashIdentifiableValue<_ItemType, _ItemID> {
5865
self.init(
5966
AnyRandomAccessCollection([ListSection(_KeyPathHashIdentifiableValue(value: 0, keyPath: \.self), items: items.elements(identifiedBy: id))]),
6067
sectionHeader: Never._SwiftUIX_produce,
6168
sectionFooter: Never._SwiftUIX_produce,
62-
rowContent: { rowContent($0.value) }
69+
rowContent: { rowContent($0.value) },
70+
scrollPosition: scrollPosition
6371
)
6472
}
6573
}
6674

6775
extension CocoaList where Data: RangeReplaceableCollection, SectionType == _KeyPathHashIdentifiableValue<Int, Int>, SectionHeader == Never, SectionFooter == Never {
6876
public init<Items: RandomAccessCollection>(
6977
_ items: Items,
70-
@ViewBuilder rowContent: @escaping (ItemType) -> RowContent
78+
@ViewBuilder rowContent: @escaping (ItemType) -> RowContent,
79+
scrollPosition: Binding<ListScrollPosition> = Binding.constant(ListScrollPosition())
7180
) where Items.Element == ItemType {
7281
var data = Data()
7382

@@ -77,12 +86,14 @@ extension CocoaList where Data: RangeReplaceableCollection, SectionType == _KeyP
7786
data,
7887
sectionHeader: Never._SwiftUIX_produce,
7988
sectionFooter: Never._SwiftUIX_produce,
80-
rowContent: rowContent
89+
rowContent: rowContent,
90+
scrollPosition: scrollPosition
8191
)
8292
}
8393

8494
public init<Items: RandomAccessCollection>(
85-
@ViewBuilder content: @escaping () -> ForEach<Items, ItemType.ID, RowContent>
95+
@ViewBuilder content: @escaping () -> ForEach<Items, ItemType.ID, RowContent>,
96+
scrollPosition: Binding<ListScrollPosition> = Binding.constant(ListScrollPosition())
8697
) where Items.Element == ItemType, Data == Array<ListSection<SectionType, ItemType>> {
8798
var data = Data()
8899

@@ -94,7 +105,8 @@ extension CocoaList where Data: RangeReplaceableCollection, SectionType == _KeyP
94105
data,
95106
sectionHeader: Never._SwiftUIX_produce,
96107
sectionFooter: Never._SwiftUIX_produce,
97-
rowContent: content.content
108+
rowContent: content.content,
109+
scrollPosition: scrollPosition
98110
)
99111
}
100112
}
@@ -103,13 +115,15 @@ extension CocoaList where Data == Array<ListSection<SectionType, ItemType>>, Sec
103115
{
104116
public init<Items: RandomAccessCollection>(
105117
_ items: Items,
106-
@ViewBuilder rowContent: @escaping (ItemType) -> RowContent
118+
@ViewBuilder rowContent: @escaping (ItemType) -> RowContent,
119+
scrollPosition: Binding<ListScrollPosition> = Binding.constant(ListScrollPosition())
107120
) where Items.Element == ItemType {
108121
self.init(
109122
[.init(_KeyPathHashIdentifiableValue(value: 0, keyPath: \.self), items: items)],
110123
sectionHeader: Never._SwiftUIX_produce,
111124
sectionFooter: Never._SwiftUIX_produce,
112-
rowContent: rowContent
125+
rowContent: rowContent,
126+
scrollPosition: scrollPosition
113127
)
114128
}
115129
}

Sources/SwiftUIX/Intramodular/List/CocoaList-UIKit.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,21 @@ public struct CocoaList<
4141
var scrollViewConfiguration: CocoaScrollViewConfiguration<AnyView> = nil
4242
@usableFromInline
4343
var _cocoaListPreferences: _CocoaListPreferences = nil
44+
45+
public var scrollPosition: Binding<ListScrollPosition>
4446

4547
public init(
4648
_ data: Data,
4749
sectionHeader: @escaping (SectionType) -> SectionHeader,
4850
sectionFooter: @escaping (SectionType) -> SectionFooter,
49-
rowContent: @escaping (ItemType) -> RowContent
51+
rowContent: @escaping (ItemType) -> RowContent,
52+
scrollPosition: Binding<ListScrollPosition> = Binding.constant(ListScrollPosition())
5053
) {
5154
self.data = data
5255
self.sectionHeader = sectionHeader
5356
self.sectionFooter = sectionFooter
5457
self.rowContent = rowContent
58+
self.scrollPosition = scrollPosition
5559
}
5660

5761
public func makeUIViewController(
@@ -88,6 +92,14 @@ public struct CocoaList<
8892
#endif
8993

9094
uiViewController.reloadData()
95+
if scrollPosition.wrappedValue.activate {
96+
uiViewController.scroll(scrollPosition: scrollPosition.wrappedValue)
97+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
98+
var scrollPosition = scrollPosition.wrappedValue
99+
scrollPosition.activate = false
100+
self.scrollPosition.wrappedValue = scrollPosition
101+
})
102+
}
91103
}
92104
}
93105

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//
2+
// ListScrollPosition.swift
3+
// SwiftUIX
4+
//
5+
// Created by mac on 2025/4/25.
6+
//
7+
8+
import UIKit
9+
10+
public struct ListScrollPosition {
11+
var indexPath: IndexPath
12+
var anchor: UITableView.ScrollPosition
13+
var animated: Bool
14+
15+
var activate: Bool
16+
17+
public init(indexPath: IndexPath = IndexPath(row: 0, section: 0), anchor: UITableView.ScrollPosition = .none, animated: Bool = false, activate: Bool = false) {
18+
self.indexPath = indexPath
19+
self.anchor = anchor
20+
self.animated = animated
21+
self.activate = activate
22+
}
23+
}
24+

Sources/SwiftUIX/Intramodular/List/_PlatformTableViewController.swift

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,13 @@ public class _PlatformTableViewController<SectionModel: Identifiable, ItemType:
201201

202202
prototypeSectionHeader.update()
203203

204-
let height = prototypeSectionHeader
204+
var height = max(1, prototypeSectionHeader
205205
.contentHostingController
206206
.sizeThatFits(in: CGSize(width: tableView.bounds.width, height: UIView.layoutFittingExpandedSize.height))
207-
.height
207+
.height)
208208

209209
_sectionHeaderContentHeightCache[model.id] = height
210-
211-
return max(1, height)
210+
return height
212211
}
213212

214213
override public func tableView(
@@ -255,14 +254,13 @@ public class _PlatformTableViewController<SectionModel: Identifiable, ItemType:
255254

256255
prototypeSectionFooter.update()
257256

258-
let height = prototypeSectionFooter
257+
var height = max(1, prototypeSectionFooter
259258
.contentHostingController
260259
.sizeThatFits(in: CGSize(width: tableView.bounds.width, height: UIView.layoutFittingExpandedSize.height))
261-
.height
262-
260+
.height)
263261
_sectionFooterContentHeightCache[model.id] = height
264262

265-
return max(1, height)
263+
return height
266264
}
267265

268266
override public func tableView(
@@ -436,6 +434,12 @@ extension _PlatformTableViewController {
436434

437435
tableView.endUpdates()
438436
}
437+
438+
public func scroll(scrollPosition: ListScrollPosition) {
439+
//tableView.beginUpdates()
440+
tableView.scrollToRow(at: scrollPosition.indexPath, at: scrollPosition.anchor, animated: scrollPosition.animated)
441+
//tableView.endUpdates()
442+
}
439443
}
440444

441445
extension _PlatformTableViewController {

0 commit comments

Comments
 (0)