ارفع راسك فوق انته سوري حر ... :green_heart::green_heart:

Skip to content
Snippets Groups Projects
Commit 6c59d66a authored by Mustafa Merza's avatar Mustafa Merza
Browse files

- Added custom main view, main view model and main coordinator to be reusable.

- Added custom modifier to handle layout changes.
parent 0ac557aa
Branches
No related tags found
1 merge request!1Localization and theme support.
......@@ -194,6 +194,10 @@
672C46DA2C48018400497EF0 /* Color+Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 672C46D92C48018400497EF0 /* Color+Colors.swift */; };
672C46DC2C48018D00497EF0 /* UIColors+Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 672C46DB2C48018D00497EF0 /* UIColors+Colors.swift */; };
67807F8C2C48F49B00D1F168 /* HandleAppLanguageUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67807F8B2C48F49B00D1F168 /* HandleAppLanguageUseCase.swift */; };
67807F952C49306C00D1F168 /* MainCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67807F942C49306C00D1F168 /* MainCoordinator.swift */; };
67807F992C49320100D1F168 /* MainViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67807F982C49320100D1F168 /* MainViewModel.swift */; };
67807F9B2C49325A00D1F168 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67807F9A2C49325A00D1F168 /* MainView.swift */; };
67807FA02C4934BD00D1F168 /* View+LayoutChanges.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67807F9F2C4934BD00D1F168 /* View+LayoutChanges.swift */; };
B827E5196CC419E773B843E1 /* Pods_MiniScanner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E9A37DC9F9A8E3AF632DFB98 /* Pods_MiniScanner.framework */; };
EC0CF1FE254D8BBF00888722 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC0CF1FD254D8BBF00888722 /* AppDelegate.swift */; };
EC0CF200254D8BBF00888722 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC0CF1FF254D8BBF00888722 /* SceneDelegate.swift */; };
......@@ -438,6 +442,10 @@
672C46D92C48018400497EF0 /* Color+Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Colors.swift"; sourceTree = "<group>"; };
672C46DB2C48018D00497EF0 /* UIColors+Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColors+Colors.swift"; sourceTree = "<group>"; };
67807F8B2C48F49B00D1F168 /* HandleAppLanguageUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandleAppLanguageUseCase.swift; sourceTree = "<group>"; };
67807F942C49306C00D1F168 /* MainCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainCoordinator.swift; sourceTree = "<group>"; };
67807F982C49320100D1F168 /* MainViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewModel.swift; sourceTree = "<group>"; };
67807F9A2C49325A00D1F168 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
67807F9F2C4934BD00D1F168 /* View+LayoutChanges.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+LayoutChanges.swift"; sourceTree = "<group>"; };
E8AF4FB39674DF589D719DCF /* Pods-MiniScanner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MiniScanner.release.xcconfig"; path = "Target Support Files/Pods-MiniScanner/Pods-MiniScanner.release.xcconfig"; sourceTree = "<group>"; };
E9A37DC9F9A8E3AF632DFB98 /* Pods_MiniScanner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MiniScanner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
EC0CF1FA254D8BBF00888722 /* MiniScanner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MiniScanner.app; sourceTree = BUILT_PRODUCTS_DIR; };
......@@ -1000,6 +1008,7 @@
672C46A62C47E8D700497EF0 /* DI */,
672C46C42C47E98A00497EF0 /* Data */,
672C46BD2C47E98900497EF0 /* Domain */,
67807F972C49313C00D1F168 /* Presentation */,
);
path = Common;
sourceTree = "<group>";
......@@ -1103,6 +1112,24 @@
path = Style;
sourceTree = "<group>";
};
67807F972C49313C00D1F168 /* Presentation */ = {
isa = PBXGroup;
children = (
67807F9A2C49325A00D1F168 /* MainView.swift */,
67807F982C49320100D1F168 /* MainViewModel.swift */,
67807F942C49306C00D1F168 /* MainCoordinator.swift */,
);
path = Presentation;
sourceTree = "<group>";
};
67807F9C2C49348B00D1F168 /* View */ = {
isa = PBXGroup;
children = (
67807F9F2C4934BD00D1F168 /* View+LayoutChanges.swift */,
);
path = View;
sourceTree = "<group>";
};
98E49D3F46C8E62718825860 /* Pods */ = {
isa = PBXGroup;
children = (
......@@ -1193,6 +1220,7 @@
EC8A9B0A254DC2FD00F9AF99 /* Extensions */ = {
isa = PBXGroup;
children = (
67807F9C2C49348B00D1F168 /* View */,
672C46D82C48017C00497EF0 /* Style */,
672C46492C47BD8800497EF0 /* String+StringKeys.swift */,
EC0CF21C254D8F3900888722 /* String+Extensions.swift */,
......@@ -1496,6 +1524,7 @@
539996952C27130000671340 /* ConstraintConstantTarget.swift in Sources */,
672C46622C47C74300497EF0 /* DependencyInjector.swift in Sources */,
539996902C27130000671340 /* UILayoutSupport+Extensions.swift in Sources */,
67807F952C49306C00D1F168 /* MainCoordinator.swift in Sources */,
53014F992C11A8E80071CE39 /* CGPoint+Utils.swift in Sources */,
53E7D3392C1B00880025A1D3 /* FSPageViewLayout.swift in Sources */,
53BEB1422C2967E0005A3567 /* FoldersViewController.swift in Sources */,
......@@ -1521,6 +1550,7 @@
EC702546254E1E9E00BE1958 /* WalkthroughModel.swift in Sources */,
53D9D1C22C1AF521004D1C1C /* StickerView.swift in Sources */,
672C46D52C47F8D000497EF0 /* HandleAppStartUseCase.swift in Sources */,
67807FA02C4934BD00D1F168 /* View+LayoutChanges.swift in Sources */,
539996A22C27130000671340 /* ConstraintDirectionalInsets.swift in Sources */,
53E7D3352C1B00880025A1D3 /* FSPagerView.swift in Sources */,
672C46B32C47E8D700497EF0 /* DependencyManager.swift in Sources */,
......@@ -1571,6 +1601,7 @@
53014F9E2C11A8E80071CE39 /* UIImage+Orientation.swift in Sources */,
53014FB82C11A8E80071CE39 /* Transformable.swift in Sources */,
53014FA22C11A8E80071CE39 /* ScannedPageViewController.swift in Sources */,
67807F9B2C49325A00D1F168 /* MainView.swift in Sources */,
5399969D2C27130000671340 /* Constraint.swift in Sources */,
EC8A9B1D254DCEC600F9AF99 /* File.swift in Sources */,
67807F8C2C48F49B00D1F168 /* HandleAppLanguageUseCase.swift in Sources */,
......@@ -1580,6 +1611,7 @@
53014FBB2C11A8E80071CE39 /* CaptureSession+Orientation.swift in Sources */,
53014F942C11A8E80071CE39 /* DeviceOrientationHelper.swift in Sources */,
EC8A9B27254DE91B00F9AF99 /* DocumentPreviewViewController.swift in Sources */,
67807F992C49320100D1F168 /* MainViewModel.swift in Sources */,
5399964A2C26E86700671340 /* CropperConstantValues.m in Sources */,
53014F9F2C11A8E80071CE39 /* UIImage+Utils.swift in Sources */,
53CD5F582C1504CF0010424B /* UIButton+Extensions.swift in Sources */,
......
//
// View+LayoutChanges.swift
// MiniScanner
//
// Created by Mustafa Merza on 7/18/24.
// Copyright © 2024 AppsNectar. All rights reserved.
//
import SwiftUI
struct LayoutChangesModifier: ViewModifier {
@State var layoutDirection: LayoutDirection = .leftToRight
@Inject var getLanguageUseCase: GetLanguageUseCase
func body(content: Content) -> some View {
content
.onAppear {
updateLayoutDirection()
}
.environment(\.layoutDirection, layoutDirection)
}
private func updateLayoutDirection() {
let language = getLanguageUseCase.execute()
layoutDirection = language.layoutDirection
}
}
extension View {
func handleLayoutChanges() -> some View {
ModifiedContent(content: self,
modifier: LayoutChangesModifier())
}
}
......@@ -33,6 +33,10 @@ enum SupportedLanguage: CaseIterable {
var isRTL: Bool {
LanguageManager.shared.isRightToLeft
}
var layoutDirection: LayoutDirection {
isRTL ? .rightToLeft : .leftToRight
}
}
extension SupportedLanguage {
......
//
// MainCoordinator.swift
// MiniScanner
//
// Created by Mustafa Merza on 7/18/24.
// Copyright © 2024 AppsNectar. All rights reserved.
//
import SwiftUI
protocol MainCoordinator {
var navigationController: UINavigationController { get set }
func start()
func coordinate(to coordinator: MainCoordinator)
func coordinateBack()
func coordinateToView(_ view: some View, title: String?)
}
extension MainCoordinator {
func coordinate(to coordinator: MainCoordinator) {
coordinator.start()
}
func coordinateBack() {
navigationController.popViewController(animated: true)
}
func coordinateToView(_ view: some View, title: String? = nil) {
let hostingController = UIHostingController(rootView: view)
hostingController.title = title
navigationController.pushViewController(hostingController, animated: true)
}
}
//
// MainView.swift
// MiniScanner
//
// Created by Mustafa Merza on 7/18/24.
// Copyright © 2024 AppsNectar. All rights reserved.
//
import SwiftUI
struct MainView<ViewModel: MainViewModel, Content: View>: View {
var viewModel: ViewModel
@ViewBuilder var content: () -> Content
init(viewModel: ViewModel,
@ViewBuilder content: @escaping () -> Content) {
self.viewModel = viewModel
self.content = content
}
var body: some View {
content()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.onAppear {
viewModel.onAppear()
}
.onDisappear() { viewModel.onDisappear() }
.handleLayoutChanges()
}
}
//
// MainViewModel.swift
// MiniScanner
//
// Created by Mustafa Merza on 7/18/24.
// Copyright © 2024 AppsNectar. All rights reserved.
//
import Foundation
protocol MainViewModel: ObservableObject {
func onAppear()
func onDisappear()
}
extension MainViewModel {
func onDisappear() { }
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment