Setting ScrollView Height - titanium

I have a window. That window has a header (variable size) and should have a scrollable body that sits directly under the header. How can I set the height of the body so that it actually scrolls? If I set height: 'auto', the body extends beyond the bottom of the viewport to fit all of its content. If I set its top and bottom properties, nothing shows up at all.
I can't imagine that I'm the only one who's come across this, but I haven't found a single definitive answer for how to create properly sized, scrollable view within a window. Heights seem tricky since the value is so different in portrait and landscape modes on a single device, much less across devices.
Can someone provide tips on how to manage this scenario? I'm hoping I can extrapolate it to handle other view height scenarios.
Thanks.

It depends on what you are trying to achieve. If you're trying to create a ScrollView that just has the ability to scroll when empty, you should add a empty View into the ScrollView, which has the "top" property.
For example:
var win = Ti.UI.createWindow();
var scrollView = Ti.UI.createScrollView();
var emptyView = Ti.UI.createView({top: 460});
scrollView.add(emptyView)
win.add(scrollView);
Note that the "top" property has 460 set, which is 40 bigger than the iPhone screen res of "420". This will case the scrollView to scroll. If you're looking for a specific size based on the window's navBar controlTitle, you will have to run an equation based on what you think the size will be, applying that size to the view's "top" property accordingly.

Related

Codenameone Slider cannot set height

I am finding it difficult to set the right look and feel of a CN1 Slider control. Essentially i want it to look like the one in the CN1 Default Demo of the Theme window, and have it with the Thumb image to allow the user to set the scroll.
But when i code it up as per online examples, it comes out skinny on the simulator (as below)
...but doesn't display the line at all on the actual iphone device.
When i start messing with the methods, such as 'getSliderEmptyUnselectedStyle()' then this makes the background show and can see the progress but its tall and i cannot seem to shrink it.
Container container = new Container(new FlowLayout());
container.getAllStyles().setBgTransparency(255);
container.getAllStyles().setBgColor(0xffffff);
Slider slider = new Slider();
// slider.getAllStyles().setFgColor(0);
// slider.getAllStyles().setMarginLeft(0);
// slider.getSliderEmptyUnselectedStyle().setBgTransparency(255);
// slider.getSliderFullUnselectedStyle().setBgTransparency(255);
// slider.getSliderEmptySelectedStyle().setBgTransparency(255);
// slider.getSliderFullSelectedStyle().setBgTransparency(255);
// slider.getSliderEmptyUnselectedStyle().setBgColor(0xffffff);
// slider.getSliderFullUnselectedStyle().setBgColor(0x42B72A);
// slider.getSliderEmptySelectedStyle().setBgColor(0xffffff);
// slider.getSliderFullSelectedStyle().setBgColor(0x42B72A);
Style sliderStyle = UIManager.getInstance().getComponentStyle("Label");
sliderStyle.setFgColor(0);
slider.setThumbImage(
FontImage.createMaterial(FontImage.MATERIAL_RADIO_BUTTON_CHECKED, sliderStyle, 4).toImage());
slider.setMinValue(0);
slider.setIncrements(25);
slider.setProgress(entity.getCompletion_pct());
slider.setEditable(true);
container.add(slider);
return container;
How can i get it pretty much to the CN1 example?
Thanks
The slider in the example used a 9-piece border or a 3-piece border both of which have a fixed minimum height/width. This minimal height is applied to the way the slider is rendered.
Your code can be made thicker with padding but it will create a problem when you add a thumb. Once you add the thumb it will increase the overall size and make the entire height of the thumb have that background. So you need to style this via the designer and for this specific case you would want to use an image border that is carefully measured to align with the thumb image.
Also notice you used getAllStyles() which is wrong. Slider is a special case and uses the Slider and SliderFull UIID so effectively the component has two UIID's and two separate sets of Style objects.

Titanium: How to determine the screen width when using SplitView?

I'm used to using Titanium.Platform.displayCaps.platformWidth all over my app to get the width of the window.
But with SplitView on the iPad Titanium.Platform.displayCaps.platformWidth still returns the total screen size of the iPad (as it probably should).
How can I determine the actual available screen width for the app while using SplitView?
I don't mean SplitWindow BTW. This is in regards to SplitView where you can line up two different apps next to each other on the iPad
Thank you!
you can get the width your uiElement using postLayout event
var uiWidth;
myElement.addEventListener('postlayout', postlayout);
function postlayout(e){
uiWidth = e.source.rect.height;
myElement.removeEventListener('postlayout', postlayout);
}
An easy way to determine how wide a certain view is, is to use toImage() on the UI element, and then get the size.
So... when you do
console.log($.myWindow.toImage().rect.width);
You should get the width of the window. Which should be the width allocated to your app.

NSFullSizeContentViewWindowMask and title/toolbar height?

I am attempting to implement something similar to Safari where the window's style mask is set to NSFullSizeContentViewWindowMask so the NSToolBar and title bar blur the background view.
This works fine, however I have a view that I need to not be clipped by the toolbar/titlebar, similar to how Safari's WebView has an initial top padding that doesn't cover the content when the view is unschooled.
My attempted solution was to create a dummy NSView which the unclipped views align their top value to, then changing the height constant of the dummy view to the height of the titlebar/toolbar. The issue, however, is that there seems to be no way to calculate the height of the toolbar.
This suggests that I calculate the height by subtracting the height of the contentView from the height of the window, but that only works (returns 0 otherwise as the two heights are equal) if I don't use NSFullSizeContentViewWindowMask which I want to use for the blurring effect.
Am I overlooking something simple, or is there no simple way to accomplish this?
Check NSWindow's contentLayoutRect property.

How to replace a view

Application requires more than one window (Lets call A,B,C). Each window has more than one view (table views, image views as well as web view). Lets say window A has three views (x, y,z) and window B has three views (d,e,f). Application needs to display images of different size on orientation change.
I have achieved the same using gesture event listener and looping through windows for views and replacing the view with new images. The problem I have is when we navigate from one window to other and the orientation changes, the loading of view after looping goes for a toss. Is there a better way to achieve the same ?
Is there a method in titanium like following code to replace a view ?
var self=Ti.UI.currentWindow
var newView=Ti.UI.createImageView({image:'abc.png'})
self.replace(self.children[1],newView )
Unfortunately there is now replace method.
You need to remove the whole view and add it again but this can cause a wrong layout if you have more than one view on a same level. The implementation then depends on the layout which was set (vertical, horizontal, composite etc).
For example in vertical layout removing an item and simply add a new one would remove your specified item but appends the new one at the end since you can't specify in which order it should be added.
If you have a composite layout you can specify absolute positions but adding a new view causes a higher zIndex for this view so that it will hide views that were previously added at the same/similar position.
Why not simply change the image link ?
var self = Ti.UI.currentWindow;
self.children[1].image = 'bcd.png';
Well you could always lock the orientation of your window. But this isnt exactly good practice (especially for iOS).
Generally orientation changes are handled pretty well if you define the width and height of your views to be percentages or Ti.UI.FILL, if you have a composite layout. Check that you are not giving the views absolute coordinates as this could cause layout problems. If you have a vertical or horizontal layout you usually don't have to worry about orientation change, unless you did not nest your views in a main container correctly.
Prasad,
If this is about just ensuring that the images look good on different orientations,you can make use of the different folders provided by Titanium in the android/images folder.You can just make different images for each of the orientations and device sizes.For IOS you can change just the images on orientation change as you are already doing.
https://wiki.appcelerator.org/display/guides/Using+density-specific+resources+on+Android
If you are concernced about the layout there are couple of things you can do:
1.Give all the height or width values in percentages.This way all elements will be re sized once the orientation changes automatically.
2.On each window open check if the orientation is vertical or horizontal by default and accordingly set the image attribute of the imageView.
Ti.UI.orientation
This property will give you the orientation of the window by default.Values of this property could be this
Ti.UI.PORTRAIT
Ti.UI.UPSIDE_PORTRAIT
Ti.UI.LANDSCAPE_LEFT
Ti.UI.LANDSCAPE_RIGHT
Use "if else" and accordingly set the images.

I can't understand UIScrollView behavior

I've read a lot of documentation but still don't really understand how that UIScrollView works.
I have an example where I use an UINavigationViewController with the status bar (little top bar with wifi, battery, etc., icons) and a navigation bar (with the "back" button).
As the first subview of the UINavigatioViewController's main view I have a UIScrollView. Inside it I have created several subviews that make it's contents size to be 500 points.
In the "viewDidLoad" method I set the scroll view's "contentSize" equals to 500. But it doens't completely scroll down to show the last subview.
I read that I should add some points to the "contentInset" because of the "bars". I don't really know why. Isn't the scroll view inside the main view that is correctly framed? Why does it need to take the "bars" into account?
Anyway, I read that it should be like 64 points (44 navigation bar + 20 status bar). But it doesn't work.
The "magic" number (at least for me) is 84 points. I must add that quantity to the content size (584) or use it as:
self.scrollView.contentInset=UIEdgeInsetsMake(0.0,0.0,84.0,0.0); // AT THE BOTTOM!!
I'm really confused about this. Could anyone give a hand on understanding it?
Thanks.
self.scrollView.contentInset=UIEdgeInsetsMake(0.0,0.0,84.0,0.0);
UPDATE
I have seen that because I made my ScrollView size bigger in Interface Builder in order to add new elements beyond the normal small visible size, it had a "frame" size near to 500 points.
I set it frame size to 416 (just to fit and cover all the visible space) and now with a content size of 500 points (without any additional inset values) it scrolls perfectly.
But I still don't understand the previous behavior...