Skip to content

v0.2.2: addSubview fires multiple times #199

@kingbri1

Description

@kingbri1

Hi there, I recently updated to Introspect v0.2.2 and had an issue when using addSubview that I've never seen before. Basically, when I switch back and forth between views that use addSubview in an introspect call (example: TabView tabs), multiple subviews are overlaid on top of each other causing application lag and weird UI bugs.

I included my sample code below to showcase this problem. I basically add a custom scope bar with a segmented picker to the underlying UISearchController of searchable. To reproduce this bug:

  1. Launch an app on iOS 15+ (because of Searchable)
  2. Switch back and forth between the Home and Search tabs
  3. Observe the picker getting progressively whiter or darker depending on the system theme
  4. Try using the picker buttons after switching between tabs, you'll see lag

I reverted back to v0.2.1 and this issue did not occur. Am I supposed to change something in my code for v0.2.2 compatability or is this a mistake in the library?

struct MainView: View {
    enum ViewTab {
        case home
        case search
    }

    @State private var selectedTab: ViewTab = .home

    var body: some View {
        TabView(selection: $selectedTab) {
            InternalView()
                .tabItem {
                    Label("Home", systemImage: "house")
                }
                .tag(ViewTab.home)
            InternalView()
                .tabItem {
                    Label("Search", systemImage: "magnifyingglass")
                }
                .tag(ViewTab.search)
        }
    }
}

struct InternalView: View {
    @State private var searchText = ""

    var body: some View {
        NavigationView {
            List {
                ForEach(1..<100) { num in
                    Text(String(num))
                }
            }
            .searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always))
            .navigationBarTitle("Search", displayMode: .large)
            .introspectSearchController { searchController in
                searchController.hidesNavigationBarDuringPresentation = true
                searchController.searchBar.showsScopeBar = true
                searchController.searchBar.scopeButtonTitles = [""]

                (searchController.searchBar.value(forKey: "_scopeBar") as? UIView)?.isHidden = true

                let hostingController = UIHostingController(rootView: FilterView())
                hostingController.view.translatesAutoresizingMaskIntoConstraints = false
                hostingController.view.backgroundColor = .clear

                guard let containerView = searchController.searchBar.value(forKey: "_scopeBarContainerView") as? UIView else {
                    return
                }
                searchController.navigationItem.hidesSearchBarWhenScrolling = false
                containerView.addSubview(hostingController.view)

                NSLayoutConstraint.activate([
                    hostingController.view.widthAnchor.constraint(equalTo: containerView.widthAnchor),
                    hostingController.view.topAnchor.constraint(equalTo: containerView.topAnchor),
                    hostingController.view.heightAnchor.constraint(equalTo: containerView.heightAnchor)
                ])
            }
            .introspectNavigationController { navigationController in
                navigationController.navigationBar.prefersLargeTitles = true
                navigationController.navigationBar.sizeToFit()
            }
        }
    }
}

struct FilterView: View {
    @State private var textName = "first"
    @State private var secondTextName = "First"
    var body: some View {
        Picker("", selection: $textName) {
            Text("First").tag("first")
            Text("Second").tag("second")
        }
        .pickerStyle(.segmented)
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions