Jayachandra A
Jayachandra A

Reputation: 1342

SwiftUI View Alignment Issue on Device Orientation Change and App Background to Foreground Transition

I'm encountering an issue with SwiftUI view alignment when the device orientation changes or when the app transitions from the background to the foreground. Despite my efforts, the views(Tabbar) seem to be misaligned, causing a poor user experience.

Below is a simplified version of the code I'm using to display the UI:

@main
struct SSWIFTUIApp: App {
    var body: some Scene {
        WindowGroup {
            TabbarViewApp()
        }
    }
}

struct TabbarViewApp: View {
    
    init() {
        let app = UITabBarAppearance()
        app.configureWithOpaqueBackground()
        app.backgroundColor = UIColor.systemPink
        app.selectionIndicatorTintColor = .black

        UITabBar.appearance().standardAppearance = app
        if #available(iOS 15.0, *) {
            UITabBar.appearance().scrollEdgeAppearance = app
        }
    }
    
    @State private var selected: Int = 1
    
    @State private var id: String = ""
    
    var body: some View {
        TabView(selection: $selected,
                content:  {
            NavigationView(content: {
                VStack(alignment: .center, spacing: 0, content: {
                    TextField("Connection ID", text: $id)
                        .padding(.horizontal, 5)
                        .frame(height: 40)
                        .border(Color.black, width: 1)
                        .padding()
                })
            })
            .navigationViewStyle(.stack)
            .tabItem {
                Label("Home", systemImage: "house")
                    .foregroundColor(selected == 1 ? Color.accentColor : Color.white)
            }
            .tag(1)
            
            NavigationView(content: {
                
            })
            .navigationViewStyle(.stack)
            .tabItem {
                Label("Settings", systemImage: "gear")
                    .foregroundColor(selected == 2 ? Color.accentColor : Color.white)
            }
            .tag(2)
        })
    }
}

Issues demoed below with the above code enter image description here

Upon device orientation change or transitioning the app from the background to the foreground, the alignment of the views seems to be off. I've tried adjusting padding, using GeometryReader, and even incorporating specific layout guides, but the issue persists.

I would greatly appreciate any insights or solutions on how to ensure proper alignment of SwiftUI views under these circumstances. Thank you in advance for your assistance! 

Upvotes: 3

Views: 329

Answers (1)

Eugene Zaychenko
Eugene Zaychenko

Reputation: 319

it seems like an iOS SwiftUI bug, but I managed to avoid tabbar jumping, but TextField still jumps. Could you please check:

struct TabbarViewApp: View {

init() {
    let app = UITabBarAppearance()
    app.configureWithOpaqueBackground()
    app.backgroundColor = UIColor.systemPink
    app.selectionIndicatorTintColor = .black

    UITabBar.appearance().standardAppearance = app
    if #available(iOS 15.0, *) {
        UITabBar.appearance().scrollEdgeAppearance = app
    }
}

@State private var selected: Int = 1
@State private var id: String = ""

// Added a state for device orientation
//
@State private var orientation = UIDevice.current.orientation

var body: some View {
    TabView(selection: $selected,
            content:  {
        NavigationView(content: {
            VStack(alignment: .center, spacing: 0, content: {
                TextField("Connection ID", text: $id)
                    .padding(.horizontal, 5)
                    .frame(height: 40)
                    .border(Color.black, width: 1)
                    .padding()
            })
            .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
                orientation = UIDevice.current.orientation // set current orientation
            }
            .animation(.easeInOut(duration: 0), value: orientation) // observe current orientation change and avoid animation
        })
        .navigationViewStyle(.stack)
        .tabItem {
            Label("Home", systemImage: "house")
                .foregroundColor(selected == 1 ? Color.accentColor : Color.white)
        }
        .tag(1)
        
        NavigationView(content: {
            
        })
        .navigationViewStyle(.stack)
        .tabItem {
            Label("Settings", systemImage: "gear")
                .foregroundColor(selected == 2 ? Color.accentColor : Color.white)
        }
        .tag(2)
    })
  }
}

Upvotes: 0

Related Questions