Научете как да компютърирате отмествания в реално време в SwiftUI ScrollView
SwiftUI, новият декларативен начин за създаване на потребителски интерфейси, е наистина невероятна рамка. Много неща могат да се направят за нула време с пълни предварителни прегледи на живо, но понякога репликирането на нещо доста обичайно в UIKit може да се превърне в болка във врата. Отместванията на ScrollView са едно от тези неща!
В UIKit всеки UIScrollView
има свойство, което ни позволява лесно да четем отместването на самия изглед:
var contentOffset: CGPoint { get set }
Той връща структура със стойностите x
и y
. Супер лесно, супер удобно!
SwiftUI, за съжаление, днес липсва това просто свойство. Така че трябва да измислим начин да получим тази стойност по някакъв начин.
В края на този урок ще можете да създадете нещо подобно на това:
Рамката SwiftUI често ни позволява (или принуждава) да мислим нестандартно, за да решаваме проблеми, и това е един чудесен повод да го направим.
Нека първо започнем с изграждането на много прост потребителски интерфейс с дълъг списък и етикет Text
, който няма да може да покаже реалната стойност на отместването (разбира се, ще добавим тази функция по-късно), както можете да видите, че verticalOffset
var никога не се променя:
За да постигнем резултата от видеото по-горе, ще кодираме View
, който ще се държи точно като SwiftUI ScrollView
, но излъчва по някакъв начин стойността в реално време на своето отместване.
Първо, трябва да създадем нова структура, която ще отговаря на протокола PreferenceKey
.
Официалната документация на Apple ни дава дефиницията на този протокол, както следва:
Именувана стойност, произведена от изглед.
Изглед с множество деца автоматично комбинира своите стойности за дадено предпочитание в една стойност, видима за неговите предци.
Това е сложен начин да кажем, че позволяваме на изглед да говори с изгледите, които го съдържат и да предава стойности.
За да съответства на този протокол, трябва да бъдат внедрени свойство и функция, и двете статични:
static var defaultValue: Self.Value { get } static func reduce(value: inout Self.Value, nextValue: () -> Self.Value)
Стойността по подразбиране ще бъде нашето отместване, CGPoint
, с начална стойност 0,0
.
Нека създадем структурата OffsetPreferenceKey
точно така:
Браво, сега е време да създадем нашата версия на scrollView
.
Нека създадем структура със същите свойства на SwiftUI ScrollView
, но с допълнително нещо, onOffsetChanged
затваряне, което да се активира, когато scrollview
промени позицията си:
Както можете да видите, използвах общо променливо съдържание, за да предам цялото съдържание на ScrollView
. Както е посочено в дефиницията на структурата T
ще бъде от тип View
.
Нека сега да разгледаме имплементацията на свойството body
:
- На ред 2 създадох
ScrollView
- На ред 3
GeometryReader
, който съдържа празен изглед,Color.Clear
без размери. Трябва да проследим позицията на изглед и е умна идея да използваме безразмерен. Вътре в него съм задал ключаOffsetPreferenceKey
, предаващ като стойност произхода на самия кадър. ИзползвахcoordinateSpace(name:)
, за да позволя на друга функция да намира и оперира с нашия изгледColor
и да работи с измерения спрямо този изглед. - Предавам началната позиция на външния свят, стартирайки затварянето, когато тази стойност се промени, на ред 15.
- На ред 12 използвам предадения инициализатор
content
.
Това е цялата структура:
Това е готово! Имаме нашия чисто нов OffsettableScrollView
, който ще може да предава стойността на своето отместване по всяко време, когато се промени!
Сега е време да променим нашия оригинален изглед на съдържание с най-накрая свързан Text
:
Свърши! Както можете да видите, сега е супер лесно и супер чисто!
Надявам се тази статия да ви е харесала. Ако се интересувате от видео версията, това ръководство е и в моя YouTube канал:
Приятно кодиране!