How to content size of UIScrollview in Autolayout - ios7

i want to add 5 views of same size of simulator using UIScrollview. How could i can do? Specially content size of UIScrollview want to set which is approximately equals (320,2840) ?

Looking at your requirement, you need the srollview to scroll vertically as (320,2840)(w,h). While doing this auto layout doesnt create any problem as once your scroll view is set, the 5 views inside id doesnt need to be set via autolayout.
1) First create a Scrollview and set its position on a view. create and IBOutelet for scrollView and then in our viewDidAppear sets its content size to 320,2840 like this
[scrollView setContentSize:CGSizeMake(320, 2840)];
and then create your UIViews in a for loop and add them inside your scrollview with a help a variable say "y" which sets your UIviews y co-ordinate everytime before adding it to your scrollview.
like this
int y = 0;
for (int i = 0; i < 5; i++) {
UIView *insideviews = [[UIView alloc]init];
insideviews.frame = CGRectMake(0, y, 320, scr.frame.size.height);
insideviews.tag = i; // to distinguish them and use later
[scr addSubview:insideviews];
y = y + scr.frame.size.height;
}
thats its, if you still have any problem tell me else you can accept the answer :) Good Luck

Related

UITableView with right/left swipable cells perform slow and struck?

I need to list set of products in swipe(slide functionality) based on different category, I have used table view to do this, Table view cell count will be number of categories and Single category products in single cell with swipe, center part needs to load based on products in slide(you can check attachment) by clicking left/right arrows or swipe.
Please check below code(added in custom cell implementation file), We believe , struck is due to again and again load of xib. Please suggest some good solution to do this slide functionality inside tableview cell other than using xib or any other suggestion on reuse xib , how to do that?
int xOffset = 0;
self.scrollView.contentSize = CGSizeMake(scrollWidth * noOfImages, scrollHeight);
for(int index=0; index < articleDetails.count; index++) {
UIView *menuOverlay = [[UIView alloc]initWithFrame:CGRectMake(xOffset, 0, scrollWidth, self.scrollView.frame.size.height)];
menuOverlay.backgroundColor = [UIColor clearColor];
SampleXIBView *xibView = [[[NSBundle mainBundle]loadNibNamed:#"SampleXIBView" owner:self options:nil]objectAtIndex:0];
xibView.frame = CGRectMake(35 , 0, scrollWidth-70, scrollHeight);
[menuOverlay xibView];
[self.scrollView addSubview:menuOverlay];
xOffset += scrollWidth;
}
Thanks in Advance.

How to get the padding from the edge of the UITableview to the UITableViewCell

On the iPad, the Grouped style tableview's cells are inset deeper from the edge of the tableview than on the iPhone.
I need to retrieve the Left and Right distances from the edges of the tableview to where the cell begins. What i'm referring to is similar to "Margins". I read the UITableview API up and down and can't find a property that returns this.
I need to use this in calculation to compute where to position content in my cells.
Thanks in advance!
Alex
I haven't tested this but i'm pretty sure you should just be able to pick up the frame of both and then compare from there.
CGRect cellFrame = yourCell.frame;
CGRect tableFrame = yourUITableView.frame;
The CGRect values are (x coordinate, y coordinate, width, height).
Also you can just print out the frames using :
NSLog(#"your cell frame is %#",NSStringFromCGRect(yourCell.frame);
NSLog(#"your table frame is %#",NSStringFromCGRect(yourUITableView.frame);
I solved this with overriding the layoutSubviews call for the iPad and setting the grouped view margins to what I want them to be, rather then what the apparently hidden value is. Other answers in Stack point out that it can vary from 10 to 45 pixels in width.
In your CustomTableViewCell class
- (void)layoutSubviews
{
CGRect f = self.bounds;
f = CGRectInset(f, 10, 0);
self.contentView.frame = f;
self.backgroundView.frame = f;
}
You could force it to keep contentView and backgroundView to be equal to that of the TableCell width which is that TableView width, but in this case I still wanted my grouped view to be inset a little bit. It also allows you to better match with a custom header/footer view which will go edge to edge without work.

Speed up ios function

I really need help with this!
I'm building a map containing loads of tiles.. like 200x200 small 50px tiles. These tiles resides in an UIScrollView so that I can drag myself around the map! Works really nice right? Well it's super slow since there are too many subviews in the map.
Right, so I load the subviews as I scroll then! Problem is, that takes some time too, makes the scrolling a bit laggy/slow. Can you help me improve this function? I'm out of ideas. Found the Grand Central Dispatch but I'm not sire how to use it.
Here's my code
-(void)loadMapTiles {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(1, queue,
^(size_t row) {
int radiusX = 11;
int radiusY = 7;
int y = currentCoord.y-radiusY;
for(int x = currentCoord.x-radiusX; x < currentCoord.x+radiusX+1; x++) {
int currTag = mapSize.width*(y-1)+x;
if(![mapScroller viewWithTag:currTag]) {
UIImageView *mapTile = [[UIImageView alloc] initWithFrame:CGRectMake(50*x, 50*y, 50, 50)];
int mapNo = (rand() % 20) + 1;
if(mapNo > 11) {
mapNo = 1;
}
mapTile.image = [UIImage imageNamed:[NSString stringWithFormat:#"desert_map%d_50.gif", mapNo]];
//Tag the mapTile so that we can find it again!
[mapTile setTag:currTag];
[mapContentView addSubview:mapTile];
[mapTile release];
}
if(x == currentCoord.x+radiusX && y < currentCoord.y+radiusY) {
x = currentCoord.x-radiusX-1;
y++;
}
}
//Remove the other tiles outside the radius!
for (UIView *mapTile in [mapContentView subviews]) {
if(mapTile.frame.origin.x / 50 < currentCoord.x-radiusX || mapTile.frame.origin.x / 50 > currentCoord.x+radiusX || mapTile.frame.origin.y / 50 < currentCoord.y-radiusY || mapTile.frame.origin.y / 50 > currentCoord.y+radiusY) {
[mapTile removeFromSuperview];
}
}
});
}
And the function to call the map-building function above:
-(void)scrollViewDidScroll:(UIScrollView *)myScrollView {
CGPoint newCoord = CGPointMake((int)(myScrollView.contentOffset.x + myScrollView.frame.size.width/2) /50, (int)(myScrollView.contentOffset.y + myScrollView.frame.size.height/2) /50);
if(newCoord.x != currentCoord.x || newCoord.y != currentCoord.y) {
currentCoord = newCoord;
[self loadMapTiles];
}
}
You'll want to have a look at CATiledLayer. It lets you do what you want in a nice way regardless of how big your map is. It also supports having different images for different zoom levels.
I'm no obj-c developer but...
At a talk I was at a while ago on mobile web development, they recommend to re-use memory rather than allocate and free it.
Instead of creating a new UIImageView for every tile, could you have enough of them pre-allocated to for the whole screen and just change the images in them as the map is scrolled?
Maybe you should try using CoreGraphics and layers instead of scrollview to draw map and scroll it.
Look at WWDC 2010 video "Designing apps with scrollviews" and the corresponding sample code "PhotoScroller" there you will learn the big trick of "view reuse" in scrollViews.
WWDC 2011 video of similar name is a continuation of the same trick.
"Views that are no longer in the visible area should be reused and repositioned for displaying new stuff"
Adding and removing subviews while scrolling is bound to cause slow downs. Instead you should just reposition the non visible ones and show new stuff.
Other usual causes of scrolling problems are
layer.cornerRadius
layer.shadow (without setting shadowPath)
any opacity on subviews.
Always profile your code on device using core animation.

Add lots of views to NSScrollView

I'm trying to add one subview (view from an NSViewController) for every element in a dictionary to a NSScrollView to get kind of a tableview, but with much more flexibility over the cells.
Is it possible to place (programmatically) e.g. 100 subviews underneath each other so that you have to scroll down the NSScrollView to get to the last element?
The short answer is yes. I have done this before, and I assure you that it will work. Let me also assure you that it is not quite as simple as it looks ;)
The way to do this is to maintain one content view, in which you add all of your custom rows as subviews programmatically. Note that you will either have to resize the contentView before adding all of the rows, or you will have to turn off autoresizing for the row views. Set the documentView of your scrollView to this custom contentView, and you should be good to go.
Yes, simply initialize the views programmatically using (i.e.)
NSView *subView = [[NSView alloc] initWithFrame:CGRectMake(10,10,100,100)];
then add to the main using addSubview: method of the main view.
Remember to manually release the subview when you've done with it (that means, when you have added it to the main view).
As example you can do something like
int height x = 10, y = 10, width = 100, height = 100;
for(int i = 0;i<100;i++) {
NSView *subView = [[NSView alloc] initWithFrame:CGRectMake(x,y + height*i,width,height)];
[scrollView addSubview:subView];
[subView release];
}

Scrollable UINavigationBar similar to Mobile Safari

My application uses a UINavigationController and the final view (detail view) lets you view an external website within the application using a UIWebView.
I'd like to free up some additional screen real estate when the user is viewing a webpage and wanted to emulate how Safari on iPhone works where their URL bar at the top scrolls up and off the screen when you're viewing content in the UIWebView that's below the fold.
Anyone have ideas on how to achieve this? If I set the navigationBarHidden property and roll my own custom bar at the top and set it and a UIWebView within a UIScrollView then there are scrolling issues in the UIWebView as it doesn't play nicely with other scrollable views.
Based on #Brian suggestion I made this code:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat height = navigationBar.frame.size.height;
CGFloat y = scrollView.bounds.origin.y;
if (y <= 0) {
CGRect frame = navigationBar.frame;
frame.origin.y = 0;
navigationBar.frame = frame;
} else if (tableView.contentSize.height > tableView.frame.size.height) {
CGFloat diff = height - y;
CGRect frame = navigationBar.frame;
frame.origin.y = -y;
navigationBar.frame = frame;
CGFloat origin = 0;
CGFloat h = height; // height of the tableHeaderView
if (diff > 0) {
origin = diff;
h = y;
}
frame = tableView.frame;
frame.origin.y = origin;
frame.size.height = tableView.superview.frame.size.height - origin;
tableView.frame = frame;
CGRect f = CGRectMake(0, 0, tableView.frame.size.width, h);
UILabel* label = [[UILabel alloc] initWithFrame:f];
tableView.tableHeaderView = label;
[label release];
}
}
My code has a UITableView but should work with any scrollable component. If you have other components than the navigationBar and the UIScrollView subclass, you should change the way the height of the scrollable component is calculated. Something like this:
frame.size.height = tableView.superview.frame.size.height - origin - otherComponentsHeight;
I needed to add a dumb tableHeaderView to have the desired behaviour. The problem was that when scrollViewDidScroll: is called the content has an offset, but the apparience in Mobile Safari is that the content is not scrolled until the navigationBar fully disappears. I tried first changing the contentOffset.y to 0, but obviously it didn't work since all the code relies on the scrolling mechanism. So I just added a tableHeaderView whose height is exactly the scrolled offset, so the header is never really seen, and the content appears to not scroll until the navigationBar fully disappears.
If you don't add the dumb tableHeaderView, then the scrollable component appears to scroll behind the navigationBar.
With the tableHeaderView, the scrollable component is actually scrolling (as seen in the scrollbar), but since there is a tableHeaderView whose height is exactly the same than the scrolled offset, the scrollable content appears to not be scrolling until the navigationBar fully disappears:
Have a delegate for the scrolling events in the UIWebView and when you initially start scrolling the UIWebView, have the UIWebView increase in height and have it's Y position decrease at the same time while simultaneously shifting the nav bar up in the Y direction. Once the nav bar has been completely shifted out of view, stop increasing the size of the UIWebView and just allow normal scrolling to occur.
This will give the illusion of the nav bar being part of the UIWebView as it scrolls off the screen.
Also, you'll need to do the reverse when you are scrolling in the opposite direction and are reaching the top of the content of the UIWebView.
Can't give you a straight answer, but have a look at iWebKit. Maybe that provides a solution. The demo, at least, contains a "full screen" item.