Change view based on device - SwiftUI
Asked Answered
D

3

5

I have designed my app initially for the iPad and am now wanting to add functionality for an iPhone too. Is there a way to check what the device being used is, and then display a view accordingly?

Structured English:

IF current_device == iPhone THEN
    DISPLAY iPhoneView
ELSE IF current_device == iPad THEN
    DISPLAY iPadView

If possible I also want the iPad view to only be available horizontally and then the iPhone view to only be available vertically if possible.

Danika answered 20/1, 2021 at 13:16 Comment(3)
I would recommend doing this based on the frame width (I usually use 500 as the limit before switching to the bigger views). Keep in mind that apps on the iPad can be resized, and can be as thin as the iPhone's screen.Meddlesome
This would be good, however I want to rearrange the entire view, and have different items in different places, it will work far betterDanika
hi! did you manage to solve your problem?Lazarolazaruk
L
13

What you are looking for are Size Classes.

To read current horizontal size class in SwiftUI view you can refer to the environment value of horizontalSizeClass

@Environment(\.horizontalSizeClass) var horizontalSizeClass

Then use it like this in your SwiftUI View:

var body: some View {
    if horizontalSizeClass == .compact {
        return CompactView() // view laid out for smaller screens, like an iPhone
    } else {
        return RegularView() // view laid out for wide screens, like an iPad
    }
}

It is worth noting that not all iPhones are compact horizontally, and compact size class is present on iPad while in multitasking configuration. You will find all possible combinations here under the Device Size Classes and Multitasking Size Classes sections.

Some articles that may be helpful

Lazarolazaruk answered 20/1, 2021 at 13:28 Comment(0)
C
1

Alternatively you could set an individual threshold based on the devices height (or width) using a variable like this:

@State var isLargeDevice: Bool = {
    if UIScreen.main.bounds.height > 800 {
        return true
    } else {
        return false
    }
}()
Cantankerous answered 20/1, 2021 at 16:6 Comment(0)
F
0

I like the answer of @Malburrito, but needed to incorporate Macs.

#if os(iOS)
import UIKit
#endif

var isLargeDevice: Bool {
#if os(macOS)
    return true
#else
    if UIScreen.main.bounds.width > 1200 {
        return true
    } else {
        return false
    }
#endif
}

and use it like this:

struct MainView: View {
    var body: some View {
        if isLargeDevice {
            RegularMainView() // uses NavigationSplitView
        } else {
            CompactMainView() // uses NavigationStack
        }
    }
}

I might need to add more to differentiate when in portrait or landscape mode, but will cross that bridge when I get there.

Fregoso answered 10/2, 2024 at 9:59 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.