How do I obtain information about the pages in a UIScrollView? - iphone

I have a run of about 10 different methods, they all pass "page" and "index" between them in order to define a ScrollView with multiple pages. The majority of these methods run within a loop (for each page).
I'm working on a way to re-orient and re-position the pages depending on the device orientation. My trouble now is trying to get access to these multiple pages so I can run a method re-orienting them. Is there a way to loop through the pages and access their information (size, frame, contentSize etc.) so I can then just manipulate them?

You could put a pointer for each view into an array. Then iterating through the array config the Views like this:
-(void)configScrollViewForOriantation:(UIInterfaceOrientation)interfaceOrientation
//do an if on the oriantation and supply 2 versions...
//eg..
if(UIInterfaceOrientationIsPortrait(interfaceOrientation))
{
CGRect f;
for (UIViewController *page in pageArray) {
f = page.frame;
f.size.width = ..;
f.origin.x = ....;
page.contentSize = CGSizeMake(newWidth,newHeight)
//etc
}
else{
//landscape config
}
}
NB. If you called this method in a CAAffine animation it would animate the changes too.
Ideally you should only make one for loop and set some constants for the configs you are going to do based on the orientation.

Create a class that knows about the model data, and can divide it up into numbered pages. Now pass that object between your methods, instead of the raw page/index values. Now extend that object to work with your other orientation.

Related

How to tell UICollectionView to preload a larger range of cells?

I have a UICollectionView which shows images retrieved from the web. They are downloaded asynchronous.
When user scrolls fast, they see placeholders until the cell loads. It seems UICollectionView only loads what is visible.
Is there a way to say "collection view, load 20 cells more above and below" so chance is higher that it loaded more cells while user was looking at content without scrolling?
The idea is to have the VC recognize when a remote load might be required and start it. The only tricky part is keeping the right state so you don't trigger too much.
Let's say your collection is vertical, the condition you want to know about is when:
BOOL topLoad = scrollView.contentOffset.y < M * scrollView.bounds.size.height
or when
BOOL bottomLoad = scrollView.contentOffset.y > scrollView.contentSize.height - M * scrollView.bounds.size.height
in other words, when we are M "pages" from the edge of the content. In practice though, this condition will be over-triggered, like when you're first loading, or if you're testing it on scrollViewDidScroll, you don't want to generate web requests for every pixel of user scrolling.
Getting it right, therefore, requires additional state in the view controller. The vc can have a pair of BOOLs, like topLoadEnabled, bottomLoadEnabled, that are NO until the view is ready. Then, scroll delegate code looks like this:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// compute topLoad and bottomLoad conditions
if (topLoad && self.topLoadEnabled) [self startTopLoad];
similarly for bottom. The load code looks like this, abstractly:
self.topLoadEnabled = NO; // don't trigger more loading until we're done
[self.model getMoreTopStuff:^(NSArray *newStuff, NSError *error) {
// do view inserts, e.g. tableView.beginUpdates
self.topLoadEnabled = YES;
}];
Same idea for bottom. We expect the model to fetch for itself (maybe the model has image urls) and cache the result (then the model has images). As the datasource for the view, the view controller gets called upon to configure view cells. I can just naively ask the model for images. The model should answer either fetched images or placeholders.
Hope that makes sense.
In my opinion you are making the wrong assumption: cells are just views so you shouldn't treat them as model objects. UICollectionView and UITableView are very efficient because they constantly recycle cells so you should think in therms of pre loading content in the business side of things. Create interactor or viewmodel objects and populate your data source with those, then you'll be able to ask those objects to preload images, if you still wish to do so.
A BOOL flag seldom is the answer. I'd rather go for estimating a reasonable page size and fetching images as needed from the cellForItemAtIndePath method.

How to query the child views of a parent view using Titanium?

I am looking to create a general purpose routine that will operate over a view's children. Within the routine I need to be able to iterate over the child views. I don't see anything in the API that would suggest that there is any way to get the child views. There is an "add()" and a "remove()" method but nothing like "get()" nor does there appear to be any properties like "views". What am I missing?
this is the basic structure for removing child objects from a view
if (view.children) {
for (var c = view.children.length - 1; c >= 0; c--) {
view.remove(view.children[c]);
}
}
i would check also for
if (view.children[c] !== undefined) {..}
since i already got problems with android without verifieing.

Zend frame work multiple view from single action

Can anyone tell me how can i make more then one view through single action.
actually I have a controller action fetching data from model but I have to show data in 2 different views (half data in 1st and rest in 2nd)
I know it is possible.
Can any one explain how it will be implemented.
I'm not entirely sure whether you mean having two different views depending on a condition or two views at the same time.
From the action you can use:
$this->renderScript( 'views/page.phtml' );
and you can use multiple renderScripts and they will stack up and render in the order that they are called. Or you can have a condition separating them.
if($blah)
{
$this->renderScript( 'views/page.phtml' );
return;
}
else
{
$this->renderScript( 'views/page.phtml' );
return;
}
Is this the sort of thing you mean?
Just use the render method of the controller action to display the view you want.
Refer to Rendering Views in the Zend reference manual for more information (you could also use Named Segments if needed/applicable).

Using tags in iphone programming--can someone explain?

I've seen people using tags in iphone programming, like inside labels or tableview cells:
name.tag = kNameTag
Can someone explain with an example how these tags might be used? I gather that it's so that you can refer to a ui element later? Like if you programmatically use a for loop to create an array of UIButtons onto the iphone screen, do you assign tags to each button within the for loop or something?
Thanks!
The example you've included in your question is one of the common ones.
You can instantiate buttons (or other UI elements) in a loop, assigning a incremental tag to each. When an IBAction is invoked by one of those buttons, you can ask the sender for it's tag, which tells you exactly which button triggered the request.
for( int i = 0; i < 10; i++ ) {
UIButton * button = [[UIButton alloc] init...];
button.tag = i;
}
IBAction:
- (IBAction)doSomethingFromButtonTap:(id)sender {
NSLog(#"Button pressed: %d", [sender tag]);
}
They're also widely used to find specific subviews within a parent view. UIView provides a viewWithTag:(NSInteger)tag method. This is useful when building custom views without subclassing (or situations where you don't want to hold references to subviews, but know the tag).
Tags are integers. You assign them to a view using UIView.tag. You then use -[UIView viewWithTag:] to search the view hierarchy for the view.
UIKit doesn't use tags (I think), so they're free for you to use as necessary. However, tags are global to your app, so they're not an ideal replacement for IBOutlet (but it's often more convenient when you have a lot of views).
Avoid using 0 as a tag, since it's the default tag — [v viewWithTag:0] is unlikely to return the view you're looking for.

Drawing the UIPicker values from multiple components?

I have the UIPicker setup with multiple components and a button below it. Depending on what the user has chosen with the UIPicker determines which new view will be loaded but I am having trouble determining how to extrapolate the information from the picker itself. Right now I have this method being called when the button is pressed:
- (IBAction) buttonPressed {
if (component:1 == 1 && component:2 == 1) {
//Load the view number 1.
} else if (component:1 == 2 && component:2 == 1) {
//Load the view number 2.
} else {
//Load the view number 3.
}
}
I obviously know that my code is wrong but I hope it gets the point across. I have multiple components and I need to figure out how to use the information that the user is scrolling to on the picker to determine which view to move to. (I know how to load the views, I just commented those in the code to illuminate the problem areas better.)
How do I go about using the pickerViews to extrapolate the information IN the buttonPressed IBAction method?
To respond directly to picker manipulation, use the delegate's pickerView:didSelectRow:inComponent:.
To obtain the view corresponding to user selection, use viewForRow:forComponent:. From that view you can obtain information about what it displays (if it's a UILabel, inspect its text property).
Also, you can obtain this information directly from the data source, referring to the piece of information you would return in the delegate's pickerView:titleForRow:forComponent: or pickerView:viewForRow:forComponent:reusingView:, for the currently selected row and component.