Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a view is displayed on the screen? (Swift 5 and SwiftUI)

I have a view like below. I want to find out if it is the view which is displayed on the screen. Is there a function to achieve this?

struct TestView: View {
    var body: some View {
        Text("Test View")
    }
}
like image 924
codezero11 Avatar asked Mar 09 '20 06:03

codezero11


People also ask

How do I show and hide a view in SwiftUI?

Use an opacity(_:) modifier with a value of 0 so that the layout accounts for the error message whether or not it's visible. You can also use this strategy for removing a view that doesn't affect other views' placement, like a view inside an overlay(alignment:content:) modifier.

How do I disappear a view in SwiftUI?

If you need to reserve space in a layout based on the measurement of a view, but never want to show that view, you can use the hidden() modifier.

What is some view in SwiftUI?

So, in SwiftUI case, “some View” means that the body will always be implementing the View protocol, but the concrete implementation type does not need to be known by the caller. As explained in Swift documentation on Opaque Types: You can think of an opaque type like being the reverse of a generic type.


2 Answers

You could use onAppear on any kind of view that conforms to View protocol.

struct TestView: View {
    @State var isViewDisplayed = false
    var body: some View {
        Text("Test View")
        .onAppear {
            self.isViewDisplayed = true
        }
        .onDisappear {
            self.isViewDisplayed = false
        }
    }

    func someFunction() {
        if isViewDisplayed {
            print("View is displayed.")
        } else {
            print("View is not displayed.")
        }
    }
}

PS: Although this solution covers most cases, it has many edge cases that has not been covered. I'll be updating this answer when Apple releases a better solution for this requirement.

like image 146
Frankenstein Avatar answered Oct 17 '22 05:10

Frankenstein


You can check the position of view in global scope using GeometryReader and GeometryProxy.

        struct CustomButton: View {
            var body: some View {
                GeometryReader { geometry in
                    VStack {
                        Button(action: {
                        }) {
                            Text("Custom Button")
                                .font(.body)
                                .fontWeight(.bold)
                                .foregroundColor(Color.white)
                        }
                        .background(Color.blue)
                    }.navigationBarItems(trailing: self.isButtonHidden(geometry) ?
                            HStack {
                                Button(action: {
                                }) {
                                    Text("Custom Button")
                                } : nil)
                }
            }

            private func isButtonHidden(_ geometry: GeometryProxy) -> Bool {
    // Alternatively, you can also check for geometry.frame(in:.global).origin.y if you know the button height.
                if geometry.frame(in: .global).maxY <= 0 {
                    return true
                }
                return false
            }
like image 12
Seshu Vadlapudi Avatar answered Oct 17 '22 03:10

Seshu Vadlapudi