diff --git a/README.md b/README.md index 8055870..3c61abb 100755 --- a/README.md +++ b/README.md @@ -5,11 +5,18 @@ ## Methods -### `createBottomSheet({properties}) ` +### MODULE -> `createBottomSheet({properties}) ` +returns the **bottomSheetObject** + +## bottomSheetObject Methods ### `show({animated:bool}) ` ### `hide({animated:bool}) ` manually hide the controller, per exaple if to did any action in the content view -### `selectedDetentIdentifier` return STRING - selectedDetentIdentifier (medium,large or none) +### `selectedDetentIdentifier` +return STRING - selectedDetentIdentifier (medium,large or none) +### `changeCurrentDetent(STRING)` +change the selectedDetentIdentifier animated ('large' or 'medium') **on 'nonSystemSheet:true' only** + ## Events @@ -21,33 +28,52 @@ manually hide the controller, per exaple if to did any action in the content vie ## Properties -### `detents:{large:bool,medium:bool}` -#### The object of heights where a sheet can rest. +### `detents:{large:bool,medium:bool,small:bool}` +The object of heights where a sheet can rest. *if not set, default to 'medium' only* ### `preferredCornerRadius:integer` -#### The corner radius that the sheet attempts to present with. +The corner radius that the sheet attempts to present with. *if not set default to iOS default radius* ### `prefersEdgeAttachedInCompactHeight:bool` -#### A Boolean value that determines whether the sheet attaches to the bottom edge of the screen in a compact-height size class. +A Boolean value that determines whether the sheet attaches to the bottom edge of the screen in a compact-height size class. ### `prefersScrollingExpandsWhenScrolledToEdge:bool` -#### A Boolean value that determines whether scrolling expands the sheet to a larger detent. +A Boolean value that determines whether scrolling expands the sheet to a larger detent. ### `widthFollowsPreferredContentSizeWhenEdgeAttached:bool` -#### A Boolean value that determines whether the sheet's width matches its view controller's preferred content size. +A Boolean value that determines whether the sheet's width matches its view controller's preferred content size. ### `prefersGrabberVisible:bool` -#### A Boolean value that determines whether the sheet shows a grabber at the top. +A Boolean value that determines whether the sheet shows a grabber at the top. + +### `nonModal:bool` +has effect ONLY when "nonSystemSheet:false" on iOS >= 15 + ### `largestUndimmedDetentIdentifier:string` -#### medium or large - if not set, it is full dimmed depending on activated detents - The largest detent that doesn’t dim the view underneath the sheet. +medium or large - if not set, it is full dimmed depending on activated detents - The largest detent that doesn’t dim the view underneath the sheet. ***If not set, defaults to full dimmed*** ### `contentView:TiUIView,TiUIWindow or TiUINavigationWindow` -#### View (any kind), Window or NavigationWindow +View (any kind), Window or NavigationWindow + +### `closeButton:TiUIView` +View or Button + +### `backgroundColor:Hex or String` + +### `nonSystemSheet:bool` +A Boolean value that determines whether the sheet is iOS15 or fallback version - if "false" and device is non iOS15 it also fallbacks - **if NOT SET -> defaults to "true"** + +### `nonSystemSheetTopShadow:bool` +topShadow visible or not visible + +### `nonSystemSheetShouldScroll:bool` +when your contentView is not a scrollable view, then this activates scrolling if the contentView is larger then the bottomSheet +**ATTENTION**: when you put a tableView, scrollView or listView inside your contentView this property disables scrolling in the contentView in favour of the bottomSheetScrollView ## Example @@ -113,14 +139,23 @@ bottomView.setData(tableRows,{animated:false}); var bottomSheetController = TiBottomSheetControllerModule.createBottomSheet({ - detents:{large:true,medium:true}, // The object of heights where a sheet can rest. - preferredCornerRadius:20, // The corner radius that the sheet attempts to present with. - prefersEdgeAttachedInCompactHeight:false, // A Boolean value that determines whether the sheet attaches to the bottom edge of the screen in a compact-height size class. - prefersScrollingExpandsWhenScrolledToEdge:false, // A Boolean value that determines whether scrolling expands the sheet to a larger detent. - widthFollowsPreferredContentSizeWhenEdgeAttached:false, // A Boolean value that determines whether the sheet's width matches its view controller's preferred content size. - prefersGrabberVisible:true, // A Boolean value that determines whether the sheet shows a grabber at the top. - largestUndimmedDetentIdentifier:'medium', // medium or large - if not set, it is full dimmed depending on activated detents - The largest detent that doesn’t dim the view underneath the sheet. - contentView: bottomView. // View (any kind), Window or NavigationWindow + detents:{large:true,medium:true,small:false}, // "small" has effect only when "nonSystemSheet:true" + startDetent:'medium', // medium or large - when "nonSystemSheet:true" also "small" is possible -- when startDetent is "small" and detents:{small:false} is defaults to "medium" and so on... + preferredCornerRadius:20, + prefersEdgeAttachedInCompactHeight:false, // has effect only when "nonSystemSheet:false" + prefersScrollingExpandsWhenScrolledToEdge:false, // has effect only when "nonSystemSheet:false" + widthFollowsPreferredContentSizeWhenEdgeAttached:true, // has effect only when "nonSystemSheet:false" + prefersGrabberVisible:true, // bottomSheet grabberHandle visible true / false + nonModal:false, // has effect ONLY when "nonSystemSheet:false" on iOS >= 15 + largestUndimmedDetentIdentifier:'small', // medium or large (also "small" available when "nonSystemSheet:true") - if not set, it is full dimmed depending on activated detents when "nonSystemSheet:true" the property also allow to interact with the view in the background of the bottomSheet - when not dimmed, when dimmed interaction is not possible with the view in the background + contentView: bottomView, + closeButton:YOUR_CLOSEBUTTON_VIEW_FOR_THE_SHEET, // add a closeButtonView to the bottomSheet + backgroundColor:'#eeeeee', + + nonSystemSheet:false, // defaults to "true" if not set - non iOS 15 SheetController (backwards compatible to non iOS15) when "true" - iOS15+ SheetController when "false" - if non iOS15 and set to "false" it also defaults to "true" + nonSystemSheetTopShadow:true, // has effect only on "nonSystemSheet:true" + nonSystemSheetShouldScroll:true, // when your contentView is not a scrollable view, then this activates scrolling if the contentView is larger then the bottomSheet + // ATTENTION: when you put a tableView, scrollView or listView inside your contentView this property disables scrolling in the contentView in favour of the bottomSheetScrollView }); bottomSheetController.addEventListener('dismissing', function() { diff --git a/demo.gif b/demo.gif old mode 100644 new mode 100755 diff --git a/ios/Assets.xcassets/Contents.json b/ios/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/ios/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ios/Assets.xcassets/cancel.imageset/Contents.json b/ios/Assets.xcassets/cancel.imageset/Contents.json new file mode 100644 index 0000000..450a4d1 --- /dev/null +++ b/ios/Assets.xcassets/cancel.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "cancel.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ios/Assets.xcassets/cancel.imageset/cancel.png b/ios/Assets.xcassets/cancel.imageset/cancel.png new file mode 100644 index 0000000..1d960c6 Binary files /dev/null and b/ios/Assets.xcassets/cancel.imageset/cancel.png differ diff --git a/ios/Classes/BottomSheetVC.h b/ios/Classes/BottomSheetVC.h deleted file mode 100755 index 15ccf22..0000000 --- a/ios/Classes/BottomSheetVC.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// BottomSheetVC.h -// BottomSheetTutorial -// -// Created by Khoa Mai on 5/4/19. -// Copyright © 2019 Khoa Mai. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface BottomSheetVC : UIViewController - -@end - -NS_ASSUME_NONNULL_END diff --git a/ios/Classes/BottomSheetVC.m b/ios/Classes/BottomSheetVC.m deleted file mode 100755 index d68b692..0000000 --- a/ios/Classes/BottomSheetVC.m +++ /dev/null @@ -1,63 +0,0 @@ -// -// BottomSheetVC.m -// BottomSheetTutorial -// -// Created by Khoa Mai on 5/4/19. -// Copyright © 2019 Khoa Mai. All rights reserved. -// - -#import "BottomSheetVC.h" - -@interface BottomSheetVC () - -@end - -@implementation BottomSheetVC - -- (void)viewDidLoad { - [super viewDidLoad]; - UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(onPan:)]; - [self.view addGestureRecognizer:panGesture]; -} - --(void) onPan:(UIPanGestureRecognizer *) sender { - CGPoint translation = [sender translationInView:self.view]; - CGPoint velocity = [sender velocityInView:self.view]; - CGFloat y = CGRectGetMinY(self.view.frame); - if (y + translation.y >= self.view.frame.size.height * 0.7 && y + translation.y <= [[UIScreen mainScreen] bounds].size.height - 80) { - self.view.frame = CGRectMake(0, y + translation.y, self.view.frame.size.width, self.view.frame.size.height); - [sender setTranslation:CGPointZero inView:self.view]; - } - if (sender.state == UIGestureRecognizerStateEnded) { - double duration = velocity.y < 0 ? (y - self.view.frame.size.height * 0.7) / -velocity.y : ([[UIScreen mainScreen] bounds].size.height - 60) / velocity.y; - duration = duration > 1.3 ? 1.0 : duration; - [UIView animateWithDuration:duration delay:0.0 options:UIViewAnimationOptionAllowUserInteraction animations:^{ - if (velocity.y >= 0) { - self.view.frame = CGRectMake(0, [[UIScreen mainScreen] bounds].size.height - 60, self.view.frame.size.width, self.view.frame.size.height); - } else { - self.view.frame = CGRectMake(0, self.view.frame.size.height * 0.7, self.view.frame.size.width, self.view.frame.size.height); - } - } completion:nil]; - } -} - --(void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - [UIView animateWithDuration:0.3 animations:^{ - CGRect frame = self.view.frame; - CGFloat yComponent = [[UIScreen mainScreen] bounds].size.height - 60; - self.view.frame = CGRectMake(0, yComponent, frame.size.width, frame.size.height); - }]; -} - --(void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - [self prepareBackground]; -} - --(void) prepareBackground { - self.view.layer.cornerRadius = 20.0; - self.view.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner; -} - -@end diff --git a/ios/Classes/BottomSheetViewController.h b/ios/Classes/BottomSheetViewController.h new file mode 100644 index 0000000..f59db34 --- /dev/null +++ b/ios/Classes/BottomSheetViewController.h @@ -0,0 +1,72 @@ +// +// BottomSheetViewController.h +// navi-lite +// +// Created by Phineas.Huang on 2020/5/29. +// Copyright © 2020 Garmin. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +typedef enum Director { + up, + down, +}Director; + +typedef enum State { + partial, + expanded, + full, + dismiss +}State; +static State maxState = full; +static CGFloat maxPosition = 0; +static State minState = partial; +static CGFloat minPosition = 0; +static UIEdgeInsets insets; +static bool panEnabled = YES; +static bool panInit = NO; +static bool panFromScrollView = NO; + +static bool fullPositon = YES; +static bool mediumPosition = YES; +static bool smallPosition = YES; +static CGFloat lastScrollViewOffsetY = 0; +static CGFloat newSrollViewOffsetY = 0; +static CGFloat lastTranslation = 0; + + +static NSDictionary *userDetents; +static CGFloat fullViewYPosition = 0; +static CGFloat partialViewYPosition = 0; +static CGFloat expandedViewYPosition = 0; +static bool dismissModeOfSheet = NO; +static bool backgroundViewHidden = NO; +static UIColor *viewBackgroundColor = nil; +static UIColor *dimmedViewBackgroundColor = nil; +static NSString *largestUndimmedDetent = nil; +static NSString *startDetent = nil; +static NSString *detentString = nil; +@interface BottomSheetViewController : UIViewController +@property (assign, nonatomic) State lastStatus; +@property (assign, nonatomic) NSString *selectedDetentIdentifier; + +- (id)proxyOfBottomSheetController; +- (void)setProxyOfBottomSheetController:(id)args; +- (void)moveViewWithGesture:(UIPanGestureRecognizer *)recognizer; +- (void)panGesture:(UIPanGestureRecognizer *)recognizer; +- (void)moveView:(State)state; +- (State)state; +- (void)panRecognizerEnabled:(bool)enabled; +- (bool)panRecognizerState; +- (UIPanGestureRecognizer *)panRecognizer; +- (void)panRecognizerInit:(bool)enabled; +- (void)panFromScrollView:(bool)enabled; + +- (void)scrollView:(UIScrollView*)scrollview; +- (void)lastContentOffsetY:(CGFloat)contentOffsetY; +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/BottomSheetViewController.m b/ios/Classes/BottomSheetViewController.m new file mode 100644 index 0000000..aa28f14 --- /dev/null +++ b/ios/Classes/BottomSheetViewController.m @@ -0,0 +1,674 @@ +// +// BottomSheetViewController.m +// navi-lite +// +// Created by Phineas.Huang on 2020/5/29. +// Copyright © 2020 Garmin. All rights reserved. +// + +#import "BottomSheetViewController.h" +#import "TiBottomsheetcontrollerProxy.h" + + +@interface BottomSheetViewController () + + +@end + +@implementation BottomSheetViewController + + +#pragma mark Public APIs + +TiBottomsheetcontrollerProxy *myParentProxy; +UIScrollView *customSheetScrollView; +UIPanGestureRecognizer *thisGesture; +UIEdgeInsets safeAreaInset; + +-(id)proxyOfBottomSheetController +{ + return myParentProxy; +} +-(void)setProxyOfBottomSheetController:(id)args +{ + myParentProxy = args; +} + + + +#pragma mark - + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + [self setupData]; + [self setupGestureEvent]; + +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + + __weak __typeof(self)weakSelf = self; + + dispatch_async(dispatch_get_main_queue(), ^{ + + [UIView animateWithDuration:0.25 + delay:0.0 + options:UIViewAnimationOptionCurveEaseOut + animations:^{ + [myParentProxy backgroundView].backgroundColor = viewBackgroundColor; + //weakSelf.parentViewController.view.backgroundColor = viewBackgroundColor; + [weakSelf moveView:weakSelf.lastStatus]; + } completion:^(BOOL finished) { + }]; + }); + +} + +#pragma mark - + + + +- (void)setupData { + dismissModeOfSheet = NO; + backgroundViewHidden = YES; + viewBackgroundColor = [UIColor clearColor]; + dimmedViewBackgroundColor = [[TiUtils colorValue:@"#22000000"] _color]; + fullViewYPosition = 100; + partialViewYPosition = [UIScreen mainScreen].bounds.size.height - 130; + expandedViewYPosition = ceilf([UIScreen mainScreen].bounds.size.height / 2); + + safeAreaInset = UIEdgeInsetsZero; + UIViewController *topContainerController = [[[TiApp app] controller] topContainerController]; + + safeAreaInset = [[topContainerController hostingView] safeAreaInsets]; + + + maxPosition = fullViewYPosition; + maxState = full; + + minPosition = partialViewYPosition; + minState = partial; + + if ([myParentProxy valueForKey:@"startDetent"]){ + startDetent = [TiUtils stringValue:[myParentProxy valueForKey:@"startDetent"]]; + } + else { + startDetent = @"small"; + } + + if ([myParentProxy valueForKey:@"detents"]){ + userDetents = [myParentProxy valueForKey:@"detents"]; + + NSMutableArray *detentsOfController = [NSMutableArray arrayWithCapacity:2]; + + //[TiUtils boolValue:[self valueForKey:@"prefersEdgeAttachedInCompactHeight"] + + if ([TiUtils boolValue:[userDetents valueForKey:@"large"] def:YES]){ + maxPosition = fullViewYPosition; + maxState = full; + if (![TiUtils boolValue:[userDetents valueForKey:@"small"] def:YES] && ![TiUtils boolValue:[userDetents valueForKey:@"medium"] def:YES]){ + mediumPosition = NO; + smallPosition = NO; + + minPosition = fullViewYPosition; + minState = full; + startDetent = @"large"; + } + else { + if (![TiUtils boolValue:[userDetents valueForKey:@"small"] def:YES] && [TiUtils boolValue:[userDetents valueForKey:@"medium"] def:YES]){ + minPosition = expandedViewYPosition; + minState = expanded; + smallPosition = NO; + + if (![startDetent isEqual:@"medium"] && ![startDetent isEqual:@"large"]){ + startDetent = @"medium"; + } + } + else if ([TiUtils boolValue:[userDetents valueForKey:@"small"] def:YES] && ![TiUtils boolValue:[userDetents valueForKey:@"medium"] def:YES]){ + mediumPosition = NO; + + if ([startDetent isEqual:@"medium"] && ![startDetent isEqual:@"large"]){ + startDetent = @"small"; + } + } + } + } + else if ([TiUtils boolValue:[userDetents valueForKey:@"medium"] def:YES]){ + maxPosition = expandedViewYPosition; + maxState = expanded; + fullPositon = NO; + + if (![TiUtils boolValue:[userDetents valueForKey:@"small"] def:YES]){ + minPosition = expandedViewYPosition; + minState = expanded; + smallPosition = NO; + + if ([startDetent isEqual:@"small"] || [startDetent isEqual:@"large"]){ + startDetent = @"medium"; + } + } + else { + if ([startDetent isEqual:@"large"]){ + startDetent = @"medium"; + } + } + } + else if ([TiUtils boolValue:[userDetents valueForKey:@"small"] def:YES]){ + maxPosition = partialViewYPosition; + maxState = partial; + mediumPosition = NO; + fullPositon = NO; + + if ([startDetent isEqual:@"medium"] || [startDetent isEqual:@"large"]){ + startDetent = @"small"; + } + } + else { + maxPosition = fullViewYPosition; + maxState = full; + } + } + + if ([myParentProxy valueForKey:@"largestUndimmedDetentIdentifier"]){ + largestUndimmedDetent = [TiUtils stringValue:[myParentProxy valueForKey:@"largestUndimmedDetentIdentifier"]]; + } + else { + largestUndimmedDetent = @"small"; + } + + + + + + if ([startDetent isEqual: @"small"]){ + if ([TiUtils boolValue:[userDetents valueForKey:@"small"] def:YES]){ + self.lastStatus = partial; + + if (![largestUndimmedDetent isEqual: @"small"]){ + backgroundViewHidden = NO; + viewBackgroundColor = dimmedViewBackgroundColor; + } + } + else { + self.lastStatus = expanded; + + if (![largestUndimmedDetent isEqual: @"medium"]){ + backgroundViewHidden = NO; + viewBackgroundColor = dimmedViewBackgroundColor; + } + } + } + else if ([startDetent isEqual: @"medium"]){ + if ([TiUtils boolValue:[userDetents valueForKey:@"medium"] def:YES]){ + self.lastStatus = expanded; + if (![largestUndimmedDetent isEqual: @"medium"]){ + backgroundViewHidden = NO; + viewBackgroundColor = dimmedViewBackgroundColor; + } + } + else { + self.lastStatus = full; + if (![largestUndimmedDetent isEqual: @"full"]){ + backgroundViewHidden = NO; + viewBackgroundColor = dimmedViewBackgroundColor; + } + } + } + else if ([startDetent isEqual: @"large"]){ + if ([TiUtils boolValue:[userDetents valueForKey:@"large"] def:YES]){ + self.lastStatus = full; + if (![largestUndimmedDetent isEqual: @"full"]){ + backgroundViewHidden = NO; + viewBackgroundColor = dimmedViewBackgroundColor; + } + } + else { + self.lastStatus = expanded; + if (![largestUndimmedDetent isEqual: @"medium"]){ + backgroundViewHidden = NO; + viewBackgroundColor = dimmedViewBackgroundColor; + } + } + } + else { + self.lastStatus = expanded; + if ([largestUndimmedDetent isEqual: @"small"]){ + backgroundViewHidden = NO; + viewBackgroundColor = dimmedViewBackgroundColor; + } + } + [myParentProxy backgroundView].hidden = backgroundViewHidden; + + + if (customSheetScrollView){ + CGFloat width = self.view.frame.size.width; + CGFloat height = self.view.frame.size.height; + CGFloat bottomIntent = safeAreaInset.bottom; + CGFloat topInset = customSheetScrollView.contentInset.top; + + if (self.lastStatus == partial) { + bottomIntent = (((height) - 136) - bottomIntent); + } + else if (self.lastStatus == expanded) { + bottomIntent = (((height)/2) - bottomIntent) - 6; + } + else { + bottomIntent = bottomIntent + 24; + } + insets = UIEdgeInsetsMake(topInset, 0, bottomIntent, 0); + [customSheetScrollView setContentInset:insets]; + [customSheetScrollView setScrollIndicatorInsets:insets]; + } + + +} + +#pragma mark - + +- (State)state { + return self.lastStatus; +} +- (void)panFromScrollView:(bool)enabled { + panFromScrollView = enabled; +} +- (void)panRecognizerEnabled:(bool)enabled { + panEnabled = enabled; +} +- (bool)panRecognizerState { + return panEnabled; +} + +- (void)panRecognizerInit:(bool)enabled { + panInit = enabled; +} +- (UIPanGestureRecognizer *)panRecognizer { + return thisGesture; +} + + +- (void)setupGestureEvent { + UIPanGestureRecognizer *gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)]; + [self.view addGestureRecognizer:gesture]; + thisGesture = gesture; + [self roundViews]; +} + +- (void)moveView:(State)state { + CGFloat yPosition = fullViewYPosition; + const CGFloat width = self.view.frame.size.width; + const CGFloat height = self.view.frame.size.height; + CGFloat bottomIntent = safeAreaInset.bottom; + + if (dismissModeOfSheet == NO){ + if (state == partial) { + yPosition = partialViewYPosition; + bottomIntent = (((height) - 136) - bottomIntent); + + } else if (state == expanded) { + yPosition = expandedViewYPosition; + bottomIntent = (((height)/2) - bottomIntent) - 6; + } + else { + // bottomIntent = 130; + // bottomIntent = bottomIntent - 100; + // bottomIntent = bottomIntent + 24; + bottomIntent = bottomIntent + 24; + + } + } + else { + yPosition = [UIScreen mainScreen].bounds.size.height; + // bottomIntent = bottomIntent - 100; + // bottomIntent = bottomIntent + 24; + bottomIntent = bottomIntent + 24; + + } + + CGRect rect = CGRectMake(0 , yPosition, width, height); + + + // NSLog(@"before insets %f",bottomIntent); + // NSLog(@"customSheetScrollView %@",customSheetScrollView); + + CGFloat topInset = customSheetScrollView.contentInset.top; + + if (customSheetScrollView){ + // NSLog(@"intents %f",bottomIntent); + + insets = UIEdgeInsetsMake(topInset, 0, bottomIntent, 0); + [customSheetScrollView setContentInset:insets]; + [customSheetScrollView setScrollIndicatorInsets:insets]; + } + + self.view.frame = rect; +} + +- (void)moveViewWithGesture:(UIPanGestureRecognizer *)recognizer { + CGPoint translation = [recognizer translationInView:self.view]; + + if(panInit == YES){ + panInit = NO; + translation.y = 0; + } + + // NSLog(@"sheet translation %f", translation.y); + + +// if (translation.y > 1){ +// translation.y = 1; +// } + + const CGFloat minY = self.view.frame.origin.y; + dismissModeOfSheet = NO; + + if ((minY + translation.y >= maxPosition)) { + const CGFloat width = self.view.frame.size.width; + const CGFloat height = self.view.frame.size.height; + const CGRect rect = CGRectMake(0 , minY + translation.y, width, height); + self.view.frame = rect; + [recognizer setTranslation:CGPointZero inView:self.view]; + if (minY + translation.y > minPosition) { + dismissModeOfSheet = YES; + } + else { + dismissModeOfSheet = NO; + } + } +} + +- (void)roundViews { + self.view.clipsToBounds = NO; +} + + +- (void)scrollView:(UIScrollView*)scrollview { + customSheetScrollView = scrollview; +} +- (void)lastContentOffsetY:(CGFloat)contentOffsetY{ + newSrollViewOffsetY = contentOffsetY; +} + +- (void)panGesture:(UIPanGestureRecognizer *)recognizer { + + CGPoint translation = [recognizer translationInView:self.view]; + +// NSLog(@"panEnabled %d",panEnabled); +// +// NSLog(@"translation %f",translation.y); +// NSLog(@"lastTranslation %f",lastTranslation); +// +// NSLog(@"newSrollViewOffsetY %f",newSrollViewOffsetY); +// NSLog(@"lastScrollViewOffsetY %f",lastScrollViewOffsetY); +// NSLog(@"customSheetScrollView.isDragging %d",customSheetScrollView.isDragging); +// +// +// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ +// +// }); + + + if (customSheetScrollView != nil){ + + + if (panFromScrollView == YES){ + // NSLog(@"---------------- panFromScrollView"); + + if (panEnabled == YES && customSheetScrollView.isDragging == NO){ + // NSLog(@"---------------- panFromScrollView SKIP"); + + return; + } + + } + else { + // NSLog(@"-------------- NO panFromScrollView"); + + } + + if (lastScrollViewOffsetY != newSrollViewOffsetY && customSheetScrollView.isDragging != NO){ + // NSLog(@"lastScrollViewOffsetY != newSrollViewOffsetY && dragging != NO"); + lastScrollViewOffsetY = newSrollViewOffsetY; + lastTranslation = translation.y; + } + else { + + if ((panEnabled == YES && lastTranslation == newSrollViewOffsetY) || (panEnabled == YES && translation.y == 0)){ + + if ((panEnabled == YES && lastScrollViewOffsetY == newSrollViewOffsetY)){ + lastTranslation = translation.y; + lastScrollViewOffsetY = newSrollViewOffsetY; + // NSLog(@"++++++++++++++ NO SKIP"); + + } + else { + if (customSheetScrollView.isDragging == NO){ + // NSLog(@"SKIP"); + lastTranslation = translation.y; + lastScrollViewOffsetY = newSrollViewOffsetY; + return; + } + // NSLog(@"++++++++++++++ NO SKIP AFTER"); + + lastTranslation = translation.y; + lastScrollViewOffsetY = newSrollViewOffsetY; + } + } + + lastTranslation = translation.y; + lastScrollViewOffsetY = newSrollViewOffsetY; + } + if (panEnabled == NO){ + lastTranslation = translation.y; + + lastScrollViewOffsetY = newSrollViewOffsetY; + return; + } + lastTranslation = translation.y; + + lastScrollViewOffsetY = newSrollViewOffsetY; + } + + + [self moveViewWithGesture:recognizer]; + + if (recognizer.state != UIGestureRecognizerStateEnded) { + return; + } + + __weak __typeof(self)weakSelf = self; + + + if (dismissModeOfSheet == YES){ + [myParentProxy sendEvent:@"dismiss"]; + return; + } + else { + // dispatch_async(dispatch_get_main_queue(), ^{ + + [UIView animateKeyframesWithDuration:0.25 + delay:0.0 + options:UIViewKeyframeAnimationOptionAllowUserInteraction + animations:^{ + const Director director = [recognizer velocityInView:weakSelf.view].y >= 0 ? down: up; + State state = weakSelf.lastStatus; + + if (weakSelf.lastStatus == partial && director == up) { + if (mediumPosition){ + state = expanded; + } + else if (fullPositon){ + state = full; + } + else { + if (smallPosition){ + state = partial; + } + else { + state = partial; + } + } + + } else if (weakSelf.lastStatus == expanded && director == up) { + if (maxState == full){ + state = full; + } + else { + state = expanded; + } + } + + if (weakSelf.lastStatus == full && director == down) { + if (mediumPosition){ + state = expanded; + } + else { + state = partial; + } + + } else if (weakSelf.lastStatus == expanded && director == down) { + if (smallPosition){ + state = partial; + } + else { + state = expanded; + } + } + + // handle + if (recognizer.view) { + if (state == expanded) { + CGFloat endLocation = recognizer.view.frame.origin.y; + if (endLocation > expandedViewYPosition && + director == down && smallPosition) { + state = partial; + + } else if (endLocation < expandedViewYPosition && + director == up && fullPositon) { + if (maxPosition == fullViewYPosition){ + state = full; + } + else { + state = expanded; + } + } + + } else if (state == partial && + weakSelf.lastStatus == partial) { + CGFloat endLocation = recognizer.view.frame.origin.y; + if (endLocation < expandedViewYPosition && mediumPosition) { + state = expanded; + } + else { + if (fullPositon){ + state = full; + } + else { + state = partial; + } + } + } + } + + weakSelf.lastStatus = state; + [weakSelf moveView:state]; + + + if (self.lastStatus == expanded){ + detentString = @"medium"; + } + else if (self.lastStatus == full){ + detentString = @"large"; + } + else { + if (dismissModeOfSheet == false){ + detentString = @"small"; + } + else { + detentString = @"dismiss"; + } + } + + if (dismissModeOfSheet == NO){ + + + if (weakSelf.lastStatus == expanded){ + if ([largestUndimmedDetent isEqual: @"medium"]){ + backgroundViewHidden = YES; + viewBackgroundColor = [UIColor clearColor]; + } + else { + if ([largestUndimmedDetent isEqual: @"small"]){ + backgroundViewHidden = NO; + viewBackgroundColor = dimmedViewBackgroundColor; + } + else { + backgroundViewHidden = YES; + viewBackgroundColor = [UIColor clearColor]; + } + } + } + else if (weakSelf.lastStatus == full){ + if ([largestUndimmedDetent isEqual: @"full"]){ + backgroundViewHidden = YES; + viewBackgroundColor = [UIColor clearColor]; + } + else { + backgroundViewHidden = NO; + viewBackgroundColor = dimmedViewBackgroundColor; + } + } + else { + // partial + if ([largestUndimmedDetent isEqual: @"small"] || [largestUndimmedDetent isEqual: @"medium"] || [largestUndimmedDetent isEqual: @"full"]){ + backgroundViewHidden = YES; + viewBackgroundColor = [UIColor clearColor]; + } + else { + backgroundViewHidden = NO; + viewBackgroundColor = dimmedViewBackgroundColor; + } + } + + + dispatch_async(dispatch_get_main_queue(), ^{ + if (backgroundViewHidden == NO){ + [myParentProxy backgroundView].hidden = backgroundViewHidden; + } + + [UIView animateWithDuration:0.25 + delay:0.0 + options:UIViewAnimationOptionCurveEaseOut + animations:^{ + [myParentProxy backgroundView].backgroundColor = viewBackgroundColor; + } completion:^(BOOL finished) { + if (backgroundViewHidden == YES){ + [myParentProxy backgroundView].hidden = backgroundViewHidden; + } + if (customSheetScrollView != nil){ + customSheetScrollView.panGestureRecognizer.enabled = YES; + } + }]; + }); + + + } + + id detentID = detentString; + + [myParentProxy sendEvent:detentID]; + dismissModeOfSheet = NO; + + + } completion:^(BOOL finished) { + + + }]; + // }); + } + + +} + +@end diff --git a/ios/Classes/TiBottomsheetcontrollerModule.h b/ios/Classes/TiBottomsheetcontrollerModule.h index acf38c0..c2826bd 100755 --- a/ios/Classes/TiBottomsheetcontrollerModule.h +++ b/ios/Classes/TiBottomsheetcontrollerModule.h @@ -6,7 +6,8 @@ */ #import "TiModule.h" +#import -@interface TiBottomsheetcontrollerModule : TiModule - +@interface TiBottomsheetcontrollerModule : TiModule +- (void)cleanup; @end diff --git a/ios/Classes/TiBottomsheetcontrollerModule.m b/ios/Classes/TiBottomsheetcontrollerModule.m index eca3a2a..58ca2a5 100755 --- a/ios/Classes/TiBottomsheetcontrollerModule.m +++ b/ios/Classes/TiBottomsheetcontrollerModule.m @@ -6,13 +6,16 @@ */ #import "TiBottomsheetcontrollerModule.h" -#import "TiBottomsheetcontrollerProxy.h" #import "TiBase.h" #import "TiHost.h" #import "TiUtils.h" +#import "TiBottomsheetcontrollerProxy.h" @implementation TiBottomsheetcontrollerModule + +id myBottomSheet = nil; + #pragma mark Internal // This is generated for your module, please do not change it @@ -27,19 +30,51 @@ - (NSString *)moduleId return @"ti.bottomsheetcontroller"; } -#pragma mark Public API's +#pragma mark Lifecycle + +- (void)startup +{ + // This method is called when the module is first loaded + // You *must* call the superclass + [super startup]; + NSLog(@"[DEBUG] %@ loaded", self); +} + + +-(void)shutdown:(id)sender +{ + // this method is called when the module is being unloaded + // typically this is during shutdown. make sure you don't do too + // much processing here or the app will be quit forceably + + // you *must* call the superclass + [super shutdown:sender]; +} + +#pragma mark Public API +- (void)cleanup +{ + myBottomSheet = nil; + // NSLog(@"cleanup"); +} + +- (id)createBottomSheet:(id)args{ + // NSLog(@"createBottomSheet "); + + // [self performSelector:@selector(updateContentViewWithSafeAreaInsets:) withObject:insetsValue afterDelay:.05]; -- (id)createBottomSheet:(id)args -{ - if ([TiUtils isIOSVersionOrGreater:@"15.0"] || [TiUtils isMacOS] ) { - if (@available(iOS 15, macCatalyst 15, *)) { - return [[TiBottomsheetcontrollerProxy alloc] _initWithPageContext:[self executionContext] args:args]; - } + if (myBottomSheet == nil){ + myBottomSheet = [[TiBottomsheetcontrollerProxy alloc] _initWithPageContext:[self executionContext] args:args]; + [myBottomSheet bottomSheetModule:self]; + return myBottomSheet; } else { - [self throwException:@"this API is not available on non iOS 15+" subreason:nil location:CODELOCATION]; - return nil; + // NSLog(@"is open "); + // [self throwException:@"BottomSheet is already presented" subreason:nil location:CODELOCATION]; + //[myBottomSheet hide:nil]; + return myBottomSheet; } + } @end diff --git a/ios/Classes/TiBottomsheetcontrollerProxy.h b/ios/Classes/TiBottomsheetcontrollerProxy.h index af7a11b..cded643 100755 --- a/ios/Classes/TiBottomsheetcontrollerProxy.h +++ b/ios/Classes/TiBottomsheetcontrollerProxy.h @@ -6,21 +6,43 @@ * * WARNING: This is generated code. Modify at your own risk and without support. */ +#define USE_TI_UINAVIGATIONWINDOW #import #import +#import #import -#import "BottomSheetVC.h" +#import "TiUINavigationWindowProxy.h" +#import "TiUINavigationWindowInternal.h" +@interface ContentScrollView : UIScrollView -@interface TiBottomsheetcontrollerProxy : TiProxy { +@property (assign, nonatomic) bool dismissing; + +@end + + +@interface TiBottomsheetcontrollerProxy : TiProxy { + pthread_rwlock_t listenerLockSheet; + NSMutableDictionary *listenersSheet; + UIEdgeInsets insets; + UIView *containerView; + ContentScrollView *scrollView; + BOOL nonSystemSheetShouldScroll; + BOOL eventFired; + BOOL useNavController; + BOOL defaultsToNonSystemSheet; CGSize TiBottomSheetContentSize; UIViewController *viewController; + TiUINavigationWindowProxy *centerProxy; UISheetPresentationController *bottomSheet; NSDictionary *userDetents; - + NSString *detentStatus; + NSString *lastDetentStatus; + UIView *backgroundView; @private TiViewProxy *contentViewProxy; + TiViewProxy *closeButtonProxy; CGRect popoverRect; BOOL animated; BOOL popoverInitialized; @@ -28,10 +50,20 @@ NSCondition *bottomSheetclosingCondition; TiDimension poWidth; TiDimension poHeight; + TiDimension poBWidth; + TiDimension poBHeight; BOOL deviceRotated; } @property(nonatomic, copy) NSArray * _Nullable detents; @property(nonatomic, copy, nullable) UISheetPresentationControllerDetentIdentifier largestUndimmedDetentIdentifier; +- (void)sendEvent:(id)args; +- (UIView*)backgroundView; +- (UIScrollView*)scrollView; +- (TiBottomsheetcontrollerProxy*)bottomSheet; +- (void)bottomSheetModule:(id)args; + @end +@interface myViewController : UIViewController +@end diff --git a/ios/Classes/TiBottomsheetcontrollerProxy.m b/ios/Classes/TiBottomsheetcontrollerProxy.m index 0e5fea5..1db980c 100755 --- a/ios/Classes/TiBottomsheetcontrollerProxy.m +++ b/ios/Classes/TiBottomsheetcontrollerProxy.m @@ -15,25 +15,33 @@ #import #import #import - -API_AVAILABLE(ios(15), macosx(12)) +#import "BottomSheetViewController.h" +#import "TiBottomsheetcontrollerModule.h" +#import "TouchDelayGestureRecognizer.h" TiBottomsheetcontrollerProxy *currentTiBottomSheet; +BottomSheetViewController *customBottomSheet; +TiBottomsheetcontrollerModule *bottomSheetModule; +UIView *closeButtonView = nil; @implementation TiBottomsheetcontrollerProxy - #pragma mark Setup - (id)init { - if (self = [super init]) { - bottomSheetclosingCondition = [[NSCondition alloc] init]; - poWidth = TiDimensionUndefined; - poHeight = TiDimensionUndefined; - } - - return self; + if (self = [super init]) { + bottomSheetclosingCondition = [[NSCondition alloc] init]; + poWidth = TiDimensionUndefined; + poHeight = TiDimensionUndefined; + poBWidth = TiDimensionUndefined; + poBHeight = TiDimensionUndefined; + // NSLog(@"self %@",self); + nonSystemSheetShouldScroll = NO; + defaultsToNonSystemSheet = YES; + } + + return self; } - (void)dealloc @@ -51,6 +59,7 @@ - (void)dealloc #if !TARGET_OS_MACCATALYST bottomSheet.delegate = nil; #endif + RELEASE_TO_NIL(customBottomSheet); RELEASE_TO_NIL(bottomSheet); } @@ -60,109 +69,426 @@ - (NSString *)apiName return @"Ti.UI.BottomSheetController"; } -#pragma mark Public Constants - (NSString *)selectedDetentIdentifier { - if (bottomSheet.selectedDetentIdentifier == UISheetPresentationControllerDetentIdentifierMedium){ - return @"medium"; - } - else if (bottomSheet.selectedDetentIdentifier == UISheetPresentationControllerDetentIdentifierLarge){ - return @"large"; + if (defaultsToNonSystemSheet == NO){ + if (bottomSheet.selectedDetentIdentifier == UISheetPresentationControllerDetentIdentifierMedium){ + return @"medium"; + } + else if (bottomSheet.selectedDetentIdentifier == UISheetPresentationControllerDetentIdentifierLarge){ + return @"large"; + } + else { + return @"none"; + } } else { - return @"none"; + return customBottomSheet.selectedDetentIdentifier; } + } +- (void)changeCurrentDetent:(id)value +{ + ENSURE_ARG_COUNT(value, 1); + NSString *identifier = [TiUtils stringValue:[value objectAtIndex:0]]; + + if (defaultsToNonSystemSheet == NO){ + + UISheetPresentationControllerDetentIdentifier newDetent = bottomSheet.selectedDetentIdentifier; -- (void)setContentView:(id)value + if ([identifier isEqual: @"large"] && ([bottomSheet.detents containsObject:[UISheetPresentationControllerDetent largeDetent]])){ + newDetent = UISheetPresentationControllerDetentIdentifierLarge; + } + else if ([identifier isEqual: @"medium"] && ([bottomSheet.detents containsObject:[UISheetPresentationControllerDetent mediumDetent]])){ + newDetent = UISheetPresentationControllerDetentIdentifierMedium; + } + [bottomSheet animateChanges:^{ + bottomSheet.selectedDetentIdentifier = newDetent; + }]; + } +} + +#pragma mark Public Constants + + +- (void)setLargestUndimmedDetentIdentifier:(id)value +{ + if ([[TiUtils stringValue:value] isEqual: @"large"]){ + _largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge; + if (bottomSheet != nil){ + bottomSheet.largestUndimmedDetentIdentifier = _largestUndimmedDetentIdentifier; + } + } + else if ([[TiUtils stringValue:value] isEqual: @"medium"]){ + _largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierMedium; + if (bottomSheet != nil){ + bottomSheet.largestUndimmedDetentIdentifier = _largestUndimmedDetentIdentifier; + } + } +} + + + +- (void)setCloseButton:(id)value { - if (popoverInitialized) { - DebugLog(@"[ERROR] Changing contentView when the popover is showing is not supported"); - return; - } ENSURE_SINGLE_ARG(value, TiViewProxy); + // NSLog(@"set closeButton "); + + if (closeButtonProxy != nil) { + // NSLog(@"release closeButtonproxy "); + + RELEASE_TO_NIL(closeButtonProxy); + } + // NSLog(@"closeButton "); + + closeButtonProxy = [(TiViewProxy *)value retain]; + [self replaceValue:closeButtonProxy forKey:@"closeButton" notification:NO]; + + // + +} +- (void)setNonSystemSheetShouldScroll:(id)value +{ + nonSystemSheetShouldScroll = [TiUtils boolValue:value]; +} + +- (void)setNonSystemSheet:(id)value +{ + if (@available(iOS 15, macCatalyst 15, *)) { + defaultsToNonSystemSheet = [TiUtils boolValue:value]; + } + else { + defaultsToNonSystemSheet = YES; + } +} + + +- (void)setContentView:(id)value +{ + ENSURE_SINGLE_ARG(value, TiViewProxy); if (contentViewProxy != nil) { - RELEASE_TO_NIL(contentViewProxy); + RELEASE_TO_NIL(contentViewProxy); } contentViewProxy = [(TiViewProxy *)value retain]; - [self replaceValue:contentViewProxy forKey:@"contentView" notification:NO]; + + + if (defaultsToNonSystemSheet == NO){ + // NSLog(@"nonSystemSheet == false "); + [contentViewProxy replaceValue:[NSNumber numberWithFloat:24] forKey:@"top" notification:NO]; + } + + [self replaceValue:contentViewProxy forKey:@"contentView" notification:NO]; + } + +- (void)sendEvent:(id)args +{ + //NSLog(@"sendEvent"); + + detentStatus = [TiUtils stringValue:args]; + + if ([detentStatus isEqual:@"dismiss"]){ + + // NSLog(@"sendEvent dismiss"); + if (isDismissing == NO){ + isDismissing = YES; + [self hide:nil]; + } + } + else { + if (lastDetentStatus != detentStatus){ + NSMutableDictionary * event = [NSMutableDictionary dictionary]; + customBottomSheet.selectedDetentIdentifier = detentStatus; + [event setValue:detentStatus + forKey:@"selectedDetentIdentifier"]; + + [self fireEvent:@"detentChange" withObject:event]; + + + + // NSLog(@"sendEvent %@",[TiUtils stringValue:args]); + } + if (scrollView != nil){ + // scrollView.scrollEnabled = YES; + // scrollView.userInteractionEnabled = NO; + + // scrollView.panGestureRecognizer.enabled = YES; + scrollView.dismissing = NO; + // [customBottomSheet lastContentOffsetY:-1]; + // scrollView.panGestureRecognizer.enabled = YES; + [customBottomSheet panFromScrollView:NO]; + + [customBottomSheet panRecognizerEnabled:YES]; + // scrollView.panGestureRecognizer.enabled = YES; + + } + } + lastDetentStatus = detentStatus; +} + + + + #pragma mark Public Methods +- (void)addEventListener:(NSArray *)args +{ + NSString *type = [args objectAtIndex:0]; + + if (![self _hasListeners:@"closed"] && [type isEqual:@"closed"]) { + // NSLog(@"BottomSheet addEventListener"); + + [super addEventListener:args]; + } + if (![self _hasListeners:@"opened"] && [type isEqual:@"opened"]) { + // NSLog(@"BottomSheet addEventListener"); + + [super addEventListener:args]; + } + if (![self _hasListeners:@"dismissing"] && [type isEqual:@"dismissing"]) { + // NSLog(@"BottomSheet addEventListener"); + + [super addEventListener:args]; + } + if (![self _hasListeners:@"detentChange"] && [type isEqual:@"detentChange"]) { + // NSLog(@"BottomSheet addEventListener"); + + [super addEventListener:args]; + } + +} - (void)show:(id)args { + ENSURE_SINGLE_ARG_OR_NIL(args, NSDictionary); + // NSLog(@"BottomSheet show"); - if (contentViewProxy == nil) { - DebugLog(@"[ERROR] Popover presentation without contentView property set is no longer supported. Ignoring call") return; - } - - ENSURE_SINGLE_ARG_OR_NIL(args, NSDictionary); - [self rememberSelf]; - [self retain]; - - animated = [TiUtils boolValue:@"animated" properties:args def:YES]; + // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + + // if (isDismissing == NO){ + - popoverInitialized = YES; + + if (popoverInitialized == NO) { + // NSLog(@"!popoverInitialized"); + eventFired = NO; + + if (contentViewProxy == nil) { + NSLog(@"[ERROR] BottomSheet no contentView set - Ignoring call") return; + } + + + [self rememberSelf]; + [self retain]; + + animated = [TiUtils boolValue:@"animated" properties:args def:YES]; + + + TiThreadPerformOnMainThread( + ^{ + [self initAndShowSheetController]; + isDismissing = NO; + popoverInitialized = YES; + }, + YES); + } + else { + + NSLog(@"BottomSheet is showing. Ignoring call") return; + +// TiThreadPerformOnMainThread( +// ^{ +// [currentTiBottomSheet sendEvent:@"dismiss"]; +// }, +// YES); + + } + // } + + // }); - TiThreadPerformOnMainThread( - ^{ - [self initAndShowSheetController]; - }, - YES); } - (void)hide:(id)args { - if (!popoverInitialized) { - DebugLog(@"Popover is not showing. Ignoring call") return; - } - - ENSURE_SINGLE_ARG_OR_NIL(args, NSDictionary); + //NSLog(@"BottomSheet hide"); + + if (popoverInitialized == NO) { + NSLog(@"BottomSheet is not showing. Ignoring call") return; + } + TiThreadPerformOnMainThread( ^{ - [self->contentViewProxy windowWillClose]; - - self->animated = [TiUtils boolValue:@"animated" properties:args def:NO]; - [[self viewController] dismissViewControllerAnimated:self->animated - completion:^{ - - - - [self fireEvent:@"closed" withObject:nil]; - //[self cleanup]; - }]; + if (defaultsToNonSystemSheet == NO){ + [self->contentViewProxy windowWillClose]; + + self->animated = [TiUtils boolValue:@"animated" properties:args def:YES]; + + [[self viewController] dismissViewControllerAnimated:self->animated + completion:^{ + // NSLog(@"BottomSheet closed iOS15+"); + if (eventFired == NO){ + eventFired = YES; + + // NSLog(@"BottomSheet before closed fired"); + + if ([self _hasListeners:@"closed"]) { + [self fireEvent:@"closed" withObject:nil]; + } + + // NSLog(@"BottomSheet closed fired"); + + [bottomSheetModule cleanup]; + popoverInitialized = NO; + + bottomSheet = nil; + viewController = nil; + contentViewProxy = nil; + centerProxy = nil; + closeButtonView = nil; + currentTiBottomSheet = nil; + } + + //[self cleanup]; + }]; + + } + else { + + if (eventFired == NO){ + eventFired = YES; + // NSLog(@"BottomSheet closed iOS < 15+"); + [self->contentViewProxy windowWillClose]; + + // + + + UIColor *viewBackgroundColor = [UIColor clearColor]; + + + + [UIView animateWithDuration:0.25 + delay:0.0 + options:UIViewAnimationOptionCurveEaseOut + animations:^{ + backgroundView.backgroundColor = viewBackgroundColor; + CGFloat width = customBottomSheet.view.frame.size.width; + CGFloat height = customBottomSheet.view.frame.size.height; + CGRect rect = CGRectMake(0 , [UIScreen mainScreen].bounds.size.height, width, height); + customBottomSheet.view.frame = rect; + } completion:^(BOOL finished) { + + if (finished){ + + // NSLog(@"BottomSheet before closed fired"); + + if ([self _hasListeners:@"closed"]) { + [self fireEvent:@"closed" withObject:nil]; + // NSLog(@"BottomSheet closed fired"); + } + + if (useNavController) { + [centerProxy windowWillClose]; + [centerProxy close:nil]; + [centerProxy windowDidClose]; + centerProxy = nil; + } + [backgroundView removeFromSuperview]; + [customBottomSheet.view removeFromSuperview]; + // [[TiApp app] hideModalController:viewController animated:NO]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + currentTiBottomSheet = nil; + + + [self forgetSelf]; + [self release]; + // [viewController.view removeFromSuperview]; + [bottomSheetModule cleanup]; + scrollView = nil; + popoverInitialized = NO; + contentViewProxy = nil; + customBottomSheet = nil; + backgroundView = nil; + viewController = nil; + closeButtonView = nil; + + // [customBottomSheet willMoveToParentViewController:viewController]; + // [customBottomSheet.view removeFromSuperview]; + // [customBottomSheet removeFromParentViewController]; + + + + + } + + + }]; + + + } + else { + // NSLog(@"BottomSheet closed Event already fired"); + } + } + + // [self dealloc]; }, - NO); + YES); + + + // NSLog(@"BottomSheet hide done"); + } +- (TiBottomsheetcontrollerProxy*)bottomSheet +{ + return bottomSheet; +} +- (void)bottomSheetModule:(id)args +{ + bottomSheetModule = args; +} +- (UIView *)backgroundView +{ + return backgroundView; +} + +- (UIScrollView *)scrollView +{ + return scrollView; +} + -#pragma mark Internal Methods - (UIViewController *)viewController { if (viewController == nil) { if ([contentViewProxy isKindOfClass:[TiWindowProxy class]]) { [(TiWindowProxy *)contentViewProxy setIsManaged:YES]; viewController = [[(TiWindowProxy *)contentViewProxy hostingController] retain]; - [viewController.view addObserver:self forKeyPath:@"safeAreaInsets" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; + //[viewController.view addObserver:self forKeyPath:@"safeAreaInsets" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; } else { + // + viewController = [[TiViewController alloc] initWithViewProxy:contentViewProxy]; - [viewController.view addObserver:self forKeyPath:@"safeAreaInsets" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; + // [viewController.view addObserver:self forKeyPath:@"safeAreaInsets" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; } } - viewController.view.clipsToBounds = YES; + viewController.view.clipsToBounds = NO; return viewController; } +#pragma mark Internal Methods + + - (void)cleanup { currentTiBottomSheet = nil; @@ -224,6 +550,8 @@ - (void)initAndShowSheetController currentTiBottomSheet = self; [contentViewProxy setProxyObserver:self]; if ([contentViewProxy isKindOfClass:[TiWindowProxy class]]) { + useNavController = YES; + UIView *topWindowView = [[[TiApp app] controller] topWindowProxyView]; if ([topWindowView isKindOfClass:[TiUIView class]]) { TiViewProxy *theProxy = (TiViewProxy *)[(TiUIView *)topWindowView proxy]; @@ -234,6 +562,20 @@ - (void)initAndShowSheetController [(TiWindowProxy *)contentViewProxy setIsManaged:YES]; [(TiWindowProxy *)contentViewProxy open:nil]; [(TiWindowProxy *)contentViewProxy gainFocus]; + + if (closeButtonProxy){ + [closeButtonProxy windowWillOpen]; + [closeButtonProxy reposition]; + [closeButtonProxy layoutChildrenIfNeeded]; + + CGFloat width = [closeButtonProxy autoWidthForSize:CGSizeMake(1000, 1000)]; + CGFloat height = [closeButtonProxy autoHeightForSize:CGSizeMake(width, 0)]; + CGRect closeButtonViewFrame = CGRectMake( 0 , 0, width, height); + closeButtonView = [[UIView alloc] initWithFrame:closeButtonViewFrame]; + // NSLog(@"closeButton %f x %f",width,height); + } + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self updatePopoverNow]; [contentViewProxy windowDidOpen]; @@ -241,8 +583,25 @@ - (void)initAndShowSheetController } else { [contentViewProxy windowWillOpen]; [contentViewProxy reposition]; - //[self updateContentSize]; - // NSLog(@"before updatePopoverNow "); + // NSLog(@"closeButtonProxy %@",closeButtonProxy); + + CGSize closeButtonSize = [self buttonSize]; + + if (closeButtonProxy){ + [closeButtonProxy windowWillOpen]; + [closeButtonProxy reposition]; + [closeButtonProxy layoutChildrenIfNeeded]; + + CGFloat width = [closeButtonProxy autoWidthForSize:CGSizeMake(1000, 1000)]; + CGFloat height = [closeButtonProxy autoHeightForSize:CGSizeMake(width, 0)]; + CGRect closeButtonViewFrame = CGRectMake( 0 , 0, width, height); + closeButtonView = [[UIView alloc] initWithFrame:closeButtonViewFrame]; + + // NSLog(@"closeButton %f x %f",width,height); + } + [self updateContentSize]; + + // NSLog(@"before updatePopoverNow "); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self updatePopoverNow]; @@ -252,6 +611,30 @@ - (void)initAndShowSheetController } + +- (CGSize)buttonSize +{ +#ifndef TI_USE_AUTOLAYOUT + CGSize screenSize = [[UIScreen mainScreen] bounds].size; + if (poBWidth.type != TiDimensionTypeUndefined) { + [closeButtonProxy layoutProperties]->width.type = poBWidth.type; + [closeButtonProxy layoutProperties]->width.value = poBWidth.value; + poBWidth = TiDimensionUndefined; + } + + if (poBHeight.type != TiDimensionTypeUndefined) { + [closeButtonProxy layoutProperties]->height.type = poBHeight.type; + [closeButtonProxy layoutProperties]->height.value = poBHeight.value; + poBHeight = TiDimensionUndefined; + } + + return SizeConstraintViewWithSizeAddingResizing([closeButtonProxy layoutProperties], closeButtonProxy, screenSize, NULL); +#else + return CGSizeZero; +#endif +} + + - (CGSize)contentSize { #ifndef TI_USE_AUTOLAYOUT @@ -268,7 +651,15 @@ - (CGSize)contentSize poHeight = TiDimensionUndefined; } + if (defaultsToNonSystemSheet == NO && useNavController == NO){ + [contentViewProxy layoutProperties]->top.type = TiDimensionTypeDip; + [contentViewProxy layoutProperties]->top.value = 24; + } + TiBottomSheetContentSize = SizeConstraintViewWithSizeAddingResizing([contentViewProxy layoutProperties], contentViewProxy, screenSize, NULL); + + // TiBottomSheetContentSize.height = TiBottomSheetContentSize.height + 24; + return TiBottomSheetContentSize; #else return CGSizeZero; @@ -277,102 +668,414 @@ - (CGSize)contentSize - (void)updateContentSize { - // NSLog(@"updateContentSize "); +// NSLog(@"updateContentSize "); + CGSize newSize = [self contentSize]; + + if (defaultsToNonSystemSheet == NO){ + [[self viewController] setPreferredContentSize:newSize]; + } + [contentViewProxy reposition]; - CGSize newSize = [self contentSize]; - [[self viewController] setPreferredContentSize:newSize]; - [contentViewProxy reposition]; } - (void)updatePopoverNow { - // NSLog(@"updatePopoverNow "); + // NSLog(@"updatePopoverNow "); + if (![self valueForKey:@"backgroundColor"] || [[self valueForKey:@"backgroundColor"] isEqual:@"transparent"]){ + [self replaceValue:[TiUtils hexColorValue:[UIColor lightGrayColor]] forKey:@"backgroundColor" notification:YES]; + } - UIViewController *theController = [self viewController]; + if (defaultsToNonSystemSheet == NO){ + + UIViewController *theController = [self viewController]; + + bottomSheet = [theController sheetPresentationController]; + + bottomSheet.delegate = self; + + if ([self valueForKey:@"largestUndimmedDetentIdentifier"]){ + if ([[TiUtils stringValue:[self valueForKey:@"largestUndimmedDetentIdentifier"]] isEqual: @"large"]){ + _largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge; + bottomSheet.largestUndimmedDetentIdentifier = _largestUndimmedDetentIdentifier; + } + else if ([[TiUtils stringValue:[self valueForKey:@"largestUndimmedDetentIdentifier"]] isEqual: @"medium"]){ + _largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierMedium; + + bottomSheet.largestUndimmedDetentIdentifier = _largestUndimmedDetentIdentifier; + + } + else { + } + } + + if ([self valueForKey:@"preferredCornerRadius"]){ + bottomSheet.preferredCornerRadius = [TiUtils floatValue:[self valueForKey:@"preferredCornerRadius"]]; + } + + + + + + bottomSheet.prefersScrollingExpandsWhenScrolledToEdge = [TiUtils boolValue:[self valueForKey:@"prefersScrollingExpandsWhenScrolledToEdge"] def:YES]; + + bottomSheet.prefersEdgeAttachedInCompactHeight = [TiUtils boolValue:[self valueForKey:@"prefersEdgeAttachedInCompactHeight"] def:YES]; + + bottomSheet.widthFollowsPreferredContentSizeWhenEdgeAttached = [TiUtils boolValue:[self valueForKey:@"widthFollowsPreferredContentSizeWhenEdgeAttached"] def:YES]; + + + + + + if ([self valueForKey:@"detents"]){ + userDetents = [self valueForKey:@"detents"]; + + NSMutableArray *detentsOfController = [NSMutableArray arrayWithCapacity:2]; + + if ([TiUtils boolValue:[self valueForKey:@"nonModal"] def:NO]) { + if ([TiUtils boolValue:[userDetents valueForKey:@"large"] def:NO]) { + [detentsOfController addObject:[UISheetPresentationControllerDetent largeDetent]]; + } + if ([TiUtils boolValue:[userDetents valueForKey:@"medium"] def:NO]) { + [detentsOfController addObject:[UISheetPresentationControllerDetent mediumDetent]]; + } + } + else { + if ([TiUtils boolValue:[userDetents valueForKey:@"medium"] def:NO]) { + [detentsOfController addObject:[UISheetPresentationControllerDetent mediumDetent]]; + } + if ([TiUtils boolValue:[userDetents valueForKey:@"large"] def:NO]) { + [detentsOfController addObject:[UISheetPresentationControllerDetent largeDetent]]; + } + } + + + bottomSheet.detents = detentsOfController; + + if ([TiUtils stringValue:[self valueForKey:@"startDetent"]]){ + if ([[TiUtils stringValue:[self valueForKey:@"startDetent"]] isEqual: @"large"] && ([TiUtils boolValue:[userDetents valueForKey:@"large"] def:NO])){ + bottomSheet.selectedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge; + + } + else if ([[TiUtils stringValue:[self valueForKey:@"startDetent"]] isEqual: @"medium"] && ([TiUtils boolValue:[userDetents valueForKey:@"medium"] def:NO])){ + bottomSheet.selectedDetentIdentifier = UISheetPresentationControllerDetentIdentifierMedium; + + } + else { + + } + } + } + + + bottomSheet.prefersGrabberVisible = [TiUtils boolValue:[self valueForKey:@"prefersGrabberVisible"] def:YES]; + -// [theController setModalPresentationStyle:UIModalPresentationPageSheet]; - - bottomSheet = [theController sheetPresentationController]; - - bottomSheet.delegate = self; + if ([self valueForKey:@"backgroundColor"]){ + // [theController.view setBackgroundColor:[[TiUtils colorValue:[self valueForKey:@"backgroundColor"]] _color]]; - if ([self valueForKey:@"largestUndimmedDetentIdentifier"]){ - if ([[TiUtils stringValue:[self valueForKey:@"largestUndimmedDetentIdentifier"]] isEqual: @"large"]){ - _largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge; +// [theController.view setBackgroundColor:[[TiUtils colorValue:[self valueForKey:@"backgroundColor"]] _color]]; + } + [theController.view setBackgroundColor:[[TiUtils colorValue:[self valueForKey:@"backgroundColor"]] _color]]; + + // [theController.view setBackgroundColor:[UIColor redColor]]; + + if ([self valueForKey:@"modalPresentation"]){ + if ([[TiUtils stringValue:[self valueForKey:@"modalPresentation"]] isEqual: @"fullScreen"]){ + [theController setModalPresentationStyle:UIModalPresentationFullScreen]; + } + else if ([[TiUtils stringValue:[self valueForKey:@"modalPresentation"]] isEqual: @"pageSheet"]){ + [theController setModalPresentationStyle:UIModalPresentationPageSheet]; + } + else if ([[TiUtils stringValue:[self valueForKey:@"modalPresentation"]] isEqual: @"currentContext"]){ + [theController setModalPresentationStyle:UIModalPresentationCurrentContext]; + } + else if ([[TiUtils stringValue:[self valueForKey:@"modalPresentation"]] isEqual: @"overCurrentContext"]){ + [theController setModalPresentationStyle:UIModalPresentationOverCurrentContext]; + } + else { + [theController setModalPresentationStyle:UIModalPresentationPageSheet]; + } } else { - _largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierMedium; + [theController setModalPresentationStyle:UIModalPresentationPageSheet]; } - bottomSheet.largestUndimmedDetentIdentifier = _largestUndimmedDetentIdentifier; + + + // NSLog(@"before closeButtonView "); + + if (closeButtonView != nil){ + closeButtonProxy.view.frame = closeButtonView.bounds; + [closeButtonView addSubview:closeButtonProxy.view]; + [closeButtonProxy reposition]; + + CGSize size = theController.view.frame.size; + [closeButtonView setCenter:CGPointMake((size.width - (closeButtonView.bounds.size.width/2)), 24)]; + + [theController.view addSubview:closeButtonView]; + [theController.view bringSubviewToFront:closeButtonView]; + + // NSLog(@"added closeButtonView "); + // NSLog(@"closeButtonView %@",closeButtonView); + } + + [[[[TiApp app] controller] topPresentedController] presentViewController:theController animated:animated completion:^{ + [self fireEvent:@"opened" withObject:nil]; + + }]; + + + } + + else { + customBottomSheet = [BottomSheetViewController new]; + [customBottomSheet setProxyOfBottomSheetController:self]; + + + const CGFloat y = [[[TiApp app] controller] topPresentedController].view.frame.origin.y; + const CGFloat height = [[[TiApp app] controller] topPresentedController].view.frame.size.height; + const CGFloat width = [[[TiApp app] controller] topPresentedController].view.frame.size.width; + + backgroundView = [[UIView alloc] init]; + backgroundView.frame = CGRectMake( 0, 0, width, height); + + UITapGestureRecognizer *singleFingerTap = + [[UITapGestureRecognizer alloc] initWithTarget:self + action:@selector(handleSingleTap:)]; + [backgroundView addGestureRecognizer:singleFingerTap]; + + + customBottomSheet.view.frame = CGRectMake( 0, y + height, width, height); + + containerView = [[UIView alloc] init]; + + if ([TiUtils boolValue:[self valueForUndefinedKey:@"nonSystemSheetTopShadow"] def:NO]){ + customBottomSheet.view.layer.shadowOffset = CGSizeMake(0,-2); + customBottomSheet.view.layer.shadowRadius = 6; + customBottomSheet.view.layer.shadowOpacity = .6f; + customBottomSheet.view.layer.shadowColor = [UIColor blackColor].CGColor; + //customBottomSheet.view.layer.masksToBounds = NO; } + containerView.clipsToBounds = YES; + + - if ([self valueForKey:@"preferredCornerRadius"]){ - bottomSheet.preferredCornerRadius = [TiUtils floatValue:[self valueForKey:@"preferredCornerRadius"]]; + [customBottomSheet.view addSubview:containerView]; + + const CGFloat heightOfContainer = customBottomSheet.view.frame.size.height - 100; + const CGFloat widthOfContainer = customBottomSheet.view.frame.size.width; + containerView.frame = CGRectMake( 0, 0, widthOfContainer, heightOfContainer); + + + + useNavController = NO; + + if ([[[contentViewProxy class] description] isEqualToString:@"TiUINavigationWindowProxy"]) { + useNavController = YES; } + + UIView *controllerView_; - bottomSheet.prefersScrollingExpandsWhenScrolledToEdge = [TiUtils boolValue:[self valueForKey:@"prefersScrollingExpandsWhenScrolledToEdge"] def:YES]; - - bottomSheet.prefersEdgeAttachedInCompactHeight = [TiUtils boolValue:[self valueForKey:@"prefersEdgeAttachedInCompactHeight"] def:YES]; + if (useNavController) { + //[(TiWindowProxy *)contentViewProxy setIsManaged:YES]; + centerProxy = [self valueForUndefinedKey:@"contentView"]; + controllerView_ = [[centerProxy controller] view]; + [controllerView_ setFrame:[containerView bounds]]; + } + else { + controllerView_ = [contentViewProxy view]; + [controllerView_ setFrame:[containerView bounds]]; + } + - bottomSheet.widthFollowsPreferredContentSizeWhenEdgeAttached = [TiUtils boolValue:[self valueForKey:@"widthFollowsPreferredContentSizeWhenEdgeAttached"] def:YES]; - - - if ([self valueForKey:@"detents"]){ - userDetents = [self valueForKey:@"detents"]; + + if (nonSystemSheetShouldScroll == YES){ - NSMutableArray *detentsOfController = [NSMutableArray arrayWithCapacity:2]; + // NSLog(@"nonSystemSheetShouldScroll == YES "); + UIEdgeInsets safeAreaInset = UIEdgeInsetsZero; + UIViewController *topContainerController = [[[TiApp app] controller] topContainerController]; - //[TiUtils boolValue:[self valueForKey:@"prefersEdgeAttachedInCompactHeight"] + safeAreaInset = [[topContainerController hostingView] safeAreaInsets]; + + const CGFloat heightOfScrollContainer = containerView.frame.size.height; + const CGFloat widthOfScrollContainer = containerView.frame.size.width; + - if ([TiUtils boolValue:[userDetents valueForKey:@"medium"] def:NO]) { - [detentsOfController addObject:[UISheetPresentationControllerDetent mediumDetent]]; + scrollView = [[ContentScrollView alloc] initWithFrame:CGRectMake( 0, 24, widthOfScrollContainer, heightOfScrollContainer)]; + scrollView.dismissing = NO; + scrollView.delegate = self; +// UITapGestureRecognizer *panScrollView = +// [[UITapGestureRecognizer alloc] initWithTarget:self +// action:@selector(handleGesture:)]; +// [scrollView addGestureRecognizer:panScrollView]; + scrollView.delaysContentTouches = NO; + scrollView.scrollEnabled = YES; + // scrollView.pagingEnabled = YES; + scrollView.showsVerticalScrollIndicator = YES; + scrollView.showsHorizontalScrollIndicator = NO; + scrollView.canCancelContentTouches = YES; + scrollView.contentSize = CGSizeMake(controllerView_.frame.size.width, controllerView_.frame.size.height); + // NSLog(@"contentSize height %f ",[contentViewProxy view].frame.size.height); + scrollView.insetsLayoutMarginsFromSafeArea = YES; + [containerView addSubview:scrollView]; + [scrollView addSubview:controllerView_]; + CGPoint contentOffet = scrollView.contentOffset; + contentOffet.y = 0; + scrollView.contentOffset = contentOffet; + //[customBottomSheet panRecognizerEnabled:NO]; + [customBottomSheet panRecognizerEnabled:YES]; + [customBottomSheet scrollView:scrollView]; + [customBottomSheet lastContentOffsetY:0]; + + + [self disableScrolling:controllerView_]; + + } + else { + // NSLog(@"nonSystemSheetShouldScroll == NO "); + + [containerView addSubview:controllerView_]; + } + + + + if ([self valueForKey:@"preferredCornerRadius"]){ + containerView.layer.cornerRadius = [TiUtils floatValue:[self valueForKey:@"preferredCornerRadius"]]; + } + else { + containerView.layer.cornerRadius = 10; + } + + containerView.backgroundColor = [[TiUtils colorValue:[self valueForKey:@"backgroundColor"]] _color]; + + if ([TiUtils boolValue:[self valueForKey:@"prefersGrabberVisible"] def:YES]){ + CGRect handleViewFrame = CGRectMake( 0, 0, 44, 6); + UIView *handle = [[UIView alloc] initWithFrame:handleViewFrame]; + handle.backgroundColor = [UIColor blackColor]; + handle.layer.cornerRadius = 4; + handle.alpha = 0.4; + CGSize size = containerView.frame.size; + [handle setCenter:CGPointMake(size.width/2, 10)]; + + if (nonSystemSheetShouldScroll == YES){ + [containerView insertSubview:handle aboveSubview:scrollView]; } - if ([TiUtils boolValue:[userDetents valueForKey:@"large"] def:NO]) { - [detentsOfController addObject:[UISheetPresentationControllerDetent largeDetent]]; + else { + [containerView insertSubview:handle aboveSubview:controllerView_]; } - - bottomSheet.detents = detentsOfController; } - - bottomSheet.prefersGrabberVisible = [TiUtils boolValue:[self valueForKey:@"prefersGrabberVisible"] def:YES]; - - if ([self valueForKey:@"backgroundColor"]){ - [theController.view setBackgroundColor:[[TiColor colorNamed:[self valueForKey:@"backgroundColor"]] _color]]; + + if (closeButtonView != nil){ + + closeButtonProxy.view.frame = closeButtonView.bounds; + [closeButtonView addSubview:closeButtonProxy.view]; + [closeButtonProxy reposition]; + + + CGSize size = containerView.frame.size; + + [closeButtonView setCenter:CGPointMake((size.width - (closeButtonView.bounds.size.width/2)), 24)]; + + if (nonSystemSheetShouldScroll == YES){ + [containerView insertSubview:closeButtonView aboveSubview:scrollView]; + } + else { + [containerView insertSubview:closeButtonView aboveSubview:controllerView_]; + } + } + + + + // [[[[TiApp app] controller] topPresentedController] presentViewController:theController animated:animated completion:^{ +// }]; + + + + [[[[TiApp app] controller] topPresentedController].view addSubview:backgroundView]; + + [[[[TiApp app] controller] topPresentedController].view insertSubview:customBottomSheet.view aboveSubview:backgroundView]; + + + + // [[[[TiApp app] controller] topPresentedController].view addSubview:theController.view]; + // [[TiApp app] showModalController:theController animated:animated]; + + [self fireEvent:@"opened" withObject:nil]; } +} + + +- (void)disableScrolling:(UIView *)view +{ - if ([self valueForKey:@"modalPresentation"]){ - if ([[TiUtils stringValue:[self valueForKey:@"modalPresentation"]] isEqual: @"overFullScreen"]){ - [theController setModalPresentationStyle:UIModalPresentationOverFullScreen]; - } - else if ([[TiUtils stringValue:[self valueForKey:@"modalPresentation"]] isEqual: @"pageSheet"]){ - [theController setModalPresentationStyle:UIModalPresentationPageSheet]; - } - else if ([[TiUtils stringValue:[self valueForKey:@"modalPresentation"]] isEqual: @"currentContext"]){ - [theController setModalPresentationStyle:UIModalPresentationCurrentContext]; - } - else if ([[TiUtils stringValue:[self valueForKey:@"modalPresentation"]] isEqual: @"overCurrentContext"]){ - [theController setModalPresentationStyle:UIModalPresentationOverCurrentContext]; - } - else { - [theController setModalPresentationStyle:UIModalPresentationAutomatic]; + if ([view respondsToSelector:@selector(setScrollEnabled:)]){ + // NSLog(@"UIView %@ ",view); + + if ([view performSelector: @selector (isScrollEnabled)]){ + + if ([view isKindOfClass:[UITableView class]]){ + [(UITableView *)view setScrollEnabled:NO]; + // NSLog(@"TableView %@ ",view); + + } + else if ([view isKindOfClass:[UIScrollView class]]){ + [(UIScrollView *)view setScrollEnabled:NO]; + // NSLog(@"ScrollView %@ ",view); + } + else { + // NSLog(@"UIView isScrollEnabled %d ",[view performSelector: @selector (isScrollEnabled)]); + } } } - else { - [theController setModalPresentationStyle:UIModalPresentationAutomatic]; + + for (UIView *eachView in view.subviews) { + + if ([eachView respondsToSelector:@selector(setScrollEnabled:)]){ + // NSLog(@"UIView %@ ",eachView); + + if ([eachView performSelector: @selector (isScrollEnabled)]){ + + if ([eachView isKindOfClass:[UITableView class]]){ + [(UITableView *)eachView setScrollEnabled:NO]; + //NSLog(@"TableView %@ ",eachView); + + } + else if ([eachView isKindOfClass:[UIScrollView class]]){ + [(UIScrollView *)eachView setScrollEnabled:NO]; + //NSLog(@"ScrollView %@ ",eachView); + } + else { + // NSLog(@"UIView isScrollEnabled %d ",[eachView performSelector: @selector (isScrollEnabled)]); + } + } + } + [self disableScrolling:eachView]; } - - [[[[TiApp app] controller] topPresentedController] presentViewController:theController animated:animated completion:^{ - [self fireEvent:@"opened" withObject:nil]; - }]; +} - +//The event handling method +- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer +{ + CGPoint location = [recognizer locationInView:[recognizer.view superview]]; + if (isDismissing == NO){ + isDismissing = YES; + [self hide:nil]; + } + //Do stuff here... +} + +- (void)handleGesture:(UITapGestureRecognizer *)recognizer +{ + if (scrollView.dismissing == NO){ + // NSLog(@"*************** handleGesture"); + [customBottomSheet panFromScrollView:YES]; + } } @@ -381,16 +1084,103 @@ - (void)updateContentViewWithSafeAreaInsets:(NSValue *)insetsValue TiThreadPerformOnMainThread( ^{ UIViewController *viewController = [self viewController]; + +// CGRect newControllerFrame = viewController.view.frame; +// +// newControllerFrame.size.height = viewController.view.frame.size.height + 24; +// viewController.view.frame = newControllerFrame; + self->contentViewProxy.view.frame = viewController.view.frame; + +// CGRect controllerFrame = viewController.view.frame; +// controllerFrame.origin.y = 24; +// // controllerFrame.size.height = controllerFrame.size.height - 24; +// self->contentViewProxy.view.frame = controllerFrame; + +// UIEdgeInsets edgeInsets = [insetsValue UIEdgeInsetsValue]; - viewController.view.frame = CGRectMake(viewController.view.frame.origin.x + edgeInsets.left, viewController.view.frame.origin.y + edgeInsets.top, viewController.view.frame.size.width - edgeInsets.left - edgeInsets.right, viewController.view.frame.size.height - edgeInsets.top - edgeInsets.bottom); +// + viewController.view.frame = CGRectMake(viewController.view.frame.origin.x + edgeInsets.left, viewController.view.frame.origin.y + (edgeInsets.top), viewController.view.frame.size.width - edgeInsets.left - edgeInsets.right, viewController.view.frame.size.height - (edgeInsets.top) - edgeInsets.bottom); + + +// +// +// self->contentViewProxy.view.frame = CGRectMake(self->contentViewProxy.view.frame.origin.x + edgeInsets.left, self->contentViewProxy.view.frame.origin.y + (edgeInsets.top), self->contentViewProxy.view.frame.size.width - edgeInsets.left - edgeInsets.right, self->contentViewProxy.view.frame.size.height - (edgeInsets.top) - edgeInsets.bottom); + }, NO); } - #pragma mark Delegate methods + +-(void)scrollViewDidScroll:(ContentScrollView *)scrollView{ + + // NSLog(@"++++++++++ scrollViewDidScroll "); + + [customBottomSheet lastContentOffsetY:scrollView.contentOffset.y]; + + if (scrollView.contentOffset.y <= 0) { + //scrollView.contentOffset = CGPointZero; + + if (scrollView.dismissing == NO){ + scrollView.dismissing = YES; + [customBottomSheet panRecognizerInit:YES]; + [customBottomSheet panRecognizerEnabled:YES]; + // scrollView.panGestureRecognizer.enabled = NO; + // scrollView.panGestureRecognizer.enabled = NO; + // NSLog(@"++++++++++ scrollViewDidScroll disable ScrollView "); + + } + } + else { + scrollView.dismissing = NO; + [customBottomSheet panRecognizerEnabled:NO]; + // scrollView.panGestureRecognizer.enabled = YES; + // NSLog(@"++++++++++ scrollViewDidScroll enable ScrollView "); + // [customBottomSheet panFromScrollView:NO]; + +// if (scrollView.panGestureRecognizer.enabled == NO){ +// scrollView.panGestureRecognizer.enabled = YES; +// } + } + +} +// +- (void)scrollViewDidEndDecelerating:(ContentScrollView *)scrollView_ // scrolling has ended +{ + [customBottomSheet panRecognizerEnabled:YES]; + // NSLog(@"scrollViewDidEndDecelerating "); + // scrollView.panGestureRecognizer.enabled = YES; + scrollView.dismissing = NO; + [customBottomSheet panFromScrollView:NO]; +// scrollView.panGestureRecognizer.enabled = YES; + // [customBottomSheet panRecognizerEnabled:YES]; + +} +// +- (void)scrollViewDidEndDragging:(ContentScrollView *)scrollView willDecelerate:(BOOL)decelerate +{ + // NSLog(@"scrollViewDidEndDragging "); + scrollView.dismissing = NO; + // scrollView.panGestureRecognizer.enabled = YES; + [customBottomSheet panRecognizerEnabled:YES]; + [customBottomSheet panFromScrollView:NO]; + + // [customBottomSheet panFromScrollView:NO]; + +} +// +//-(void)scrollViewWillBeginDragging:(ContentScrollView *)scrollView{ +// // [customBottomSheet panRecognizerEnabled:NO]; +// NSLog(@"scrollViewWillBeginDragging "); +// if ([customBottomSheet panRecognizerState] == YES) { +// NSLog(@"scrollViewWillBeginDragging pan disabled"); +// [customBottomSheet panRecognizerEnabled:NO]; +// } +//} + + - (void)proxyDidRelayout:(id)sender { if (sender == contentViewProxy) { @@ -399,7 +1189,7 @@ - (void)proxyDidRelayout:(id)sender if (TiBottomSheetContentSize.width != newSize.width || TiBottomSheetContentSize.height != newSize.height){ if (!CGSizeEqualToSize([viewController preferredContentSize], newSize)) { // NSLog(@"proxyDidRelayout "); - // [self updateContentSize]; + [self updateContentSize]; } } } @@ -410,7 +1200,7 @@ - (void)proxyDidRelayout:(id)sender - (void)sheetPresentationControllerDidChangeSelectedDetentIdentifier :(UISheetPresentationController *)bottomSheetPresentationController { - NSLog(@"\n\n sheetPresentationControllerDidChangeSelectedDetentIdentifier "); + // NSLog(@"\n\n sheetPresentationControllerDidChangeSelectedDetentIdentifier "); if (bottomSheetPresentationController.selectedDetentIdentifier == UISheetPresentationControllerDetentIdentifierMedium){ NSDictionary *detentObject = [NSDictionary dictionaryWithObjectsAndKeys:@"medium", @"selectedDetentIdentifier", nil]; @@ -426,6 +1216,10 @@ - (void)sheetPresentationControllerDidChangeSelectedDetentIdentifier :(UISheetPr - (BOOL)presentationControllerShouldDismiss:(UISheetPresentationController *)bottomSheetPresentationController { + + // NSLog(@"presentationControllerShouldDismiss "); + + if ([[self viewController] presentedViewController] != nil) { return NO; } @@ -437,10 +1231,16 @@ - (BOOL)presentationControllerShouldDismiss:(UISheetPresentationController *)bot - (void)presentationControllerDidDismiss:(UISheetPresentationController *)bottomSheetPresentationController { - // NSLog(@"presentationControllerDidDismiss "); - currentTiBottomSheet = nil; + // NSLog(@"presentationControllerDidDismiss "); + // DebugLog(@"BottomSheet presentationControllerDidDismiss"); + [bottomSheetModule cleanup]; - [self fireEvent:@"closed" withObject:nil]; + if (eventFired == NO){ + eventFired = YES; + [self fireEvent:@"closed" withObject:nil]; + } + + currentTiBottomSheet = nil; // [self cleanup]; } @@ -454,11 +1254,11 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N if (!UIEdgeInsetsEqualToEdgeInsets(oldInsets, newInsets)) { deviceRotated = NO; - // [self updateContentViewWithSafeAreaInsets:insetsValue]; + [self updateContentViewWithSafeAreaInsets:insetsValue]; } else if (deviceRotated) { // [self viewController] need a bit of time to set its frame while rotating deviceRotated = NO; - // [self performSelector:@selector(updateContentViewWithSafeAreaInsets:) withObject:insetsValue afterDelay:.05]; + [self performSelector:@selector(updateContentViewWithSafeAreaInsets:) withObject:insetsValue afterDelay:.05]; } } } @@ -468,4 +1268,115 @@ - (void)deviceRotated:(NSNotification *)sender deviceRotated = YES; } + + @end + +@implementation ContentScrollView +// +//- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event +//{ +// UIView *hitView = [super hitTest:point withEvent:event]; +// +// if (hitView == self) { +// return nil; +// } +// return hitView; +//} + +//- (BOOL)gestureRecognizer:(UIPanGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIPanGestureRecognizer *)otherGestureRecognizer +//{ +// NSLog(@"gestureRecognizer: %f ",self.contentOffset.y); +// +//// +//// if (self.scrollEnabled == YES){ +//// +//// if (self.contentOffset.y < 0) { +//// +//// self.scrollEnabled = NO; +//// +//// //self.contentOffset = CGPointZero; +//// // if (self.scrollEnabled == YES){ +//// // self.scrollEnabled = NO; +//// // } +//// NSLog(@"gestureRecognizer should pan"); +//// return NO; +//// +//// +//// // scrollView.userInteractionEnabled = NO; +//// // scrollView.panGestureRecognizer.enabled = NO; +//// } +//// else { +//// // if (self.scrollEnabled == NO){ +//// self.scrollEnabled = YES; +//// // } +//// NSLog(@"gestureRecognizer should NOT pan"); +//// return NO; +//// +//// +//// } +//// +//// } +// if (self.contentOffset.y == 0) { +// return YES; +// } +// else { +// return NO; +// } +// +//} +//- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer +//{ +// if (_panRecognizer == gestureRecognizer) { +// if ([otherGestureRecognizer.view isKindOfClass:UIScrollView.class]) { +// UIScrollView *scrollView = (UIScrollView *)otherGestureRecognizer.view; +// if (scrollView.contentOffset.x == 0) { +// return YES; +// } +// } +// } +// +// return NO; +//} + +//- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer +//{ +// //NSLog(@"gestureRecognizer "); +// if (self.contentOffset.y <= 0 && self.panGestureRecognizer.enabled == YES) { +// self.panGestureRecognizer.enabled = NO; +// // NSLog(@"gestureRecognizer disabled"); +// } +// // [customBottomSheet panFromScrollView:YES]; +// +//// if (self.contentOffset.y <= 0) { +//// +//// NSLog(@"panRecognizer offset.y <= 0"); +//// return YES; +//// +//// } +//// else { +//// NSLog(@"panRecognizer offset.y > 0"); +//// +//// return NO; +//// } +// return YES; +// +//// NSLog(@"gestureRecognizer %@",gestureRecognizer.state); +// // NSLog(@"otherGestureRecognizer %@",otherGestureRecognizer.state); +// +// +//// if (self.dismissing == YES){ +//// NSLog(@"gestureRecognizer YES"); +//// return YES; +//// } +//// else { +//// NSLog(@"gestureRecognizer NO"); +//// +//// return NO; +//// } +//// return YES; +//} + +@end + + diff --git a/ios/Classes/TouchDelayGestureRecognizer.h b/ios/Classes/TouchDelayGestureRecognizer.h new file mode 100644 index 0000000..8eb7e6d --- /dev/null +++ b/ios/Classes/TouchDelayGestureRecognizer.h @@ -0,0 +1,13 @@ +// +// TouchDelayGestureRecognizer.h +// TouchDemo +// +// Created by Antonio081014 on 8/23/15. +// Copyright (c) 2015 antonio081014.com. All rights reserved. +// + +#import + +@interface TouchDelayGestureRecognizer : UIGestureRecognizer + +@end diff --git a/ios/Classes/TouchDelayGestureRecognizer.m b/ios/Classes/TouchDelayGestureRecognizer.m new file mode 100644 index 0000000..0495631 --- /dev/null +++ b/ios/Classes/TouchDelayGestureRecognizer.m @@ -0,0 +1,65 @@ +// +// TouchDelayGestureRecognizer.m +// TouchDemo +// +// Created by Antonio081014 on 8/23/15. +// Copyright (c) 2015 antonio081014.com. All rights reserved. +// + +#import "TouchDelayGestureRecognizer.h" +#import + + +@interface TouchDelayGestureRecognizer() +@property (nonatomic, strong) NSTimer *timer; +@end + +@implementation TouchDelayGestureRecognizer + +- (instancetype)initWithTarget:(id)target action:(SEL)action +{ + if (self = [super initWithTarget:target action:action]) { + self.delaysTouchesBegan = YES; + } + return self; +} + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + NSLog(@"touchesBegan"); + // start timer; + self.timer = [NSTimer scheduledTimerWithTimeInterval:0.0f target:self selector:@selector(fail) userInfo:nil repeats:NO]; +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self fail]; +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self fail]; +} + + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self fail]; +} + +- (void)reset +{ + NSLog(@"reset"); + + [self.timer invalidate]; + self.timer = nil; +} + +- (void)fail +{ + NSLog(@"fail"); + + self.state = UIGestureRecognizerStateFailed; +} + +@end diff --git a/ios/TiBottomSheetController_Prefix.pch b/ios/TiBottomSheetController_Prefix.pch old mode 100644 new mode 100755 diff --git a/ios/manifest b/ios/manifest index 4ecb4b7..1f8705e 100755 --- a/ios/manifest +++ b/ios/manifest @@ -2,7 +2,7 @@ # this is your module manifest and used by Titanium # during compilation, packaging, distribution, etc. # -version: 1.0.0 +version: 1.0.1 apiversion: 2 architectures: arm64 x86_64 mac: false diff --git a/ios/ti.bottomsheetcontroller.podspec b/ios/ti.bottomsheetcontroller.podspec old mode 100644 new mode 100755 diff --git a/ios/ti.bottomsheetcontroller.xcodeproj/project.pbxproj b/ios/ti.bottomsheetcontroller.xcodeproj/project.pbxproj index a319d32..6979dd3 100755 --- a/ios/ti.bottomsheetcontroller.xcodeproj/project.pbxproj +++ b/ios/ti.bottomsheetcontroller.xcodeproj/project.pbxproj @@ -26,8 +26,10 @@ 24DD6CFA1134B3F500162E58 /* TiBottomsheetcontrollerModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 24DD6CF81134B3F500162E58 /* TiBottomsheetcontrollerModule.m */; }; 24DE9E1111C5FE74003F90F6 /* TiBottomsheetcontrollerModuleAssets.h in Headers */ = {isa = PBXBuildFile; fileRef = 24DE9E0F11C5FE74003F90F6 /* TiBottomsheetcontrollerModuleAssets.h */; }; 24DE9E1211C5FE74003F90F6 /* TiBottomsheetcontrollerModuleAssets.m in Sources */ = {isa = PBXBuildFile; fileRef = 24DE9E1011C5FE74003F90F6 /* TiBottomsheetcontrollerModuleAssets.m */; }; - 2C66AD8B26FEBFAD00F08984 /* BottomSheetVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C66AD8926FEBFAD00F08984 /* BottomSheetVC.m */; }; - 2C66AD8C26FEBFAD00F08984 /* BottomSheetVC.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C66AD8A26FEBFAD00F08984 /* BottomSheetVC.h */; }; + 2C20742A270FD9680075E87C /* TouchDelayGestureRecognizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C207428270FD9680075E87C /* TouchDelayGestureRecognizer.h */; }; + 2C20742B270FD9680075E87C /* TouchDelayGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C207429270FD9680075E87C /* TouchDelayGestureRecognizer.m */; }; + 2CCB47082702A0BE007988E2 /* BottomSheetViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CCB47062702A0BE007988E2 /* BottomSheetViewController.h */; }; + 2CCB47092702A0BE007988E2 /* BottomSheetViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CCB47072702A0BE007988E2 /* BottomSheetViewController.m */; }; 2CCBDD6726E3FADF0078F941 /* TiBottomsheetcontrollerProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CCBDD6526E3FADF0078F941 /* TiBottomsheetcontrollerProxy.h */; }; 2CCBDD6826E3FADF0078F941 /* TiBottomsheetcontrollerProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CCBDD6626E3FADF0078F941 /* TiBottomsheetcontrollerProxy.m */; }; AA747D9F0F9514B9006C5449 /* TiBottomSheetController_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* TiBottomSheetController_Prefix.pch */; }; @@ -51,8 +53,11 @@ 24DD6D1B1134B66800162E58 /* titanium.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = titanium.xcconfig; sourceTree = ""; }; 24DE9E0F11C5FE74003F90F6 /* TiBottomsheetcontrollerModuleAssets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TiBottomsheetcontrollerModuleAssets.h; path = Classes/TiBottomsheetcontrollerModuleAssets.h; sourceTree = ""; }; 24DE9E1011C5FE74003F90F6 /* TiBottomsheetcontrollerModuleAssets.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TiBottomsheetcontrollerModuleAssets.m; path = Classes/TiBottomsheetcontrollerModuleAssets.m; sourceTree = ""; }; - 2C66AD8926FEBFAD00F08984 /* BottomSheetVC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BottomSheetVC.m; path = Classes/BottomSheetVC.m; sourceTree = ""; }; - 2C66AD8A26FEBFAD00F08984 /* BottomSheetVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BottomSheetVC.h; path = Classes/BottomSheetVC.h; sourceTree = ""; }; + 2C207427270F69C40075E87C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 2C207428270FD9680075E87C /* TouchDelayGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TouchDelayGestureRecognizer.h; path = Classes/TouchDelayGestureRecognizer.h; sourceTree = ""; }; + 2C207429270FD9680075E87C /* TouchDelayGestureRecognizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TouchDelayGestureRecognizer.m; path = Classes/TouchDelayGestureRecognizer.m; sourceTree = ""; }; + 2CCB47062702A0BE007988E2 /* BottomSheetViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BottomSheetViewController.h; path = Classes/BottomSheetViewController.h; sourceTree = ""; }; + 2CCB47072702A0BE007988E2 /* BottomSheetViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BottomSheetViewController.m; path = Classes/BottomSheetViewController.m; sourceTree = ""; }; 2CCBDD6526E3FADF0078F941 /* TiBottomsheetcontrollerProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TiBottomsheetcontrollerProxy.h; path = Classes/TiBottomsheetcontrollerProxy.h; sourceTree = ""; }; 2CCBDD6626E3FADF0078F941 /* TiBottomsheetcontrollerProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TiBottomsheetcontrollerProxy.m; path = Classes/TiBottomsheetcontrollerProxy.m; sourceTree = ""; }; AA747D9E0F9514B9006C5449 /* TiBottomSheetController_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TiBottomSheetController_Prefix.pch; sourceTree = SOURCE_ROOT; }; @@ -85,6 +90,7 @@ 0867D691FE84028FC02AAC07 /* ti.popover */ = { isa = PBXGroup; children = ( + 2C207427270F69C40075E87C /* Assets.xcassets */, 08FB77AEFE84172EC02AAC07 /* Classes */, 32C88DFF0371C24200C91783 /* Other Sources */, 0867D69AFE84028FC02AAC07 /* Frameworks */, @@ -105,10 +111,12 @@ 08FB77AEFE84172EC02AAC07 /* Classes */ = { isa = PBXGroup; children = ( + 2C207428270FD9680075E87C /* TouchDelayGestureRecognizer.h */, + 2C207429270FD9680075E87C /* TouchDelayGestureRecognizer.m */, 2CCBDD6526E3FADF0078F941 /* TiBottomsheetcontrollerProxy.h */, 2CCBDD6626E3FADF0078F941 /* TiBottomsheetcontrollerProxy.m */, - 2C66AD8A26FEBFAD00F08984 /* BottomSheetVC.h */, - 2C66AD8926FEBFAD00F08984 /* BottomSheetVC.m */, + 2CCB47062702A0BE007988E2 /* BottomSheetViewController.h */, + 2CCB47072702A0BE007988E2 /* BottomSheetViewController.m */, 24DE9E0F11C5FE74003F90F6 /* TiBottomsheetcontrollerModuleAssets.h */, 24DE9E1011C5FE74003F90F6 /* TiBottomsheetcontrollerModuleAssets.m */, 24DD6CF71134B3F500162E58 /* TiBottomsheetcontrollerModule.h */, @@ -133,10 +141,11 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 2CCB47082702A0BE007988E2 /* BottomSheetViewController.h in Headers */, 2CCBDD6726E3FADF0078F941 /* TiBottomsheetcontrollerProxy.h in Headers */, - 2C66AD8C26FEBFAD00F08984 /* BottomSheetVC.h in Headers */, AA747D9F0F9514B9006C5449 /* TiBottomSheetController_Prefix.pch in Headers */, 24DD6CF91134B3F500162E58 /* TiBottomsheetcontrollerModule.h in Headers */, + 2C20742A270FD9680075E87C /* TouchDelayGestureRecognizer.h in Headers */, 24DE9E1111C5FE74003F90F6 /* TiBottomsheetcontrollerModuleAssets.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -212,8 +221,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2C20742B270FD9680075E87C /* TouchDelayGestureRecognizer.m in Sources */, 2CCBDD6826E3FADF0078F941 /* TiBottomsheetcontrollerProxy.m in Sources */, - 2C66AD8B26FEBFAD00F08984 /* BottomSheetVC.m in Sources */, + 2CCB47092702A0BE007988E2 /* BottomSheetViewController.m in Sources */, 24DD6CFA1134B3F500162E58 /* TiBottomsheetcontrollerModule.m in Sources */, 24DE9E1211C5FE74003F90F6 /* TiBottomsheetcontrollerModuleAssets.m in Sources */, ); @@ -253,7 +263,7 @@ GCC_WARN_UNUSED_VALUE = NO; GCC_WARN_UNUSED_VARIABLE = NO; INSTALL_PATH = /usr/local/lib; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LIBRARY_SEARCH_PATHS = ""; OTHER_CFLAGS = ( "-DDEBUG", @@ -297,7 +307,7 @@ GCC_WARN_UNUSED_VALUE = NO; GCC_WARN_UNUSED_VARIABLE = NO; INSTALL_PATH = /usr/local/lib; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LIBRARY_SEARCH_PATHS = ""; OTHER_CFLAGS = "-DTI_POST_1_2"; OTHER_LDFLAGS = "-ObjC"; @@ -369,7 +379,7 @@ GCC_WARN_UNUSED_VALUE = NO; GCC_WARN_UNUSED_VARIABLE = NO; INSTALL_PATH = /usr/local/lib; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MACOSX_DEPLOYMENT_TARGET = 12.0; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = ( @@ -444,7 +454,7 @@ GCC_WARN_UNUSED_VALUE = NO; GCC_WARN_UNUSED_VARIABLE = NO; INSTALL_PATH = /usr/local/lib; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MACOSX_DEPLOYMENT_TARGET = 12.0; OTHER_CFLAGS = "-DTI_POST_1_2"; OTHER_LDFLAGS = "-ObjC"; diff --git a/ios/ti.bottomsheetcontroller.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/ti.bottomsheetcontroller.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist old mode 100644 new mode 100755 diff --git a/ios/ti.bottomsheetcontroller.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/ti.bottomsheetcontroller.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings old mode 100644 new mode 100755 diff --git a/ios/ti.bottomsheetcontroller.xcodeproj/project.xcworkspace/xcuserdata/marcbender.xcuserdatad/UserInterfaceState.xcuserstate b/ios/ti.bottomsheetcontroller.xcodeproj/project.xcworkspace/xcuserdata/marcbender.xcuserdatad/UserInterfaceState.xcuserstate index 61bd928..763d513 100755 Binary files a/ios/ti.bottomsheetcontroller.xcodeproj/project.xcworkspace/xcuserdata/marcbender.xcuserdatad/UserInterfaceState.xcuserstate and b/ios/ti.bottomsheetcontroller.xcodeproj/project.xcworkspace/xcuserdata/marcbender.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ios/ti.bottomsheetcontroller.xcodeproj/project.xcworkspace/xcuserdata/marcbender.xcuserdatad/WorkspaceSettings.xcsettings b/ios/ti.bottomsheetcontroller.xcodeproj/project.xcworkspace/xcuserdata/marcbender.xcuserdatad/WorkspaceSettings.xcsettings old mode 100644 new mode 100755 diff --git a/ios/ti.bottomsheetcontroller.xcodeproj/xcshareddata/xcschemes/ti.bottomsheetcontroller.xcscheme b/ios/ti.bottomsheetcontroller.xcodeproj/xcshareddata/xcschemes/ti.bottomsheetcontroller.xcscheme old mode 100644 new mode 100755 diff --git a/ios/ti.bottomsheetcontroller.xcodeproj/xcuserdata/marcbender.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/ios/ti.bottomsheetcontroller.xcodeproj/xcuserdata/marcbender.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..ac49d39 --- /dev/null +++ b/ios/ti.bottomsheetcontroller.xcodeproj/xcuserdata/marcbender.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + +