From 2791f810fe53f1225d07ed4680ed87a133bb5ab8 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Fri, 28 Jan 2022 14:55:51 +0200 Subject: iOS: Scroll to top on status bar taps --- src/ios.m | 30 +++++++++++++++++++++++++++++- src/ui/documentwidget.c | 6 ++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/ios.m b/src/ios.m index 154eb3ef..68c03827 100644 --- a/src/ios.m +++ b/src/ios.m @@ -163,7 +163,8 @@ API_AVAILABLE(ios(13.0)) /*----------------------------------------------------------------------------------------------*/ -@interface AppState : NSObject { +@interface AppState : NSObject { iString *fileBeingSaved; iString *pickFileCommand; iSystemTextInput *sysCtrl; @@ -173,6 +174,7 @@ API_AVAILABLE(ios(13.0)) @end static AppState *appState_; +static UIScrollView *statusBarTapper_; /* dummy scroll view just for getting notified of taps */ @implementation AppState @@ -310,6 +312,11 @@ replacementString:(NSString *)string { notifyChange_SystemTextInput_(sysCtrl); } +- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView { + postCommand_App("scroll.top smooth:1"); + return NO; +} + @end /*----------------------------------------------------------------------------------------------*/ @@ -428,6 +435,19 @@ void setupWindow_iOS(iWindow *window) { UIViewController *ctl = viewController_(window); isSystemDarkMode_ = isDarkMode_(window); postCommandf_App("~os.theme.changed dark:%d contrast:1", isSystemDarkMode_ ? 1 : 0); + /* A hack to get notified on status bar taps. We create a thin dummy UIScrollView + that occupies the top of the screen where the status bar is located. */ { + CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame; + statusBarTapper_ = [[UIScrollView alloc] initWithFrame:statusBarFrame]; +// [statusBarTapper_ setBackgroundColor:[UIColor greenColor]]; /* to see where it is */ + [statusBarTapper_ setShowsVerticalScrollIndicator:NO]; + [statusBarTapper_ setShowsHorizontalScrollIndicator:NO]; + [statusBarTapper_ setContentSize:(CGSize){ 10000, 10000 }]; + [statusBarTapper_ setContentOffset:(CGPoint){ 0, 1000 }]; + [statusBarTapper_ setScrollsToTop:YES]; + [statusBarTapper_ setDelegate:appState_]; + [ctl.view addSubview:statusBarTapper_]; + } } void playHapticEffect_iOS(enum iHapticEffect effect) { @@ -445,6 +465,14 @@ void playHapticEffect_iOS(enum iHapticEffect effect) { } iBool processEvent_iOS(const SDL_Event *ev) { + if (ev->type == SDL_DISPLAYEVENT) { + if (deviceType_App() == phone_AppDeviceType) { + [statusBarTapper_ setHidden:(ev->display.data1 == SDL_ORIENTATION_LANDSCAPE || + ev->display.data1 == SDL_ORIENTATION_LANDSCAPE_FLIPPED)]; + } + [statusBarTapper_ setFrame:[UIApplication sharedApplication].statusBarFrame]; + return iFalse; + } if (ev->type == SDL_WINDOWEVENT) { if (ev->window.event == SDL_WINDOWEVENT_RESTORED) { const iBool isDark = isDarkMode_(get_Window()); diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index beff0f3f..2e15cdce 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c @@ -4351,6 +4351,12 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) return iTrue; } else if (equal_Command(cmd, "scroll.top") && document_App() == d) { + if (argLabel_Command(cmd, "smooth")) { + stopWidgetMomentum_Touch(w); + smoothScroll_DocumentView_(&d->view, -pos_SmoothScroll(&d->view.scrollY), 500); + d->view.scrollY.flags |= muchSofter_AnimFlag; + return iTrue; + } init_Anim(&d->view.scrollY.pos, 0); invalidate_VisBuf(d->view.visBuf); clampScroll_DocumentView_(&d->view); -- cgit v1.2.3