英文:
Track view visibility by percentage in SwiftUI
问题
我正在尝试获取ExampleView的可见百分比。我尝试了下面的方法,你可以在代码中看到。更精确地说,当ExampleView变得可见时,它将开始计算该视图的可见百分之多少。
struct ContentView: View {
var body: some View {
NavigationView {
List {
ForEach(1..<20) { index in
if index % 5 == 0 {
VStack {
ExampleView()
.onPreferenceChange(BoundsPreferenceKey.self) { value in
print(value as Any)
}
}
.frame(minHeight: 500)
} else {
Rectangle()
.fill(.blue)
.frame(minHeight: 300)
}
}
}
}
}
}
struct BoundsPreferenceKey: PreferenceKey {
typealias Value = Anchor<CGRect>?
static var defaultValue: Value = nil
static func reduce(
value: inout Value,
nextValue: () -> Value
) {
value = nextValue()
}
}
struct ExampleView: View {
var body: some View {
ZStack {
Color.yellow
Text("Hello World !!!")
.anchorPreference(
key: BoundsPreferenceKey.self,
value: .bounds
) { $0 }
}
.overlayPreferenceValue(BoundsPreferenceKey.self) { preferences in
GeometryReader { geometry in
preferences.map {
Rectangle()
.stroke()
.frame(
width: geometry[$0].width,
height: geometry[$0].height
)
.offset(
x: geometry[$0].minX,
y: geometry[$0].minY
)
}
}
}
}
}
在overlayPreferenceValue(offset)每次调用时,ExampleView的框架发生更改。然而,我不知道如何获得这些百分比。如果您有其他建议,请告诉我。
请帮助我获取可见百分比。如果您需要更多信息,请告诉我。
提前感谢。
英文:
I am trying to get visibility percentage of the ExampleView. I tried below things which you can see in code. To more precise word when ExampleView become visible it's going start counting how many percent of that view is visible.
struct ContentView: View {
var body: some View {
NavigationView {
List {
ForEach(1..<20) { index in
if index%5 == 0 {
VStack {
ExampleView()
.onPreferenceChange(BoundsPreferenceKey.self) { value in
print(value as Any)
}
}
.frame(minHeight: 500)
}else {
Rectangle()
.fill(.blue)
.frame(minHeight: 300)
}
}
}
}
}
}
struct BoundsPreferenceKey: PreferenceKey {
typealias Value = Anchor<CGRect>?
static var defaultValue: Value = nil
static func reduce(
value: inout Value,
nextValue: () -> Value
) {
value = nextValue()
}
}
struct ExampleView: View {
var body: some View {
ZStack {
Color.yellow
Text("Hello World !!!")
.anchorPreference(
key: BoundsPreferenceKey.self,
value: .bounds
) { $0 }
}
.overlayPreferenceValue(BoundsPreferenceKey.self) { preferences in
GeometryReader { geometry in
preferences.map {
Rectangle()
.stroke()
.frame(
width: geometry[$0].width,
height: geometry[$0].height
)
.offset(
x: geometry[$0].minX,
y: geometry[$0].minY
)
}
}
}
}
}
On overlayPreferenceValue(offset) calling every time when its frame of ExampleView is changing. However I don't how get those percentage. If you any other suggestion please let me know.
Please help me to get visibility percentage. Please let me know if you need more information about it.
Thanks in advance.
答案1
得分: 1
这里我找到了我的答案。如果您有更好的解决方案或建议,请在评论中提出或进行编辑。
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Rectangle()
.fill(.green)
.frame(minHeight: 300)
List {
ForEach(1..<20) { index in
if index % 5 == 0 {
VStack {
CustomView()
}
.frame(minHeight: 300)
} else {
Rectangle()
.fill(.blue)
.frame(minHeight: 300)
}
}
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct CustomView: View {
var body: some View {
Image("Monitor")
.resizable()
.background(Color.red)
.aspectRatio(contentMode: .fill)
.overlay(
GeometryReader { geo in
Color.clear
.onAppear() {
self.getPercentage(geo: geo, heightOfAdView: 300)
}
.onChange(of: geo.frame(in: .global)) { _ in
self.getPercentage(geo: geo, heightOfAdView: 300)
}
}
)
}
func getPercentage(geo: GeometryProxy, heightOfAdView: CGFloat) {
let screenHeight = UIScreen.main.bounds.height
let yAxisOfAdView = geo.frame(in: .global).origin.y
let visiblityInPx = screenHeight - yAxisOfAdView
let visiblePCT = (visiblityInPx * 100.0) / heightOfAdView
print("screenHeight:- \(screenHeight)")
print("yAxisOfAdView:- \(yAxisOfAdView)")
print("visiblityInPx:- \(visiblityInPx)")
visiblePCT <= 100 ? print("visiblePCT:- \(visiblePCT)") : print("visiblePCT:- 100")
}
}
如果您需要进一步的帮助,请告诉我。
英文:
Here I found my answer. If you have any better solution or suggestion, Please comment on it or edit it.
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Rectangle()
.fill(.green)
.frame(minHeight: 300)
List {
ForEach(1..<20) { index in
if index%5 == 0 {
VStack {
CustomView()
}
.frame(minHeight: 300)
}else {
Rectangle()
.fill(.blue)
.frame(minHeight: 300)
}
}
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct CustomView: View {
var body: some View {
Image("Monitor")
.resizable()
.background(Color.red)
.aspectRatio(contentMode: .fill)
.overlay(
GeometryReader { geo in
Color.clear
.onAppear() {
self.getPercentage(geo: geo, heightOfAdView: 300)
}
.onChange(of: geo.frame(in: .global)) { _ in
self.getPercentage(geo: geo, heightOfAdView: 300)
}
}
)
}
func getPercentage(geo: GeometryProxy,heightOfAdView: CGFloat) {
let screenHeight = UIScreen.main.bounds.height
let yAxisOfAdView = geo.frame(in: .global).origin.y
let visiblityInPx = screenHeight - yAxisOfAdView
let visiblePCT = (visiblityInPx * 100.0)/heightOfAdView
print("screenHeight:- \(screenHeight)")
print("yAxisOfAdView:- \(yAxisOfAdView)")
print("visiblityInPx:- \(visiblityInPx)")
visiblePCT <= 100 ? print("visiblePCT:- \(visiblePCT)") : print("visiblePCT:- 100")
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论