Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 58 additions & 5 deletions Ports/iOSPort/nativeSources/CodenameOne_GLViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,31 @@ static CGSize cn1OrientationCorrectSize(UIView *view) {
return size;
}
BOOL forceSlideUpField;
static UIScrollView *cn1StatusBarTapProxy = nil;

// UIScrollView subclass used solely to receive the status-bar tap
// (scrollViewShouldScrollToTop:) on iOS. Touches must pass through to the
// underlying GL view, so we always return NO from pointInside:.
// layoutSubviews keeps contentSize larger than the bounds so iOS considers
// the scroll view actually scrollable, which is required for the system to
// dispatch the scroll-to-top message.
@interface CN1StatusBarTapProxyView : UIScrollView
@end
@implementation CN1StatusBarTapProxyView
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
return NO;
}
- (void)layoutSubviews {
[super layoutSubviews];
CGSize sz = self.bounds.size;
if (sz.width < 1) sz.width = 1;
self.contentSize = CGSizeMake(sz.width, sz.height + 1);
if (self.contentOffset.y <= 0) {
self.contentOffset = CGPointMake(0, 1);
}
}
@end

static CN1StatusBarTapProxyView *cn1StatusBarTapProxy = nil;


// 1 for portrait lock, and 2 for landscape lock
Expand Down Expand Up @@ -572,6 +596,11 @@ void cn1_setStyleDoneButton(CN1_THREAD_STATE_MULTI_ARG UIBarButtonItem* btn) {
utv.blockPaste = CN1_blockPaste || blockCopyPaste;
utv.blockCopy = CN1_blockCopy || blockCopyPaste;
utv.blockCut = CN1_blockCut || blockCopyPaste;
// Avoid competing with the CN1 status-bar tap proxy: iOS only fires
// scrollViewShouldScrollToTop: when exactly one scroll view has
// scrollsToTop=YES, and UITextView's internal scroll view defaults
// to YES.
utv.scrollsToTop = NO;
[utv setBackgroundColor:[UIColor clearColor]];
[utv.layer setBorderColor:[[UIColor clearColor] CGColor]];
[utv.layer setBorderWidth:0];
Expand Down Expand Up @@ -1946,17 +1975,37 @@ - (void)viewDidLoad {

- (void)cn1InstallStatusBarTapProxy {
if (cn1StatusBarTapProxy != nil) {
// Re-attach if it was detached and ensure it sits on top so it isn't
// hidden by peer components added later in the view hierarchy.
if (cn1StatusBarTapProxy.superview != self.view) {
[cn1StatusBarTapProxy removeFromSuperview];
[self.view addSubview:cn1StatusBarTapProxy];
} else {
[self.view bringSubviewToFront:cn1StatusBarTapProxy];
}
return;
}
cn1StatusBarTapProxy = [[UIScrollView alloc] initWithFrame:self.view.bounds];
cn1StatusBarTapProxy = [[CN1StatusBarTapProxyView alloc] initWithFrame:self.view.bounds];
cn1StatusBarTapProxy.delegate = self;
cn1StatusBarTapProxy.backgroundColor = [UIColor clearColor];
cn1StatusBarTapProxy.contentSize = CGSizeMake(1, 2);
cn1StatusBarTapProxy.contentOffset = CGPointMake(0, 1);
cn1StatusBarTapProxy.scrollsToTop = YES;
cn1StatusBarTapProxy.userInteractionEnabled = NO;
// userInteractionEnabled must remain YES; some iOS versions skip the
// scrollViewShouldScrollToTop: dispatch for views that have it disabled.
// pointInside: in the subclass ensures touches still pass through.
cn1StatusBarTapProxy.userInteractionEnabled = YES;
cn1StatusBarTapProxy.scrollEnabled = YES;
cn1StatusBarTapProxy.showsVerticalScrollIndicator = NO;
cn1StatusBarTapProxy.showsHorizontalScrollIndicator = NO;
cn1StatusBarTapProxy.bounces = NO;
cn1StatusBarTapProxy.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
cn1StatusBarTapProxy.alpha = 0.0f;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
if (@available(iOS 11.0, *)) {
cn1StatusBarTapProxy.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
#endif
cn1StatusBarTapProxy.contentSize = CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height + 1);
cn1StatusBarTapProxy.contentOffset = CGPointMake(0, 1);
[self.view addSubview:cn1StatusBarTapProxy];
}

Expand Down Expand Up @@ -2032,6 +2081,10 @@ - (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self becomeFirstResponder];
[self updateCanvas:animated];
// Re-install / bring the status-bar tap proxy to the front. Native peers
// (browsers, video, etc.) added after viewDidLoad can obscure it or push
// sibling scroll views into the hierarchy.
[self cn1InstallStatusBarTapProxy];
//replaceViewDidAppear
}

Expand Down
8 changes: 8 additions & 0 deletions Ports/iOSPort/nativeSources/IOSNative.m
Original file line number Diff line number Diff line change
Expand Up @@ -2605,6 +2605,10 @@ JAVA_LONG com_codename1_impl_ios_IOSNative_createBrowserComponent___java_lang_Ob
com_codename1_impl_ios_IOSNative_createBrowserComponent.backgroundColor = [UIColor clearColor];
com_codename1_impl_ios_IOSNative_createBrowserComponent.opaque = NO;
com_codename1_impl_ios_IOSNative_createBrowserComponent.autoresizesSubviews = YES;
// Disable scrollsToTop on the embedded scroll view so it doesn't compete
// with the CN1 status-bar tap proxy. iOS only delivers the tap when
// exactly one scroll view on screen has scrollsToTop=YES.
com_codename1_impl_ios_IOSNative_createBrowserComponent.scrollView.scrollsToTop = NO;
UIWebViewEventDelegate *del = [[UIWebViewEventDelegate alloc] initWithCallback:obj];
com_codename1_impl_ios_IOSNative_createBrowserComponent.delegate = del;
com_codename1_impl_ios_IOSNative_createBrowserComponent.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
Expand Down Expand Up @@ -2653,6 +2657,10 @@ JAVA_LONG com_codename1_impl_ios_IOSNative_createWKBrowserComponent___java_lang_
com_codename1_impl_ios_IOSNative_createWKBrowserComponent.backgroundColor = [UIColor clearColor];
com_codename1_impl_ios_IOSNative_createWKBrowserComponent.opaque = NO;
com_codename1_impl_ios_IOSNative_createWKBrowserComponent.autoresizesSubviews = YES;
// Disable scrollsToTop on the embedded scroll view so it doesn't compete
// with the CN1 status-bar tap proxy. iOS only delivers the tap when
// exactly one scroll view on screen has scrollsToTop=YES.
com_codename1_impl_ios_IOSNative_createWKBrowserComponent.scrollView.scrollsToTop = NO;
cn1_setBrowserFollowTargetBlank(com_codename1_impl_ios_IOSNative_createWKBrowserComponent, YES);

if (getBooleanClientProperty(CN1_THREAD_GET_STATE_PASS_ARG obj, @"BrowserComponent.ios.debug")) {
Expand Down
Loading