Category: swiftui

  • SwiftUI combine rectangle and triangle in shape

    SwiftUI combine rectangle and triangle in shape

    SwiftUI combine rectangle and triangle in shape

    Making custom shape is not hard in SwiftUI by implementing func path(in rect: CGRect) -> Path. You just have to draw points in your desired location in 2D coordinate space by path.move() and path.addLine() func, a line will be drawn automatically.

    struct MomentumArrow: Shape {
        
        func path(in rect: CGRect) -> Path {
            var path = Path()
            
            let squareHeight = rect.height * 0.65
            
            // Rect
            path.move(to: CGPoint(x: 0, y: 0))
            path.addLine(to: CGPoint(x: 0, y: squareHeight))
            path.addLine(to: CGPoint(x: rect.width, y: squareHeight))
            path.addLine(to: CGPoint(x: rect.width, y: 0))
            path.addLine(to: CGPoint(x: 0, y: 0))
            
            // Triangle
            path.move(to: CGPoint(x: 0, y: squareHeight))
            path.addLine(to: CGPoint(x: rect.midX, y: rect.height))
            path.addLine(to: CGPoint(x: rect.width, y: squareHeight))
        
            return path
        }
        
    }
    Spread the love
  • Navigation in SwiftUI with multiple views

    Navigation in SwiftUI with multiple views

    Download Complete Login app with Laravel API

    I was trying to build a simple app in iOS + SwiftUI with multiple views that uses NavigationView and NavigationLink.

    This app is very simple and uses a model to navigate between destinations. Enum ViewType tracks all the destinations. If you want to have another view, View4, just add a new case in ViewType enum.

    struct Menu: Identifiable {
        var id = UUID()
        var name: String
        var image: String
        var destination: ViewType
    }
    
    enum ViewType {
        case home
        case view1
        case view2
    }

    Our all views must have a property with menu type

    struct HomeView: View {
        var menu: Menu
        
        var body: some View {
            Text("Home View")
        }
    }

    Our MasterView which is the main view in root ContentView. Also, we added HomeView as our default view here.

    var body: some View {
            NavigationView {
                MasterView()
                    .navigationBarTitle(
                        Text("Navigation Demo")
                    )
                HomeView(menu: Menu(name:"Home",      image:"image",  destination:    .home))
            }.navigationViewStyle(DefaultNavigationViewStyle())
      }

    In our MasterView we have an array of Menu with title and destination view case, which populated in a list view.

    let  view1 =  Menu(name:"Home",      image:"image",  destination:    .home)
    let  view2 =  Menu(name:"View 1",          image:"image",  destination:    .view1)
    let  view3 =  Menu(name:"View 3",       image:"image",  destination:    .view2)
    
    var body: some View {
            let menus: [Menu] = [view1, view2, view3]
    
            return List {
                ForEach(menus) { menu in
                    self.destinationView(menu: menu)
                }
            }
    }

    function destinationView return a NavigationLink based on what item you choose on the list and take the user to the expected view.

    func destinationView(menu: Menu) -> some View {
            
            switch menu.destination {
                case .view1:
                    return NavigationLink(
                        destination: AnyView(View1(menu: menu))
                    )
                    {
                        Text("\(menu.name)")
                    }
                case .view2:
                       return NavigationLink(
                           destination: AnyView(View2(menu: menu))
                       )
                       {
                           Text("\(menu.name)")
                       }
                default:
                   return NavigationLink(
                       destination: AnyView(HomeView(menu: menu))
                   )
                   {
                       Text("\(menu.name)")
                   }
            }
            
        }

    Download the source code

    Spread the love
  • SwiftUI Know When Entering Landscape Mode

    SwiftUI Know When Entering Landscape Mode

    Create a ObservableObject Object like this

    final class UserAndDeviceSettings: ObservableObject {
        @Published var userInterfaceOrientationChanges:Bool = false
        @Published var userInterfaceOrientationLandscape:Bool = false
    }

    Now go to your SceneDelegate and add a var on top and pass your settings var in UIHostingController in willConnectTo method.

    var settings = UserAndDeviceSettings()
    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
            // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
            // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    
            // Get the managed object context from the shared persistent container
            let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    
            // Create the SwiftUI view and set the context as the value for the managedObjectContext environment keyPath
            let contentView = ContentView().environment(\.managedObjectContext, context)
    
            // Use a UIHostingController as window root view controller.
            if let windowScene = scene as? UIWindowScene {
                let window = UIWindow(windowScene: windowScene)
                
                // read the initial device orientation here
                self.settings.userInterfaceOrientationLandscape = (windowScene.interfaceOrientation.isLandscape == true)
                
                window.rootViewController = UIHostingController(rootView: contentView.environmentObject(self.settings))
                self.window = window
                window.makeKeyAndVisible()
            }
        }

    and in didUpdate delegate method, add this code.

    
    func windowScene(_ windowScene: UIWindowScene, didUpdate previousCoordinateSpace: UICoordinateSpace, interfaceOrientation previousInterfaceOrientation: UIInterfaceOrientation, traitCollection previousTraitCollection: UITraitCollection) {
            print(">> previous tratis  \(previousTraitCollection)")
            print(">> previous coordinateSpace \(previousCoordinateSpace)")
            print(">> previous orientation \(previousInterfaceOrientation)")
            
            self.settings.userInterfaceOrientationChanges = true
            
            if previousInterfaceOrientation == .portrait || previousInterfaceOrientation == .portraitUpsideDown {
                self.settings.userInterfaceOrientationLandscape = true
            } else {
                self.settings.userInterfaceOrientationLandscape = false
            }
        }

    Now you can use this @EnvironmentObject in any View

    @EnvironmentObject var settings:UserAndDeviceSettings
    
    if self.settings.userInterfaceOrientationLandscape {
        
    }
    Spread the love