Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

499 Inconsistent padding #596

Merged
merged 9 commits into from
Dec 10, 2024
5 changes: 3 additions & 2 deletions FRW/Modules/Wallet/MoveAsset/MoveComponentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ struct MoveFeeView: View {
var body: some View {
VStack(alignment: .leading, spacing: 4) {
HStack {
Text("Move Fee")
Text("move_fee".localized)
.font(.inter(size: 12, weight: .bold))
.foregroundStyle(Color.Theme.Text.black8)
Spacer()
Expand All @@ -127,9 +127,10 @@ struct MoveFeeView: View {
}
.frame(height: 16)
Text(feeHint())
.lineLimit(nil)
.fixedSize(horizontal: false, vertical: true)
Comment on lines +130 to +131
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This enables the text to be displayed in multiple lines, if needed, otherwise it stays on a single line and wrapped if necessary.

.font(.inter(size: 12, weight: .bold))
.foregroundStyle(Color.Theme.Text.black6)
.frame(height: 16)
}
}

Expand Down
89 changes: 44 additions & 45 deletions FRW/Modules/Wallet/MoveAsset/MoveTokenView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ struct MoveTokenView: RouteableView, PresentActionDelegate {
// MARK: Internal

var changeHeight: (() -> Void)?
@StateObject
var viewModel: MoveTokenViewModel
@StateObject private var viewModel: MoveTokenViewModel
@State private var primaryButtonSize: CGSize = .zero

var title: String {
""
Expand All @@ -36,52 +36,51 @@ struct MoveTokenView: RouteableView, PresentActionDelegate {
}

var body: some View {
GeometryReader { _ in
VStack {
ScrollView(showsIndicators: false) {
VStack(spacing: 0) {
HStack {
Text("move_single_token".localized)
.font(.inter(size: 18, weight: .w700))
.foregroundStyle(Color.LL.Neutrals.text)
.padding(.top, 6)
Spacer()

Button {
viewModel.closeAction()
} label: {
Image("icon_close_circle_gray")
.resizable()
.frame(width: 24, height: 24)
}
}
.padding(.top, 8)

Color.clear
.frame(height: 20)

VStack(spacing: 8) {
ContactRelationView(
fromContact: viewModel.fromContact,
toContact: viewModel.toContact
)
VStack {
VStack(spacing: 0) {
HStack {
Text("move_single_token".localized)
.font(.inter(size: 18, weight: .w700))
.foregroundStyle(Color.LL.Neutrals.text)
.padding(.top, 6)
Spacer()

MoveTokenView.AccountView(isFree: viewModel.fromContact.walletType == viewModel.toContact.walletType) { _ in }
.padding(.bottom, 36)
}
.padding(.bottom, 20)
Button {
viewModel.closeAction()
} label: {
Image("icon_close_circle_gray")
.resizable()
.frame(width: 24, height: 24)
}
.padding(18)
}
.padding(.bottom, 36)
Spacer()
.padding(.top, 8)

Color.clear
.frame(height: 20)

VStack(spacing: 8) {
ContactRelationView(
fromContact: viewModel.fromContact,
toContact: viewModel.toContact
)

MoveTokenView
.AccountView(
isFree: viewModel.fromContact.walletType == viewModel
.toContact.walletType
) { _ in
}
}
.padding(.bottom, self.primaryButtonSize.height)
}
.hideKeyboardWhenTappedAround()
.backgroundFill(Color.Theme.BG.bg1)
.cornerRadius([.topLeading, .topTrailing], 16)
.environmentObject(viewModel)
.edgesIgnoringSafeArea(.bottom)
.overlay(alignment: .bottom) {
.padding(18)
}
.hideKeyboardWhenTappedAround()
.backgroundFill(Color.Theme.BG.bg1)
.cornerRadius([.topLeading, .topTrailing], 16)
.environmentObject(viewModel)
.edgesIgnoringSafeArea(.bottom)
.overlay(alignment: .bottom) {
VStack(spacing: 0) {
InsufficientStorageToastView<MoveTokenViewModel>()
.environmentObject(self.viewModel)
Expand All @@ -96,8 +95,8 @@ struct MoveTokenView: RouteableView, PresentActionDelegate {
}, title: "move".localized)
.padding(.horizontal, 18)
.padding(.bottom, 8)
.sizeGetter($primaryButtonSize)
}
}
}
.applyRouteable(self)
}
Expand Down
2 changes: 1 addition & 1 deletion FRW/Modules/Wallet/TokenDetail/TokenDetailView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ struct TokenDetailView: RouteableView {
.buttonStyle(.plain)
.backgroundFill(.LL.deepBg)
.applyRouteable(self)
.halfSheet(showSheet: $vm.showSheet) {
.halfSheet(showSheet: $vm.showSheet, autoResizing: true) {
if vm.buttonAction == .move {
MoveTokenView(tokenModel: vm.token, isPresent: $vm.showSheet)
}
Expand Down
1 change: 1 addition & 0 deletions FRW/Resource/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,7 @@ Please create backups for your wallet to ensure you retain access to your Flow a
"create_phrase_backup_note" = "Create a 12 word recovery phrase";
"Recommended" = "Recommended";

"move_fee" = "Move Fee";
"move_fee_hint_cost" = "It appears when moving between VM accounts";
"move_fee_hint_free" = "No fee between your Flow accounts 🤟";
"move_fee_cost" = "~ 0.001";
Expand Down
77 changes: 61 additions & 16 deletions FRW/UI/Component/HalfSheetModal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct SheetHeaderView: View {
// MARK: Internal

let title: String
var closeAction: (() -> Void)? = nil
var closeAction: (() -> Void)?

var body: some View {
VStack(spacing: 0) {
Expand Down Expand Up @@ -65,13 +65,14 @@ extension View {
// Binding Show Variable...
func halfSheet<SheetView: View>(
showSheet: Binding<Bool>,
autoResizing: Bool = false,
@ViewBuilder sheetView: @escaping () -> SheetView,
onEnd: (() -> Void)? = nil
) -> some View {
// why we using overlay or background...
// bcz it will automatically use the swiftui frame Size only....
background(
HalfSheetHelper(sheetView: sheetView(), showSheet: showSheet)
HalfSheetHelper(sheetView: sheetView(), autoResizing: autoResizing, showSheet: showSheet)
)
.onChange(of: showSheet.wrappedValue) { newValue in
if let onEnd = onEnd, !newValue {
Expand All @@ -86,7 +87,7 @@ extension View {
// UIKit Integration...
struct HalfSheetHelper<SheetView: View>: UIViewControllerRepresentable {
// On Dismiss...
class Coordinator: NSObject, UISheetPresentationControllerDelegate {
final class Coordinator: NSObject, UISheetPresentationControllerDelegate {
// MARK: Lifecycle

init(parent: HalfSheetHelper) {
Expand All @@ -103,8 +104,9 @@ struct HalfSheetHelper<SheetView: View>: UIViewControllerRepresentable {
}

var sheetView: SheetView
@Binding
var showSheet: Bool
let autoResizing: Bool
@Binding var showSheet: Bool
@State private var sheetSize: CGSize = .zero

let controller = UIViewController()

Expand All @@ -121,7 +123,18 @@ struct HalfSheetHelper<SheetView: View>: UIViewControllerRepresentable {
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
if showSheet {
if uiViewController.view.tag == 0 {
let sheetController = CustomHostingController(rootView: sheetView)
let rootView = sheetView
.readSize { size in
self.sheetSize = size
}

let sheetController = CustomHostingController(
rootView: rootView,
sheetSize: self.autoResizing ? _sheetSize.projectedValue : nil
)
if #available(iOS 16.4, *), self.autoResizing {
sheetController.safeAreaRegions = []
}
sheetController.presentationController?.delegate = context.coordinator
uiViewController.present(sheetController, animated: true)
uiViewController.view.tag = 1
Expand All @@ -139,19 +152,23 @@ struct HalfSheetHelper<SheetView: View>: UIViewControllerRepresentable {
// MARK: - CustomHostingController

// Custom UIHostingController for halfSheet....
class CustomHostingController<Content: View>: UIHostingController<Content> {
final class CustomHostingController<Content: View>: UIHostingController<Content> {
private let sheetSize: Binding<CGSize>?

// MARK: Lifecycle

public init(
rootView: Content,
sheetSize: Binding<CGSize>? = nil,
showLarge: Bool = false,
showGrabber: Bool = true,
onlyLarge: Bool = false
) {
super.init(rootView: rootView)
self.sheetSize = sheetSize
self.showLarge = showLarge
self.showGrabber = showGrabber
self.onlyLarge = onlyLarge
super.init(rootView: rootView)
overrideUserInterfaceStyle = ThemeManager.shared.getUIKitStyle()
}

Expand All @@ -162,24 +179,52 @@ class CustomHostingController<Content: View>: UIHostingController<Content> {
}

// MARK: Internal

var showLarge: Bool = false
var showGrabber: Bool = true
var onlyLarge: Bool = false
private var autoResizing: Bool { return self.sheetSize != nil }
private let showLarge: Bool
private let showGrabber: Bool
private let onlyLarge: Bool
private let customDetentId = UISheetPresentationController.Detent.Identifier(rawValue: "custom-detent")
private var customDetent: UISheetPresentationController.Detent {
if #available(iOS 16, *), let sheetSize {
return UISheetPresentationController.Detent.custom(identifier: self.customDetentId) { _ in
print("[SHEET SIZE] \(sheetSize.height.wrappedValue)")
return sheetSize.height.wrappedValue
}
} else {
return UISheetPresentationController.Detent.medium()
}
}

override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .clear

// setting presentation controller properties...
if let presentationController = presentationController as? UISheetPresentationController {
if let sheetPresentationController {
if onlyLarge {
presentationController.detents = [.large()]
sheetPresentationController.detents = [.large()]
} else {
presentationController.detents = showLarge ? [.medium(), .large()] : [.medium()]
sheetPresentationController.detents = showLarge ? [customDetent, .large()] : [customDetent]
}
// to show grab protion...
presentationController.prefersGrabberVisible = true
sheetPresentationController.prefersGrabberVisible = self.showLarge || self.onlyLarge

if self.autoResizing {
sheetPresentationController.prefersScrollingExpandsWhenScrolledToEdge = false
}

}
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

if #available(iOS 16, *) {
if let sheetPresentationController {
sheetPresentationController.animateChanges {
sheetPresentationController.invalidateDetents()
}
}
}
}
}