#swift #swiftui #scrollview
Вопрос:
В iOS 14 вы можете использовать ScrollViewReader для автоматической прокрутки представления вверх или вниз по мере изменения содержимого в представлении прокрутки.
Я нахожусь в ситуации, когда мне нужно поддерживать iOS 13. Есть ли способ, даже банальный способ, программно прокручивать представление прокрутки в iOS 13?
Для этого я пишу следующий код, он работает с вертикальной прокруткой, но мне нужна горизонтальная прокрутка, и ему нужно переместить выбранный индекс.
struct ListScrollingHelper: UIViewRepresentable {
let proxy: ListScrollingProxy // reference type
func makeUIView(context: Context) -> UIView {
return UIView() // managed by SwiftUI, no overloads
}
func updateUIView(_ uiView: UIView, context: Context) {
proxy.catchScrollView(for: uiView) // here UIView is in view hierarchy
}
}
class ListScrollingProxy {
enum Action {
case end
case top
case point(point: CGPoint) // << bonus !!
}
private var scrollView: UIScrollView?
func catchScrollView(for view: UIView) {
if nil == scrollView {
scrollView = view.enclosingScrollView()
}
}
func scrollTo(_ action: Action) {
if let scroller = scrollView {
var rect = CGRect(origin: .zero, size: CGSize(width: 1, height: 1))
switch action {
case .end:
rect.origin.y = scroller.contentSize.height
scroller.contentInset.bottom scroller.contentInset.top - 1
case .point(let point):
rect.origin.y = point.y
default: {
// default goes to top
}()
}
scroller.scrollRectToVisible(rect, animated: true)
}
}
}
extension UIView {
func enclosingScrollView() -> UIScrollView? {
var next: UIView? = self
repeat {
next = next?.superview
if let scrollview = next as? UIScrollView {
return scrollview
}
} while next != nil
return nil
}
}
я использую свой код следующим образом:
struct ContentView: View {
private let scrollingProxy = ListScrollingProxy() // proxy helper
var body: some View {
VStack {
HStack {
Button(action: { self.scrollingProxy.scrollTo(.top) }) { // < here
Image(systemName: "arrow.up.to.line")
.padding(.horizontal)
}
Button(action: { self.scrollingProxy.scrollTo(.end) }) { // << here
Image(systemName: "arrow.down.to.line")
.padding(.horizontal)
}
}
Divider()
List {
ForEach(0 ..< 200) { i in
Text("Item (i)")
.background(
ListScrollingHelper(proxy: self.scrollingProxy) // injection
)
}
}
}
}
}
Ответ №1:
Используйте следующий подход:
import SwiftUI
struct ContentView: View {
var body: some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 10) {
ForEach(1..<11) {
Text("ITEM ($0)")
.frame(width: 70, height: 70)
}
}
}
}
}
Прокрутка всей таблицы выглядит так:
struct ContentView: View {
var body: some View {
List {
ScrollView(.horizontal, showsIndicators: false) {
Text("First List Item in a first cell")
Text("Second List Item in a second cell")
Text("Third List Item in a third cell")
}
}
}
}
Вы можете комбинировать обе методологии.
Комментарии:
1. Здесь мы можем использовать свойство прокрутки вида прокрутки