From 7575450121c4280efd802490fbe8b5fd57646336 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Tue, 15 Feb 2022 22:16:01 -0800 Subject: [PATCH 01/13] use scroll view delegate to watch scroll changes and update nav bar visibility --- .../Sources/Views/Article/WebAppView.swift | 3 + .../Views/Article/WebAppViewCoordinator.swift | 44 ++++++++++++- .../Views/Article/WebAppWrapperView.swift | 5 +- .../LinkedItemDetail/LinkItemDetailView.swift | 64 ++++++++++++++++++- 4 files changed, 111 insertions(+), 5 deletions(-) diff --git a/apple/OmnivoreKit/Sources/Views/Article/WebAppView.swift b/apple/OmnivoreKit/Sources/Views/Article/WebAppView.swift index dbe50286e..6d7286f2c 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/WebAppView.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/WebAppView.swift @@ -10,6 +10,7 @@ import WebKit let rawAuthCookie: String? let openLinkAction: (URL) -> Void let webViewActionHandler: (WKScriptMessage) -> Void + let navBarVisibilityRatioUpdater: (Double) -> Void @Binding var annotation: String @Binding var annotationSaveTransactionID: UUID? @Binding var sendIncreaseFontSignal: Bool @@ -33,6 +34,7 @@ import WebKit webView.isOpaque = false webView.backgroundColor = UIColor.clear webView.configuration.userContentController = contentController + webView.scrollView.delegate = context.coordinator for action in WebViewAction.allCases { webView.configuration.userContentController.add(context.coordinator, name: action.rawValue) @@ -53,6 +55,7 @@ import WebKit context.coordinator.linkHandler = openLinkAction context.coordinator.webViewActionHandler = webViewActionHandler + context.coordinator.updateNavBarVisibilityRatio = navBarVisibilityRatioUpdater return webView } diff --git a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift index 28609f510..c8f9837bd 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift @@ -1,6 +1,4 @@ -// import Models import SwiftUI -// import Utils import WebKit final class WebAppViewCoordinator: NSObject { @@ -8,6 +6,10 @@ final class WebAppViewCoordinator: NSObject { var linkHandler: (URL) -> Void = { _ in } var needsReload = true var lastSavedAnnotationID: UUID? + var updateNavBarVisibilityRatio: (Double) -> Void = { _ in } + private var yOffsetAtStartOfDrag: Double? + private var lastYOffset: Double = 0 + private var hasDragged = false override init() { super.init() @@ -34,6 +36,44 @@ extension WebAppViewCoordinator: WKNavigationDelegate { } } +extension WebAppViewCoordinator: UIScrollViewDelegate { + func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { + hasDragged = true + yOffsetAtStartOfDrag = scrollView.contentOffset.y + } + + func scrollViewDidScroll(_ scrollView: UIScrollView) { + guard hasDragged else { return } + + let yOffset = scrollView.contentOffset.y + + if yOffset <= 0 { + updateNavBarVisibilityRatio(1) + return + } + + if yOffset < 30 { + updateNavBarVisibilityRatio(1) // yOffset / 30) + return + } + + guard let yOffsetAtStartOfDrag = yOffsetAtStartOfDrag else { return } + + if yOffset > yOffsetAtStartOfDrag { + let translation = yOffset - yOffsetAtStartOfDrag + let ratio = 0.0 // translation < 30 ? translation / 30 : 0 + updateNavBarVisibilityRatio(ratio) + } + } + + func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { + if decelerate, scrollView.contentOffset.y < (yOffsetAtStartOfDrag ?? 0) { + updateNavBarVisibilityRatio(1) + } + yOffsetAtStartOfDrag = nil + } +} + struct WebViewConfig { let url: URL let themeId: String diff --git a/apple/OmnivoreKit/Sources/Views/Article/WebAppWrapperView.swift b/apple/OmnivoreKit/Sources/Views/Article/WebAppWrapperView.swift index f8bae2f3f..f87b67573 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/WebAppWrapperView.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/WebAppWrapperView.swift @@ -35,9 +35,11 @@ public struct WebAppWrapperView: View { @State private var annotation = String() @State var annotationSaveTransactionID: UUID? @State var safariWebLink: SafariWebLink? + let navBarVisibilityRatioUpdater: (Double) -> Void - public init(viewModel: WebAppWrapperViewModel) { + public init(viewModel: WebAppWrapperViewModel, navBarVisibilityRatioUpdater: ((Double) -> Void)? = nil) { self.viewModel = viewModel + self.navBarVisibilityRatioUpdater = navBarVisibilityRatioUpdater ?? { _ in } } public var body: some View { @@ -53,6 +55,7 @@ public struct WebAppWrapperView: View { #endif }, webViewActionHandler: webViewActionHandler, + navBarVisibilityRatioUpdater: navBarVisibilityRatioUpdater, annotation: $annotation, annotationSaveTransactionID: $annotationSaveTransactionID, sendIncreaseFontSignal: $viewModel.sendIncreaseFontSignal, diff --git a/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift b/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift index 0af2bd8e2..bb26f31f6 100644 --- a/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift +++ b/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift @@ -25,8 +25,11 @@ public final class LinkItemDetailViewModel: ObservableObject { } public struct LinkItemDetailView: View { + @Environment(\.presentationMode) var presentationMode: Binding + @ObservedObject private var viewModel: LinkItemDetailViewModel @State private var showFontSizePopover = false + @State private var navBarVisibilityRatio = 1.0 public init(viewModel: LinkItemDetailViewModel) { self.viewModel = viewModel @@ -51,12 +54,69 @@ public struct LinkItemDetailView: View { } public var body: some View { - innerBody #if os(iOS) - .navigationBarTitleDisplayMode(.inline) + if UIDevice.isIPhone, !viewModel.item.isPDF { + compactInnerBody + } else { + innerBody + } + #else + innerBody #endif } + @ViewBuilder private var compactInnerBody: some View { + VStack { + withAnimation { + HStack(alignment: .center) { + Button( + action: { self.presentationMode.wrappedValue.dismiss() }, + label: { + Image(systemName: "chevron.backward") + .font(.appTitleThree) + .foregroundColor(.appGrayTextContrast) + .padding(.horizontal) + .padding(.bottom, 5) + } + ) + Spacer() + Button( + action: { showFontSizePopover = true }, + label: { + Image(systemName: "textformat.size") + } + ) + .padding(.horizontal) + #if os(iOS) + .fittedPopover(isPresented: $showFontSizePopover) { + FontSizeAdjustmentPopoverView( + increaseFontAction: { viewModel.webAppWrapperViewModel?.sendIncreaseFontSignal = true }, + decreaseFontAction: { viewModel.webAppWrapperViewModel?.sendDecreaseFontSignal = true } + ) + } + #endif + } + .scaleEffect(x: 1, y: navBarVisibilityRatio) + .frame(height: 30 * navBarVisibilityRatio) + } + if let webAppWrapperViewModel = viewModel.webAppWrapperViewModel { + WebAppWrapperView( + viewModel: webAppWrapperViewModel, + navBarVisibilityRatioUpdater: { + print($0) + navBarVisibilityRatio = $0 + } + ) + } else { + Spacer() + .onAppear { + viewModel.performActionSubject.send(.load) + } + } + } + .navigationBarHidden(true) + } + @ViewBuilder private var innerBody: some View { if let pdfURL = viewModel.item.pdfURL { #if os(iOS) From ed6740c158d1fb57acd2e6a32993d18d6cbf2dd3 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Wed, 16 Feb 2022 08:32:04 -0800 Subject: [PATCH 02/13] tune the scrolling behavior of nav bar --- .../Sources/Views/Article/WebAppViewCoordinator.swift | 11 ++++++++--- .../Views/LinkedItemDetail/LinkItemDetailView.swift | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift index c8f9837bd..79bd6c40b 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift @@ -10,6 +10,7 @@ final class WebAppViewCoordinator: NSObject { private var yOffsetAtStartOfDrag: Double? private var lastYOffset: Double = 0 private var hasDragged = false + private var isNavBarHidden = false override init() { super.init() @@ -48,20 +49,23 @@ extension WebAppViewCoordinator: UIScrollViewDelegate { let yOffset = scrollView.contentOffset.y if yOffset <= 0 { + isNavBarHidden = false updateNavBarVisibilityRatio(1) return } if yOffset < 30 { - updateNavBarVisibilityRatio(1) // yOffset / 30) + let isScrollingUp = yOffsetAtStartOfDrag ?? 0 > yOffset + updateNavBarVisibilityRatio(isScrollingUp ? 1 : 1 - (yOffset / 30)) return } guard let yOffsetAtStartOfDrag = yOffsetAtStartOfDrag else { return } - if yOffset > yOffsetAtStartOfDrag { + if yOffset > yOffsetAtStartOfDrag, !isNavBarHidden { let translation = yOffset - yOffsetAtStartOfDrag - let ratio = 0.0 // translation < 30 ? translation / 30 : 0 + let ratio = translation < 30 ? translation / 30 : 0 + isNavBarHidden = ratio == 0 updateNavBarVisibilityRatio(ratio) } } @@ -69,6 +73,7 @@ extension WebAppViewCoordinator: UIScrollViewDelegate { func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { if decelerate, scrollView.contentOffset.y < (yOffsetAtStartOfDrag ?? 0) { updateNavBarVisibilityRatio(1) + isNavBarHidden = false } yOffsetAtStartOfDrag = nil } diff --git a/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift b/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift index bb26f31f6..8c5a9d1f0 100644 --- a/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift +++ b/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift @@ -96,8 +96,9 @@ public struct LinkItemDetailView: View { } #endif } - .scaleEffect(x: 1, y: navBarVisibilityRatio) .frame(height: 30 * navBarVisibilityRatio) + .opacity(navBarVisibilityRatio) + .offset(x: 0.0, y: -30 * (1 - navBarVisibilityRatio)) } if let webAppWrapperViewModel = viewModel.webAppWrapperViewModel { WebAppWrapperView( From 997f087635ff33942e0509be9aaaf8014f863bd8 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Wed, 16 Feb 2022 13:39:45 -0800 Subject: [PATCH 03/13] adjust nav bar height --- .../Views/Article/WebAppViewCoordinator.swift | 7 +++--- .../LinkedItemDetail/LinkItemDetailView.swift | 23 +++++++++++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift index 79bd6c40b..4eca657e8 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift @@ -2,6 +2,7 @@ import SwiftUI import WebKit final class WebAppViewCoordinator: NSObject { + let navBarHeight = LinkItemDetailView.navBarHeight var webViewActionHandler: (WKScriptMessage) -> Void = { _ in } var linkHandler: (URL) -> Void = { _ in } var needsReload = true @@ -54,9 +55,9 @@ extension WebAppViewCoordinator: UIScrollViewDelegate { return } - if yOffset < 30 { + if yOffset < navBarHeight { let isScrollingUp = yOffsetAtStartOfDrag ?? 0 > yOffset - updateNavBarVisibilityRatio(isScrollingUp ? 1 : 1 - (yOffset / 30)) + updateNavBarVisibilityRatio(isScrollingUp ? 1 : 1 - (yOffset / navBarHeight)) return } @@ -64,7 +65,7 @@ extension WebAppViewCoordinator: UIScrollViewDelegate { if yOffset > yOffsetAtStartOfDrag, !isNavBarHidden { let translation = yOffset - yOffsetAtStartOfDrag - let ratio = translation < 30 ? translation / 30 : 0 + let ratio = translation < navBarHeight ? 1 - (translation / navBarHeight) : 0 isNavBarHidden = ratio == 0 updateNavBarVisibilityRatio(ratio) } diff --git a/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift b/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift index 8c5a9d1f0..c3576ba81 100644 --- a/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift +++ b/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift @@ -27,6 +27,7 @@ public final class LinkItemDetailViewModel: ObservableObject { public struct LinkItemDetailView: View { @Environment(\.presentationMode) var presentationMode: Binding + static let navBarHeight = 50.0 @ObservedObject private var viewModel: LinkItemDetailViewModel @State private var showFontSizePopover = false @State private var navBarVisibilityRatio = 1.0 @@ -73,20 +74,22 @@ public struct LinkItemDetailView: View { action: { self.presentationMode.wrappedValue.dismiss() }, label: { Image(systemName: "chevron.backward") - .font(.appTitleThree) + .font(.appTitle) .foregroundColor(.appGrayTextContrast) .padding(.horizontal) - .padding(.bottom, 5) } ) + .scaleEffect(navBarVisibilityRatio) Spacer() Button( action: { showFontSizePopover = true }, label: { Image(systemName: "textformat.size") + .font(.appTitle) } ) .padding(.horizontal) + .scaleEffect(navBarVisibilityRatio) #if os(iOS) .fittedPopover(isPresented: $showFontSizePopover) { FontSizeAdjustmentPopoverView( @@ -96,15 +99,13 @@ public struct LinkItemDetailView: View { } #endif } - .frame(height: 30 * navBarVisibilityRatio) + .frame(height: LinkItemDetailView.navBarHeight * navBarVisibilityRatio) .opacity(navBarVisibilityRatio) - .offset(x: 0.0, y: -30 * (1 - navBarVisibilityRatio)) } if let webAppWrapperViewModel = viewModel.webAppWrapperViewModel { WebAppWrapperView( viewModel: webAppWrapperViewModel, navBarVisibilityRatioUpdater: { - print($0) navBarVisibilityRatio = $0 } ) @@ -164,3 +165,15 @@ public struct LinkItemDetailView: View { } } } + +// Enable swipe to go back behavior if nav bar is hidden +extension UINavigationController: UIGestureRecognizerDelegate { + override open func viewDidLoad() { + super.viewDidLoad() + interactivePopGestureRecognizer?.delegate = self + } + + public func gestureRecognizerShouldBegin(_: UIGestureRecognizer) -> Bool { + viewControllers.count > 1 + } +} From 96a02a385543e42e89198e17e7cc1aa4abb1a35a Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Wed, 16 Feb 2022 17:34:08 -0800 Subject: [PATCH 04/13] use zstack to show font adjustment view --- .../LinkedItemDetail/LinkItemDetailView.swift | 44 +++++++++++++------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift b/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift index c3576ba81..ef5e6860e 100644 --- a/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift +++ b/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift @@ -82,7 +82,7 @@ public struct LinkItemDetailView: View { .scaleEffect(navBarVisibilityRatio) Spacer() Button( - action: { showFontSizePopover = true }, + action: { showFontSizePopover.toggle() }, label: { Image(systemName: "textformat.size") .font(.appTitle) @@ -90,25 +90,41 @@ public struct LinkItemDetailView: View { ) .padding(.horizontal) .scaleEffect(navBarVisibilityRatio) - #if os(iOS) - .fittedPopover(isPresented: $showFontSizePopover) { - FontSizeAdjustmentPopoverView( - increaseFontAction: { viewModel.webAppWrapperViewModel?.sendIncreaseFontSignal = true }, - decreaseFontAction: { viewModel.webAppWrapperViewModel?.sendDecreaseFontSignal = true } - ) - } - #endif } .frame(height: LinkItemDetailView.navBarHeight * navBarVisibilityRatio) .opacity(navBarVisibilityRatio) } if let webAppWrapperViewModel = viewModel.webAppWrapperViewModel { - WebAppWrapperView( - viewModel: webAppWrapperViewModel, - navBarVisibilityRatioUpdater: { - navBarVisibilityRatio = $0 + ZStack { + WebAppWrapperView( + viewModel: webAppWrapperViewModel, + navBarVisibilityRatioUpdater: { + navBarVisibilityRatio = $0 + } + ) + if showFontSizePopover { + VStack { + HStack { + Spacer() + FontSizeAdjustmentPopoverView( + increaseFontAction: { viewModel.webAppWrapperViewModel?.sendIncreaseFontSignal = true }, + decreaseFontAction: { viewModel.webAppWrapperViewModel?.sendDecreaseFontSignal = true } + ) + .background(Color.appButtonBackground) + .cornerRadius(8) + .padding(.trailing, 5) + } + Spacer() + } + .background( + Color.clear + .contentShape(Rectangle()) + .onTapGesture { + showFontSizePopover = false + } + ) } - ) + } } else { Spacer() .onAppear { From 69c64aa390b5681cb55ac9cc4dbe7f803d2e15a4 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Wed, 16 Feb 2022 17:39:13 -0800 Subject: [PATCH 05/13] hide popover view when nav bar shrinks --- .../LinkedItemDetail/LinkItemDetailView.swift | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift b/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift index ef5e6860e..68504039f 100644 --- a/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift +++ b/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift @@ -54,6 +54,13 @@ public struct LinkItemDetailView: View { ) } + var fontAdjustmentPopoverView: some View { + FontSizeAdjustmentPopoverView( + increaseFontAction: { viewModel.webAppWrapperViewModel?.sendIncreaseFontSignal = true }, + decreaseFontAction: { viewModel.webAppWrapperViewModel?.sendDecreaseFontSignal = true } + ) + } + public var body: some View { #if os(iOS) if UIDevice.isIPhone, !viewModel.item.isPDF { @@ -99,6 +106,9 @@ public struct LinkItemDetailView: View { WebAppWrapperView( viewModel: webAppWrapperViewModel, navBarVisibilityRatioUpdater: { + if $0 < 1 { + showFontSizePopover = false + } navBarVisibilityRatio = $0 } ) @@ -106,13 +116,10 @@ public struct LinkItemDetailView: View { VStack { HStack { Spacer() - FontSizeAdjustmentPopoverView( - increaseFontAction: { viewModel.webAppWrapperViewModel?.sendIncreaseFontSignal = true }, - decreaseFontAction: { viewModel.webAppWrapperViewModel?.sendDecreaseFontSignal = true } - ) - .background(Color.appButtonBackground) - .cornerRadius(8) - .padding(.trailing, 5) + fontAdjustmentPopoverView + .background(Color.appButtonBackground) + .cornerRadius(8) + .padding(.trailing, 5) } Spacer() } @@ -154,17 +161,11 @@ public struct LinkItemDetailView: View { ) #if os(iOS) .fittedPopover(isPresented: $showFontSizePopover) { - FontSizeAdjustmentPopoverView( - increaseFontAction: { viewModel.webAppWrapperViewModel?.sendIncreaseFontSignal = true }, - decreaseFontAction: { viewModel.webAppWrapperViewModel?.sendDecreaseFontSignal = true } - ) + fontAdjustmentPopoverView } #else .popover(isPresented: $showFontSizePopover) { - FontSizeAdjustmentPopoverView( - increaseFontAction: { viewModel.webAppWrapperViewModel?.sendIncreaseFontSignal = true }, - decreaseFontAction: { viewModel.webAppWrapperViewModel?.sendDecreaseFontSignal = true } - ) + fontAdjustmentPopoverView } #endif } From e07a504daa453842bce2691feecf4bac916d0e19 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Wed, 16 Feb 2022 19:43:16 -0800 Subject: [PATCH 06/13] show nav bar when user taps the status bar --- .../Views/Article/WebAppViewCoordinator.swift | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift index 4eca657e8..cdd0c55a3 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift @@ -16,6 +16,12 @@ final class WebAppViewCoordinator: NSObject { override init() { super.init() } + + var navBarVisibilityRatio: Double = 1.0 { + didSet { + updateNavBarVisibilityRatio(navBarVisibilityRatio) + } + } } extension WebAppViewCoordinator: WKScriptMessageHandler { @@ -51,13 +57,13 @@ extension WebAppViewCoordinator: UIScrollViewDelegate { if yOffset <= 0 { isNavBarHidden = false - updateNavBarVisibilityRatio(1) + navBarVisibilityRatio = 1 return } if yOffset < navBarHeight { let isScrollingUp = yOffsetAtStartOfDrag ?? 0 > yOffset - updateNavBarVisibilityRatio(isScrollingUp ? 1 : 1 - (yOffset / navBarHeight)) + navBarVisibilityRatio = isScrollingUp ? 1 : 1 - (yOffset / navBarHeight) return } @@ -67,17 +73,26 @@ extension WebAppViewCoordinator: UIScrollViewDelegate { let translation = yOffset - yOffsetAtStartOfDrag let ratio = translation < navBarHeight ? 1 - (translation / navBarHeight) : 0 isNavBarHidden = ratio == 0 - updateNavBarVisibilityRatio(ratio) + navBarVisibilityRatio = ratio } } func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { if decelerate, scrollView.contentOffset.y < (yOffsetAtStartOfDrag ?? 0) { - updateNavBarVisibilityRatio(1) + navBarVisibilityRatio = 1 isNavBarHidden = false } yOffsetAtStartOfDrag = nil } + + func scrollViewShouldScrollToTop(_: UIScrollView) -> Bool { + if navBarVisibilityRatio == 1 { + return true + } else { + navBarVisibilityRatio = 1 + return false + } + } } struct WebViewConfig { From 45533fa562cc37e36d2e78daf24b2b113d616e8f Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Wed, 16 Feb 2022 20:27:28 -0800 Subject: [PATCH 07/13] remove scroll to top behavior on iphone reader view --- .../Views/Article/WebAppViewCoordinator.swift | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift index cdd0c55a3..56ac52396 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift @@ -19,6 +19,7 @@ final class WebAppViewCoordinator: NSObject { var navBarVisibilityRatio: Double = 1.0 { didSet { + isNavBarHidden = navBarVisibilityRatio == 0 updateNavBarVisibilityRatio(navBarVisibilityRatio) } } @@ -55,8 +56,7 @@ extension WebAppViewCoordinator: UIScrollViewDelegate { let yOffset = scrollView.contentOffset.y - if yOffset <= 0 { - isNavBarHidden = false + if yOffset == 0 { navBarVisibilityRatio = 1 return } @@ -72,7 +72,6 @@ extension WebAppViewCoordinator: UIScrollViewDelegate { if yOffset > yOffsetAtStartOfDrag, !isNavBarHidden { let translation = yOffset - yOffsetAtStartOfDrag let ratio = translation < navBarHeight ? 1 - (translation / navBarHeight) : 0 - isNavBarHidden = ratio == 0 navBarVisibilityRatio = ratio } } @@ -80,18 +79,13 @@ extension WebAppViewCoordinator: UIScrollViewDelegate { func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { if decelerate, scrollView.contentOffset.y < (yOffsetAtStartOfDrag ?? 0) { navBarVisibilityRatio = 1 - isNavBarHidden = false } yOffsetAtStartOfDrag = nil } func scrollViewShouldScrollToTop(_: UIScrollView) -> Bool { - if navBarVisibilityRatio == 1 { - return true - } else { - navBarVisibilityRatio = 1 - return false - } + navBarVisibilityRatio = 1 + return false } } From 0eca98099356de5519ea73ee94261871e8e85b0b Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Wed, 16 Feb 2022 20:40:39 -0800 Subject: [PATCH 08/13] adjust scroll content offset when nav bar toggles --- .../Sources/Views/Article/WebAppViewCoordinator.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift index 56ac52396..e741a70f6 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift @@ -57,6 +57,8 @@ extension WebAppViewCoordinator: UIScrollViewDelegate { let yOffset = scrollView.contentOffset.y if yOffset == 0 { + let additionalOffset = (1 - navBarVisibilityRatio) * navBarHeight + scrollView.contentOffset.y += additionalOffset navBarVisibilityRatio = 1 return } @@ -78,12 +80,16 @@ extension WebAppViewCoordinator: UIScrollViewDelegate { func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { if decelerate, scrollView.contentOffset.y < (yOffsetAtStartOfDrag ?? 0) { + let additionalOffset = (1 - navBarVisibilityRatio) * navBarHeight + scrollView.contentOffset.y += additionalOffset navBarVisibilityRatio = 1 } yOffsetAtStartOfDrag = nil } - func scrollViewShouldScrollToTop(_: UIScrollView) -> Bool { + func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool { + let additionalOffset = (1 - navBarVisibilityRatio) * navBarHeight + scrollView.contentOffset.y += additionalOffset navBarVisibilityRatio = 1 return false } From 50d8310ae7f415047e75aebc5930d4800393da0b Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Wed, 16 Feb 2022 21:01:55 -0800 Subject: [PATCH 09/13] add padding around font adjustment buttons to increase tap target --- .../Sources/Views/FontSizeAdjustmentPopoverView.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apple/OmnivoreKit/Sources/Views/FontSizeAdjustmentPopoverView.swift b/apple/OmnivoreKit/Sources/Views/FontSizeAdjustmentPopoverView.swift index 7147ab60d..deff8c4f8 100644 --- a/apple/OmnivoreKit/Sources/Views/FontSizeAdjustmentPopoverView.swift +++ b/apple/OmnivoreKit/Sources/Views/FontSizeAdjustmentPopoverView.swift @@ -23,6 +23,7 @@ public struct FontSizeAdjustmentPopoverView: View { Image(systemName: "minus") #if os(iOS) .foregroundColor(.appGraySolid) + .padding() #endif } ) @@ -37,6 +38,7 @@ public struct FontSizeAdjustmentPopoverView: View { Image(systemName: "plus") #if os(iOS) .foregroundColor(.appGraySolid) + .padding() #endif } ) From e929c5d1a1e1ce41f7376cd7458f06e7f0fc6882 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Wed, 16 Feb 2022 21:19:07 -0800 Subject: [PATCH 10/13] remove spacing on ios reader reader --- .../Sources/Views/LinkedItemDetail/LinkItemDetailView.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift b/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift index 68504039f..b8c4654e3 100644 --- a/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift +++ b/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift @@ -74,14 +74,14 @@ public struct LinkItemDetailView: View { } @ViewBuilder private var compactInnerBody: some View { - VStack { + VStack(spacing: 0) { withAnimation { HStack(alignment: .center) { Button( action: { self.presentationMode.wrappedValue.dismiss() }, label: { Image(systemName: "chevron.backward") - .font(.appTitle) + .font(.appTitleTwo) .foregroundColor(.appGrayTextContrast) .padding(.horizontal) } @@ -92,7 +92,7 @@ public struct LinkItemDetailView: View { action: { showFontSizePopover.toggle() }, label: { Image(systemName: "textformat.size") - .font(.appTitle) + .font(.appTitleTwo) } ) .padding(.horizontal) From ea93f3926e8cb1cc45b84b31939c2fccd7f0cf5f Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Thu, 17 Feb 2022 15:36:41 -0800 Subject: [PATCH 11/13] WiP --- .../Sources/Views/Article/WebAppView.swift | 2 +- .../Views/Article/WebAppViewCoordinator.swift | 30 ++-- .../LinkedItemDetail/LinkItemDetailView.swift | 131 ++++++++++-------- 3 files changed, 91 insertions(+), 72 deletions(-) diff --git a/apple/OmnivoreKit/Sources/Views/Article/WebAppView.swift b/apple/OmnivoreKit/Sources/Views/Article/WebAppView.swift index 6d7286f2c..0176a7dd7 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/WebAppView.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/WebAppView.swift @@ -29,7 +29,7 @@ import WebKit let webView = WebView(frame: CGRect.zero) let contentController = WKUserContentController() - webView.scrollView.isScrollEnabled = true + webView.scrollView.contentInset.top = LinkItemDetailView.navBarHeight webView.navigationDelegate = context.coordinator webView.isOpaque = false webView.backgroundColor = UIColor.clear diff --git a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift index e741a70f6..5cd8010f5 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift @@ -20,6 +20,7 @@ final class WebAppViewCoordinator: NSObject { var navBarVisibilityRatio: Double = 1.0 { didSet { isNavBarHidden = navBarVisibilityRatio == 0 + print(navBarVisibilityRatio) updateNavBarVisibilityRatio(navBarVisibilityRatio) } } @@ -48,24 +49,31 @@ extension WebAppViewCoordinator: WKNavigationDelegate { extension WebAppViewCoordinator: UIScrollViewDelegate { func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { hasDragged = true - yOffsetAtStartOfDrag = scrollView.contentOffset.y + yOffsetAtStartOfDrag = scrollView.contentOffset.y + scrollView.contentInset.top } func scrollViewDidScroll(_ scrollView: UIScrollView) { guard hasDragged else { return } - let yOffset = scrollView.contentOffset.y + let yOffset = scrollView.contentOffset.y + scrollView.contentInset.top if yOffset == 0 { - let additionalOffset = (1 - navBarVisibilityRatio) * navBarHeight - scrollView.contentOffset.y += additionalOffset + scrollView.contentInset.top = navBarHeight navBarVisibilityRatio = 1 return } + if yOffset < 0 { + navBarVisibilityRatio = 1 + scrollView.contentInset.top = navBarHeight + return + } + if yOffset < navBarHeight { let isScrollingUp = yOffsetAtStartOfDrag ?? 0 > yOffset - navBarVisibilityRatio = isScrollingUp ? 1 : 1 - (yOffset / navBarHeight) + navBarVisibilityRatio = isScrollingUp || yOffset < 0 ? 1 : min(1, 1 - (yOffset / navBarHeight)) + print("parkour!", navBarVisibilityRatio, isScrollingUp, yOffsetAtStartOfDrag, yOffset) + scrollView.contentInset.top = navBarVisibilityRatio * navBarHeight return } @@ -74,22 +82,22 @@ extension WebAppViewCoordinator: UIScrollViewDelegate { if yOffset > yOffsetAtStartOfDrag, !isNavBarHidden { let translation = yOffset - yOffsetAtStartOfDrag let ratio = translation < navBarHeight ? 1 - (translation / navBarHeight) : 0 - navBarVisibilityRatio = ratio + navBarVisibilityRatio = min(ratio, 1) +// print("bike!", navBarVisibilityRatio) + scrollView.contentInset.top = navBarVisibilityRatio * navBarHeight } } func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { - if decelerate, scrollView.contentOffset.y < (yOffsetAtStartOfDrag ?? 0) { - let additionalOffset = (1 - navBarVisibilityRatio) * navBarHeight - scrollView.contentOffset.y += additionalOffset + if decelerate, scrollView.contentOffset.y + scrollView.contentInset.top < (yOffsetAtStartOfDrag ?? 0) { + scrollView.contentInset.top = navBarHeight navBarVisibilityRatio = 1 } yOffsetAtStartOfDrag = nil } func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool { - let additionalOffset = (1 - navBarVisibilityRatio) * navBarHeight - scrollView.contentOffset.y += additionalOffset + scrollView.contentInset.top = navBarHeight navBarVisibilityRatio = 1 return false } diff --git a/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift b/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift index b8c4654e3..c107daf51 100644 --- a/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift +++ b/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift @@ -73,73 +73,84 @@ public struct LinkItemDetailView: View { #endif } - @ViewBuilder private var compactInnerBody: some View { - VStack(spacing: 0) { - withAnimation { - HStack(alignment: .center) { - Button( - action: { self.presentationMode.wrappedValue.dismiss() }, - label: { - Image(systemName: "chevron.backward") - .font(.appTitleTwo) - .foregroundColor(.appGrayTextContrast) - .padding(.horizontal) - } - ) - .scaleEffect(navBarVisibilityRatio) - Spacer() - Button( - action: { showFontSizePopover.toggle() }, - label: { - Image(systemName: "textformat.size") - .font(.appTitleTwo) - } - ) - .padding(.horizontal) - .scaleEffect(navBarVisibilityRatio) + var navBar: some View { + HStack(alignment: .center) { + Button( + action: { self.presentationMode.wrappedValue.dismiss() }, + label: { + Image(systemName: "chevron.backward") + .font(.appTitleTwo) + .foregroundColor(.appGrayTextContrast) + .padding(.horizontal) } - .frame(height: LinkItemDetailView.navBarHeight * navBarVisibilityRatio) - .opacity(navBarVisibilityRatio) - } - if let webAppWrapperViewModel = viewModel.webAppWrapperViewModel { - ZStack { - WebAppWrapperView( - viewModel: webAppWrapperViewModel, - navBarVisibilityRatioUpdater: { - if $0 < 1 { + ) + .scaleEffect(navBarVisibilityRatio) + Spacer() + Button( + action: { showFontSizePopover.toggle() }, + label: { + Image(systemName: "textformat.size") + .font(.appTitleTwo) + } + ) + .padding(.horizontal) + .scaleEffect(navBarVisibilityRatio) + } + .frame(height: LinkItemDetailView.navBarHeight * navBarVisibilityRatio) + .opacity(navBarVisibilityRatio) + .background(Color.systemBackground) + } + + @ViewBuilder private var compactInnerBody: some View { + if let webAppWrapperViewModel = viewModel.webAppWrapperViewModel { + ZStack { + WebAppWrapperView( + viewModel: webAppWrapperViewModel, + navBarVisibilityRatioUpdater: { + if $0 < 1 { + showFontSizePopover = false + } + navBarVisibilityRatio = $0 + } + ) + if showFontSizePopover { + VStack { + Color.clear + .contentShape(Rectangle()) + .frame(height: LinkItemDetailView.navBarHeight) + HStack { + Spacer() + fontAdjustmentPopoverView + .background(Color.appButtonBackground) + .cornerRadius(8) + .padding(.trailing, 5) + } + Spacer() + } + .background( + Color.clear + .contentShape(Rectangle()) + .onTapGesture { showFontSizePopover = false } - navBarVisibilityRatio = $0 - } ) - if showFontSizePopover { - VStack { - HStack { - Spacer() - fontAdjustmentPopoverView - .background(Color.appButtonBackground) - .cornerRadius(8) - .padding(.trailing, 5) - } - Spacer() - } - .background( - Color.clear - .contentShape(Rectangle()) - .onTapGesture { - showFontSizePopover = false - } - ) - } } - } else { - Spacer() - .onAppear { - viewModel.performActionSubject.send(.load) - } + VStack(spacing: 0) { + navBar + Spacer() + } } + .navigationBarHidden(true) + } else { + VStack(spacing: 0) { + navBar + Spacer() + } + .onAppear { + viewModel.performActionSubject.send(.load) + } + .navigationBarHidden(true) } - .navigationBarHidden(true) } @ViewBuilder private var innerBody: some View { From ad9d37e6114a91e090d3362394fa74c54b15a06b Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Thu, 17 Feb 2022 16:08:00 -0800 Subject: [PATCH 12/13] remove print statements --- .../Sources/Views/Article/WebAppViewCoordinator.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift index 5cd8010f5..0131665ef 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift @@ -20,7 +20,6 @@ final class WebAppViewCoordinator: NSObject { var navBarVisibilityRatio: Double = 1.0 { didSet { isNavBarHidden = navBarVisibilityRatio == 0 - print(navBarVisibilityRatio) updateNavBarVisibilityRatio(navBarVisibilityRatio) } } @@ -72,7 +71,6 @@ extension WebAppViewCoordinator: UIScrollViewDelegate { if yOffset < navBarHeight { let isScrollingUp = yOffsetAtStartOfDrag ?? 0 > yOffset navBarVisibilityRatio = isScrollingUp || yOffset < 0 ? 1 : min(1, 1 - (yOffset / navBarHeight)) - print("parkour!", navBarVisibilityRatio, isScrollingUp, yOffsetAtStartOfDrag, yOffset) scrollView.contentInset.top = navBarVisibilityRatio * navBarHeight return } @@ -83,7 +81,6 @@ extension WebAppViewCoordinator: UIScrollViewDelegate { let translation = yOffset - yOffsetAtStartOfDrag let ratio = translation < navBarHeight ? 1 - (translation / navBarHeight) : 0 navBarVisibilityRatio = min(ratio, 1) -// print("bike!", navBarVisibilityRatio) scrollView.contentInset.top = navBarVisibilityRatio * navBarHeight } } From d9f32d05595822c7088152762f343b9cc16250f9 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Thu, 17 Feb 2022 16:25:24 -0800 Subject: [PATCH 13/13] fix animation glitch --- .../Sources/Views/Article/WebAppViewCoordinator.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift index 0131665ef..bbc3e7591 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift @@ -54,7 +54,7 @@ extension WebAppViewCoordinator: UIScrollViewDelegate { func scrollViewDidScroll(_ scrollView: UIScrollView) { guard hasDragged else { return } - let yOffset = scrollView.contentOffset.y + scrollView.contentInset.top + let yOffset = scrollView.contentOffset.y if yOffset == 0 { scrollView.contentInset.top = navBarHeight @@ -90,7 +90,6 @@ extension WebAppViewCoordinator: UIScrollViewDelegate { scrollView.contentInset.top = navBarHeight navBarVisibilityRatio = 1 } - yOffsetAtStartOfDrag = nil } func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {