Skip to content

Instantly share code, notes, and snippets.

@adamtarmstrong
Last active September 4, 2018 17:39
Show Gist options
  • Save adamtarmstrong/bdc9c8bd205fc936fd53d939c1933e55 to your computer and use it in GitHub Desktop.
Save adamtarmstrong/bdc9c8bd205fc936fd53d939c1933e55 to your computer and use it in GitHub Desktop.
Ti Modal BottomSheet - Fragment
/*
* Ti Modal BottomSheet - Fragment
* Sample/Screenshot - https://imgur.com/EPHd7D2
*/
/*
* USAGE WITHIN YOUR MAIN APP:
* Simply use:
* Alloy.createController("modalBottomsheet").getView().open();
*/
//CONTROLLER
//fragments/modalBottomsheet.js
// Arguments passed into this controller can be accessed via the `$.args` object directly or:
var args = $.args;
/*
* Load Initial Configuration
*/
var matrix = Ti.UI.create2DMatrix();
var bottomSheetHeight = (OS_IOS) ? (parseInt(Ti.Platform.displayCaps.platformHeight) * 0.85) : (parseInt(Ti.Platform.displayCaps.xdpi * 0.85));
var startPosition = (OS_IOS) ? (Ti.Platform.displayCaps.platformHeight - bottomSheetHeight) : (Ti.Platform.displayCaps.xdpi - bottomSheetHeight + 20);
if (OS_IOS) {
var selectedGenerator = Ti.UI.iOS.createFeedbackGenerator({type: Ti.UI.iOS.FEEDBACK_GENERATOR_TYPE_SELECTION});
var impactGenerator = Ti.UI.iOS.createFeedbackGenerator({type: Ti.UI.iOS.FEEDBACK_GENERATOR_TYPE_IMPACT, style: Ti.UI.iOS.FEEDBACK_GENERATOR_IMPACT_STYLE_MEDIUM});
var currentPosition = startPosition;
var closePosition = startPosition + bottomSheetHeight/3;
}
/*
* Animation and Transition Helpers
*/
function showBottomSheetView(){
fadeInWindow();
$.bottomSheetView.animate(Ti.UI.createAnimation({
transform: matrix,
duration: 350,
curve: Ti.UI.ANIMATION_CURVE_EASE_IN,
top: startPosition,
opacity: 1
}));
}
function fadeInWindow(){
$.modalBottomsheet.animate(Ti.UI.createAnimation({
transform: matrix,
duration: 200,
backgroundColor: "#4D000000"
}));
}
function hideBottomSheetView(){
fadeOutWindow();
$.bottomSheetView.animate(Ti.UI.createAnimation({
transform: matrix,
duration: 200,
curve: Ti.UI.ANIMATION_CURVE_EASE_OUT,
top: "115%",
opacity: 0.7
}));
}
function fadeOutWindow(){
$.modalBottomsheet.animate(Ti.UI.createAnimation({
transform: matrix,
duration: 100,
backgroundColor: "#00000000"
}));
if (OS_IOS) { impactGenerator.impactOccurred(); }
setTimeout(function() {
close();
}, 200);
}
function handleTouchMove(e){
$.bottomSheetView.top = startPosition + e.y/2;
}
function handleTouchEnd(e){
if (startPosition + e.y > closePosition) {
hideBottomSheetView();
} else {
$.bottomSheetView.top = startPosition;
currentPosition = startPosition;
}
}
function close(){
$.modalBottomsheet.close();
}
//POSTLAYOUT
if (OS_IOS) { selectedGenerator.selectionChanged(); }
showBottomSheetView();
//STYLE
//fragments/modalBottomsheet.tss
"#modalBottomsheet": {
backgroundColor: "#00000000",
navBarHidden: true,
width: "100%",
height: "100%",
layout: "vertical"
},
"#modalBottomsheet[platform=android]": {
theme: "Theme.NoActionBar",
modal: true
}
"#container": {
backgroundColor: "#00000000",
width: "100%",
height: "100%",
layout: "vertical"
},
"#bottomSheetView": {
opacity: 0.3,
width: "100%",
top: "130%",
backgroundColor: "#f7f7f5",
layout: "vertical",
},
"#bottomSheetView[platform=ios]": {
height: "85%",
borderColor: "#66d5d3cc",
borderRadius: 10,
borderWidth: 1,
},
"#bottomSheetView[platform=android]": {
height: "85%",
elevation: 5
},
".bottomSheetHandleContainer": {
height: Ti.UI.SIZE,
width: "100%",
layout: "composite"
},
".bottomSheetHeaderBar": {
width: 48,
height: 6,
backgroundColor: "#c6c5c3",
borderColor: "#c6c5c3",
borderRadius: 3,
borderWidth: 1,
top: 8,
bottom: 10
},
".bottomSheetAndroidSoftButtonBottomPadding": {
image: "/transparent.png",
width: 1,
height: 20
},
".closeButton": {
font: { fontFamily: 'FontAwesome', fontSize: 20 },
color: "#c6c5c3",
text: "\uf057",
width: 80,
height: Ti.UI.SIZE,
top: 5,
right: 5,
textAlign: Titanium.UI.TEXT_ALIGNMENT_RIGHT
},
"Label": {
font: { fontSize: 16 },
color: "#333",
height: 40
},
//VIEW
//fragments/modalBottomsheet.xml
<Alloy>
<Window id="modalBottomsheet" onAndroid:back="hideBottomSheetView">
<View id="container" onClick="hideBottomSheetView">
<View id="bottomSheetView" bubbleParent="false">
<View class="bottomSheetHandleContainer" onTouchmove="handleTouchMove" onTouchend="handleTouchEnd" platform="ios">
<View class="bottomSheetHeaderBar" />
<Label class="closeButton" onClick="hideBottomSheetView" />
</View>
<ScrollView width="100%" height="Ti.UI.FILL">
<!--View / Content Goes Here-->
<Label text="Main View\n\nClick Here To Close" onClick="hideBottomSheetView" />
<!--View / Content Goes Here-->
<ImageView class="bottomSheetAndroidSoftButtonBottomPadding" platform="android" />
</ScrollView>
</View>
</View>
</Window>
</Alloy>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment