How to add a grid of images to a ScrollView in Titanium - javascript

I am trying to add rows of two images to a ScrollView in Titanium. I am having a problem in that only one row gets shown.
My Alloy code looks like this:
<Alloy>
<Window class='container' statusBarStyle='Ti.UI.iPhone.StatusBar.LIGHT_CONTENT'>
// Make ios status bar correct color
<View height='20' top='0' left='0' backgroundColor='#01B6AC'></View>
<View id = 'savedContents' layout='vertical' top='20'>
</View>
<Require type='view' src='bottomBar' id='bottomBar'/>
<Widget id="fa" src="com.mattmcfarland.fontawesome"/>
</Window>
</Alloy>
My Controller code looks like this:
var scrollView = Ti.UI.createScrollView({
contentWidth: 'auto',
contentHeight: 'height',
showVerticalScrollIndicator: false,
showHorizontalScrollIndicator: false,
width: '100%',
height: 400,
top: 0
});
for (i=0; i < venueDetails.length; i++) {
row = Ti.UI.createView({
width:'100%',
height:150,
layout:'composite'
});
image1 = Ti.UI.createImageView({
image:'http://www.outnow.io/assets/img/small511by309/'+venueDetails[i]["image1"],
width:'50%',
height:150,
left:0,
top:0
});
row.add(image1);
if (i+1 < venueDetails.length) {
image2 = Ti.UI.createImageView({
image:'http://www.outnow.io/assets/img/small511by309/'+venueDetails[i+1]["image1"],
width:'50%',
height:150,
left:'50%',
top:0
});
row.add(image2);
}
//$.savedContents.add(row);
scrollView.add(row);
}
$.savedContents.add(scrollView);
If I add the row views directly to the $.savedContents view (as per the commented out line in the code above) I see all of the rows correctly (two images per row). If I do this via a createScrollView I only get one row of images. I need to use the scrollView to make the images scrollable.
Anyone know what I am doing wrong?

By default the layout property has a value composite. So the scrollView has the composite layout, so you need to specify the positioning properties or "pins" (top, bottom, left, right and center) for that view (row). In your code you only specified the width and height, so all views will be centered in the parent view (ScrollView).
According to Titanium.UI.View-property-layout Reference:
composite (or absolute). Default layout. A child view is positioned
based on its positioning properties or "pins" (top, bottom, left,
right and center). If no positioning properties are specified, the
child is centered.

Related

Tooltip component rendering but not visible, and it is not the z-index

import React, {useState, useEffect} from "react";
// The tooltip component is used for the Tooltip feature that is utilized
const Tooltip = (couponProps) => {
const { couponTheme, verticalMousePosition, data, showTooltip, isSwiper } = couponProps;
const { TooltipText } = data;
const [tooltipStyles, setTooltipStyles] = useState({display: 'none'});
const [tooltipArrowStyles, setTooltipArrowStyles] = useState({display: 'none'});
const { TooltipTextColor, TooltipBackgroundColor, TooltipFontSize } = couponTheme;
// The useEffect hook will first define all the tooltip styling as objects. If the showTooltip variable defined in the parent element is active, render the tooltip.
useEffect(() => {
const topTooltipStyles = {
bottom: '130%',
left: '20%',
right: '20%',
width: '60%'
}
const topTooltipArrowStyles = {
top: '100%',
left: '50%',
marginLeft: '-5px',
borderColor: (TooltipBackgroundColor || 'black') + ' transparent transparent transparent',
marginTop: 'unset'
}
const bottomTooltipStyles = {
top: '125%',
left: '20%',
right: '20%',
width: '60%'
}
const bottomTooltipArrowStyles = {
bottom: '100%',
left: '50%',
marginLeft: '-5px',
borderColor: 'transparent transparent ' + (TooltipBackgroundColor || 'black') + ' transparent'
}
if (showTooltip) {
// The tooltip is configured to either render at the top of the interval bar or at the bottom of the interval bar. That is pased on where the mouse is located on the screen.
let tooltipPositionStyles = {};
let tooltipArrowPositionStyles = {};
// If the vertical mouse position is less than 250px to the top, render the tooltip at the bottom under the parent componet. This means the user is at the top of the screen, so use the bottom styling.
if (verticalMousePosition < 250 || isSwiper) {
// This way, the tooltip will not be cut of from the top of the screen.
tooltipPositionStyles = bottomTooltipStyles;
tooltipArrowPositionStyles = bottomTooltipArrowStyles;
// Else, that means the user is not at the top of the screen
} else {
tooltipPositionStyles = topTooltipStyles;
tooltipArrowPositionStyles = topTooltipArrowStyles;
}
const tooltipArrowStylesObj = {
content: ' ',
position: 'absolute',
borderWidth: '5px',
borderStyle: 'solid',
...tooltipArrowPositionStyles
}
const tooltipStylesObj = {
position: 'absolute',
color: TooltipTextColor || 'white',
background: TooltipBackgroundColor || 'black',
padding: '10px',
borderRadius: '10px',
zIndex: '5000',
textAlign: 'center',
...tooltipPositionStyles
}
// Set all of the arrow styles after determining if the tooltip is on top or on bottom.
setTooltipArrowStyles(tooltipArrowStylesObj);
setTooltipStyles(tooltipStylesObj);
} else {
// If the showTooltip variable is false, hide the tooltip.
setTooltipArrowStyles({});
setTooltipStyles({display: 'none'});
}
}, [showTooltip, verticalMousePosition, TooltipBackgroundColor, TooltipTextColor, isSwiper])
return (
<>{TooltipText !== undefined && TooltipText.trim() !== '' && TooltipText !== 'None' && TooltipText !== 'Inset Tooltip Text Here' && showTooltip ?
<div className='TooltipDiv' style={tooltipStyles}>
<span className="ToolTipText" style={{fontSize: TooltipFontSize || '12px'}}>{TooltipText}</span>
<span className="ToolTipArrow" style={tooltipArrowStyles}></span>
</div>
: null}</>
);
}
export default Tooltip;
So the code is passed the vertical mouse position as a prop and if the mouse is within 250 from the top of the page the tooltip is rendered below the component hovered. It all works fine if the component renders above and the mouse is lower down the page because there is nothing above to obstruct the tooltip, but when the component renders below, with bottomTooltipStyles, it is absolutely positioned but the issue is it is rendering behind another component. My gut said it was obviously the z-index, but this tooltip has a zIndex of 5000 which is significantly larger than the next largest z-index on the page at 60. Checking google chrome dev tools, the styles are all appropriate, the component renders, but it is still somehow behind/hidden behind another component no matter what I do. Any ideas would be greatly appreciated!! Thanks in advance!
So my question can also be asked like, "Is there a css property that would cause an element to render 'above' (over) another element that has an arbitrarily high z-index?"
Most of the gotchas with z-index have to do with "stacking context".
Elements are stacked on the z-axis within their stacking context.
Elements without position or explicit z-index values all share the same stacking context and are rendered in order of appearance in the rendered HTML.
Here are some specific z-index gotchas related to stacking context that may be affecting you:
1. z-index only applies to positioned elements
That is, position: absolute, position: relative, position: fixed, or position: sticky) and flex items. [1]
So first, make sure the elements you want to position on the z-axis are all explicitly positioned.
2. Some css properties can move an element into a new stacking context.
Some common ones are opacity and transform. Here is a list of CSS properties that can affect the stacking context.
And here is a detailed explanation on how opacity values affect stacking context:
Since an element with opacity less than 1 is composited from a single
offscreen image, content outside of it cannot be layered in z-order
between pieces of content inside of it. For the same reason,
implementations must create a new stacking context for any element
with opacity less than 1. If an element with opacity less than 1 is
not positioned, then it is painted on the same layer, within its
parent stacking context, as positioned elements with stack level 0. If
an element with opacity less than 1 is positioned, the ‘z-index’
property applies as described in [CSS21], except that if the used
value is ‘auto’ then the element behaves exactly as if it were ‘0’. [2]
To fix these, explicitly set the position and z-index so that they will be evaluated relative to the other positioned elements.
3. If an element's parent z-index (and position) is set, then that element's z-index will only apply within the parent.
In other words, the parent element is the stacking context.
To fix this, you can either modify the HTML hierarchy, or remove the position of the parent, or modify its z-index.
There are some good visuals and code examples for these situations here: https://www.freecodecamp.org/news/4-reasons-your-z-index-isnt-working-and-how-to-fix-it-coder-coder-6bc05f103e6c/
I had the same issue when rendering multiple components in one parent component. My popup div didn't appear on top of other components even though it had a higher z-index.
After a little bit of research, I found this answer helpful.
I had to move the popup component above everything else.
Also, please fix your code snippet so we can find out exactly what's wrong.

Adding panels with fixed 2 rows and multiple columns dynamically

I want to add a panel dynamically with this structure. It should grow in a column and also if I delete panel in middle next panels should move before.
Panel1 panel3 panel5 ....
Panel2 panel4 panel6 ....
I tried the column layout but its growing in columnwise. I tried to update the layout with
vertical: true.
if (itemLength % 2 === 1 && itemLength !== 0) {
container.setLayout({
vertical : true
})
} else {
container.setLayout({
vertical : false
})
}
Nothing seems to work.
You can use hbox layout for container in which you want to add panels horizontally and vbox for vertically.
{
xtype: 'panel',
layout: {
type: 'hbox',
align: 'stretch'
}
},
And provide flex to adjust height and width accordingly while adding or deleting.
flex: 1;
Here You can find the working fiddle for your scenario. When you click on add button, a panel will be added to your container horizontally having a delete button and width will be adjusted accordingly and same will be taken care on deletion.

React native responsive header height

Im trying to set my header height so its responsive for tablets and smartphones. I've have tried using flex column:
const headerStyle = {
paddingHorizontal: theme.metrics.mainPadding,
paddingTop: 0,
paddingBottom: 0,
backgroundColor: theme.colors.blue,
flex: 0.5,
flexDirection: 'column',
};
However, the header looks ok on a tablet but too tall on a smartphone.
What is the best way to set dimensions for different devices?
EDIT:
I have this function:
export function em(value: number) {
return unit * value;
}
And I am now using it in my stylesheet:
headerHeight: em(6),
headerImageWidth: em(3),
headerImageHeight: em(3),
headerLogoHeight: em(6),
headerLogoWidth: em(20),
The image looks ok on tablet, but now on smartphone its too small. If i understand correctly, I need to use dimensions.width to set an appropriate unit value in my function?
Smartphone
Tablet
I can think of two ways
Using flex
<View style={{flex:1}}>
<View style={{flex:0.2}}>
<Text>Header</Text>
</View>
<View style={{flex:0.8}} />
</View>
You have mentioned using flex, but not working. I am not sure how exactly as if you are using it like above, size should be relative to screen size.
Using Dimensions
How about using the Dimensions module. It can be used to get the width and height of the window and you can set height based on that
import {
Dimensions
} from 'react-native';
const winWidth = Dimensions.get('window').width;
const winHeight = Dimensions.get('window').height;
header = {
height: winHeight * 0.2 // 20%
}
Then use width and height to set the height of the header (ex. percentage-based)

Fit container inside element with table layout

I need to fit a container inside a table cell. Currently, I am unable to do so, and the container only shows when I manually set its height.
Here it is a fiddle showing the issue.
https://fiddle.sencha.com/#fiddle/13ug
If I set the container height to (say, 300), the container is displayed. However, I would like the container to automatically fit the colspan/rowspan and resize according to the table.
Could I please get some help? Thanks!
This will auto size the container to fill 100% of the cell height - even if the cell height increases.
initComponent: function() {
var me = this;
var tester2 = Ext.create("Ext.container.Container");
Ext.apply(tester2, {
height: "100%",
layout: "fit",
style:"background-color: red",
colspan: 5,
rowspan: 2,
});

Centering text field in Titanium Mobile

How do I center a text field in Titanium? Here's the text field code:
var textfield1 = Titanium.UI.createTextField({
color:'#006',
backgroundColor:'#fff',
height:50,
top:'auto',
left:'auto',
width:300,
borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED
});
If your parent uses a vertical layout, it's auto centered. 'auto' top will be 0 ; remove your left.
You can also use textAlign : 'center' in other layouts.

Categories