I have a scrollview that automatically generates a series of subviews containing imageviews. The concept is that it's pretty much a custom PDF style reader, where each page is loaded in to an imageview as an image. There are three "layers" - the outer UIScrollView, the automatically generated subViews and the imageview inside the subview.
I've been having some trouble with this, I've asked the question previously, but unfortunately, the core of my question was in the wrong place. Here is my second attempt:
On rotate, everything is rotated as needed. Unfortunately, this is what I'm getting:
Obviously, I would like Image 1 to be centred and for there to be no hint of image 2 until you flick the view across.
Here is my code for setting up the view:
- (void)loadView {
[self setUpView];
}
- (void)setUpView {
//INITIALISE PAGING SCROLL VIEW
CGRect pagingScrollViewFrame = [[UIScreen mainScreen] bounds];
pagingScrollViewFrame.origin.x -= 10;
pagingScrollViewFrame.size.width += 20;
pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
pagingScrollView.contentMode = UIViewContentModeScaleAspectFit;
//CONFIGURE PAGING SCROLL VIEW
pagingScrollView.pagingEnabled = YES;
pagingScrollView.backgroundColor = [UIColor blackColor];
pagingScrollView.contentSize = CGSizeMake(pagingScrollViewFrame.size.width*7, pagingScrollViewFrame.size.height);
//ACTIVATE PAGING SCROLL VIEW
self.view = pagingScrollView;
//ADD PAGES TO SCROLL VIEW
for (int i = 0; i < 7; i++){
ImageScrollView *page = [[[ImageScrollView alloc] init] autorelease];
[self configurePage:page forIndex:i];
[pagingScrollView addSubview:page];
}
}
How do I re-define the size of the frame? What function should I call etc. How do I centre the image?
I'm new to this so I apologise for the ambiguity of my question.
Cheers
I've figured it out. It was the Frame of the individual pages that I needed to change, so (with the help gained from another question) I wrote a re-orient method.
The first step to this came because I figured out that I needed to iterate through and re-size each frame for each of my pages and then re-apply the frames to the view. For this to happen I needed to create an array which I would fill in the For Loop above. I have 7 total pages.
Then I could (on rotate) call the below re-orient method to re-size each view:
- (void) reOrient{
if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){
CGRect f;
int i = 0;
for (ImageScrollView *page in pageArray) {
f = page.frame;
f.size.width = 320;
f.origin.x = (f.size.width * i);
page.frame = f;
pagingScrollView.contentSize = CGSizeMake(f.size.width * 7, 480);
i++;
}
}else{
CGRect f;
int i = 0;
for (ImageScrollView *page in pageArray) {
f = page.frame;
f.size.width = 480;
f.origin.x = (f.size.width * i);
page.frame = f;
pagingScrollView.contentSize = CGSizeMake(f.size.width * 7, 480);
i++;
}
}
}
This worked for me:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
//get current page based on offset before rotation
NSInteger currentPage = self.scrollView.contentOffset.x / self.scrollView.bounds.size.width;
//set anticipated scrollview content size by switching width and height (they will be switched after rotation)
[self.scrollView setContentSize:CGSizeMake(totalPages * self.view.bounds.size.height, self.view.bounds.size.width)];
//set the anticipated content offset based on height before rotation
[self.scrollView setContentOffset:CGPointMake(currentPage * self.scrollView.bounds.size.height, 0.0f)];
}
Basically I am setting the content offset for the new scrollview content size before rotating (I'm switching height and width for the anticipated height and width).
This worked for me when rotating a full-screen paged UIScrollView.
All of the paged subviews have the following autoresizing mask so that they neatly fall into place after rotation:
UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleRightMargin
Related
I need to create an horizontal list with a scroll, this list is made of 10 images, in the screen only fits 1 and a half of these images, so when the user scroll i need to set at the center of the screen an image and besides it a portion on the forward image and backward image. So far what i have is this:
scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 150, 1024, 520)];
scroll.delegate = self;
scroll.pagingEnabled = NO;
int numberOfViews = 10;
float xOrigin = 0;
for (int i = 0; i < numberOfViews; i++) {
xOrigin = i * 600;
FigureImage *tape = [[FigureImage alloc] initCustom];
[scroll addSubview:tape];
FigureImage *pictureFigure = [[FigureImage alloc] initCustom];
[scroll addSubview:pictureFigure];
}
scroll.contentSize = CGSizeMake(numberOfViews*10, 500);
pageWidth = (numberOfViews*10)/numberOfViews;
[self.view addSubview:scroll];
With this code i am able to scroll the images, but the scroll doesnt stop at any particular image, how can i able the last x position to stop the scrolling?
See the delegate method -scrollViewWillEndDragging:withVelocity:targetContentOffset:.
Its last parameter is an in-out CGPoint whose value you can change so that the scroll comes to rest with an image centered exactly.
I have UIScrollview that contains different UITableviews. You can scroll through these UITableviews using a UIPagecontrol.
This is how I add my UITableview to the UIScrollview
- (void)loadPage:(NSInteger)page {
if (page < 0 || page >= self.pageStages.count) {
// If it's outside the range of what we have to display, then do nothing
return;
}
// Load an individual page, first seeing if we've already loaded it
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView == [NSNull null]) {
CGRect frame = self.scrollView.bounds;
//frame.size.width = 280.0f;
frame.size.height = self.scrollView.bounds.size.height;
float offset=20;
frame.size.width = frame.size.width-(2*offset);
frame.origin.x = (326 * page)+offset;
frame.origin.y = 0;
UITableView *tableStage = [[UITableView alloc]initWithFrame:frame];
tableStage.backgroundColor = [UIColor colorWithRed:(250/255.0) green:(248/255.0) blue:(247/255.0) alpha:100];
tableStage.contentMode = UIViewContentModeScaleAspectFit;
tableStage.delegate = self;
tableStage.dataSource = self;
tableStage.tag = page;
tableStage.contentMode = UIViewContentModeScaleAspectFit;
[self.scrollView addSubview:tableStage];
[self.pageViews replaceObjectAtIndex:page withObject:tableStage];
}
}
Now I want that user can jump to a certain UITableview from another UIViewController. Therefore I have a variable pageNumber. When I set the pageNumber I call a method jumpToPage3 and I give the pageNumber with it. This is how the function looks like.
-(void)jumpToPage3:(NSNumber *)page{
NSLog(#"jump to page 3");
float offset=30;
float height = self.scrollView.bounds.size.height;
float width = 320 - (2*offset);
int pagee = [page intValue] - 1;
float x = (320 * pagee) + offset;
[self.scrollView scrollRectToVisible:CGRectMake(x, 0, width , height) animated:NO];
}
The problem is that it is not jumping to the correct page. It stays on the first page.
Can someone help me with this?
When you add content to the scroll view you also have to tell increase the contentSize
I have two subviews of UIScrollView. One is textView and other is tableView. I made textview's height flexible based on its content, but I have one problem. If the text in the textview (which is parsed data) is small, there is a big gap between textview and tableview. Or if the text is too large then it covers the tableview. How can I keep the same gap between textview and tableview irrespective of the amount of content of text view? This is all done in IB.
Thanks.
you must handle both textview and tableview position dynamically like ur text view height and y-axis is
y-axis 10; height 40;
now in tableview setframe:cgrectmake(your X coordinate, textview.frame.size.height+20)
so its always show same difference between textview and tableview if your textview height is 60 than tableview y point is 60+20
- (void)loadView
{
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
pagingScrollView.pagingEnabled = YES;
pagingScrollView.backgroundColor = [UIColor blackColor];
pagingScrollView.showsVerticalScrollIndicator = NO;
pagingScrollView.showsHorizontalScrollIndicator = NO;
pagingScrollView.contentSize = CGSizeMake(pagingScrollViewFrame.size.width * [self imageCount],
pagingScrollViewFrame.size.height);
pagingScrollView.delegate = self;
self.view = pagingScrollView;
}
- (CGRect)frameForPagingScrollView {
CGRect frame = [[UIScreen mainScreen] bounds];
frame.origin.x -= PADDING;
frame.size.width += (2 * PADDING);
return frame;
}
- (CGRect)frameForPageAtIndex:(NSUInteger)index {
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
CGRect pageFrame = pagingScrollViewFrame;
pageFrame.size.width -= (2 * PADDING);
pageFrame.origin.x = (pagingScrollViewFrame.size.width * index) + PADDING;
return pageFrame;
}
I'm a newbe on iOS development, I'm trying to make a scroll header like Engadget's app for iPhone, i created a custom UIView to act as a subview for UIScrollView, the algorithm for placing the subviews seems to be ok as I can Scroll the subviews, programatically i change the background color of the views, but the problem is that I can't see anything of the content, just gray backgrounds what am I doing wrong?
Thanks in advance.
This is my code:
Promoted is a UIView with two labels and a UIImageView.
- (void)layoutScrollSubViews
{
promoted *view = nil;
NSArray *subviews = [sView1 subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[promoted class]] && view.tag > 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
frame.size.height = kScrollObjHeight;
frame.size.width = kScrollObjWidth;
view.frame = frame;
curXLoc += (kScrollObjWidth);
}
}
// set the content size so it can be scrollable
[sView1 setContentSize:CGSizeMake((kNumImages * kScrollObjWidth), [sView1 bounds].size.height)];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad{
NSUInteger i;
for (i = 1; i <= kNumImages; i++)
{
promoted *p = [[promoted alloc] initWithFrame:CGRectMake(0, 0, 320, 187)];
p.title.text = #"Test 1";
p.num.text = #"1/1";
p.num.backgroundColor = [UIColor whiteColor];
// setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
p.backgroundColor = [UIColor colorWithRed:(.9/i) green:(.9/i) blue:(.9/i) alpha:1];
p.tag = i; // tag our images for later use when we place them in serial fashion
[sView1 addSubview:p];
[p release];
}
[self layoutScrollSubViews];
[super viewDidLoad];
}
You can do two things:
1. Add your image view and labels directly to scrollView
2. also alloc your label and ImageView before adding them to your UIView(and don't forgot to release them when requirement is finish, in respective scope)
As per my experience, UIScrollView is a weird buggy control released by apple. Don't know why it behaves abnormal when added through nib file. I always try to create UIScrollView programmatically and add subviews to it by allocating them programmatically as well.
May be it would sound strange, but it works for me most of the time!
I'm ATTEMPTING to learn UIScrollview using Apple's Docs and their sample code http://developer.apple.com/iphone/library/samplecode/Scrolling/index.html but something SO simple is escaping me.
How do you tell what image is currently on the screen, so that if I selected one of the images in the horizontal scrolling view, how would I get the filename of the image, or even a pointer in the array, to then do something further with the image?
I thought with Page Control enable I might be able to find a page # and map it to the image. I thought about counting deceleration to count pages, but a flick no full enough will increment it and give a false number.
The last thing I could think of is to get contentOffSet and divide by image size which will give a 1, 2, 3 and I could point to the array (too tired to try tonight... thought I might ask before I waste a lot more time ;-) ).
Any other ideas? I thought there would be a method somewhere that they use in the photo album app.
PS: Here's the code:
- (void)layoutScrollImages
{
UIImageView *view = nil;
NSArray *subviews = [scrollView1 subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UIImageView class]] && view.tag > 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (kScrollObjWidth);
}
}
// set the content size so it can be scrollable
[scrollView1 setContentSize:CGSizeMake((kNumImages * kScrollObjWidth), [scrollView1 bounds].size.height)];
}
- (void)viewDidLoad
{
self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];
// 1. setup the scrollview for multiple images and add it to the view controller
//
// note: the following can be done in Interface Builder, but we show this in code for clarity
[scrollView1 setBackgroundColor:[UIColor blackColor]];
[scrollView1 setCanCancelContentTouches:NO];
scrollView1.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView1.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview
scrollView1.scrollEnabled = YES;
// pagingEnabled property default is NO, if set the scroller will stop or snap at each photo
// if you want free-flowing scroll, don't set this property.
scrollView1.pagingEnabled = YES;
// load all the images from our bundle and add them to the scroll view
//NSUInteger i;
for (i = 1; i <= kNumImages; i++)
{
NSString *imageName = [NSString stringWithFormat:#"Card %d.png", i];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
// setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
CGRect rect = imageView.frame;
rect.size.height = kScrollObjHeight;
rect.size.width = kScrollObjWidth;
imageView.frame = rect;
imageView.tag = i; // tag our images for later use when we place them in serial fashion
[scrollView1 addSubview:imageView];
[imageView release];
}
[self layoutScrollImages]; // now place the photos in serial layout within the scrollview
This was easy after a good sleep!
CGPoint p = scrollView1.contentOffset;
NSLog(#"x = %f, y = %f", p.x, p.y);
Now just divide by 320 (if horizontal and full screen image) and add 1 (because it starts at 0).
Hope this helps someone else!
Paul