UIScrollView paging with 2 views - objective-c

I tried to implement paging with 2 views from this tutorial:
Multiple virtual pages in a UIScrollView with just 2 child views
I wanted to modify this by putting UIScrollView to pages and in every page updating it with new content:
-(void)addContent:(NSString*)txt{
int size = 5;
UITextView *txtView;
int row = 0;
//from left
int xPlace = 0;
//space between row's
int rowSpace = 20;
//from top
int yPlace = 10;
// int button_with = scrollView.frame.size.width;
int button_height = 20;
for (int i = 0; i < size; i++) {
txtView = [[UITextView alloc] initWithFrame:CGRectMake(xPlace, row*rowSpace+yPlace, scrollView.frame.size.width, 2*button_height)];
[txtView setFont:[UIFont fontWithName:#"ArialMT" size:14]];
txtView.backgroundColor = [UIColor blueColor];
[txtView setText:[NSString stringWithFormat:#"Numer %# - %i",txt,i]];
// answerCheck.titleLabel.font = [UIFont boldSystemFontOfSize:fontSize];
[scrollView addSubview:txtView];
[txtView release];
row++;
}
[scrollView setContentSize:CGSizeMake(scrollView.frame.size.width, txtView.frame.size.height*size)];
}
The idea is when scrolling just replace uiviewcontroller with new content. It calls:
- (void)setPageIndex:(NSInteger)newPageIndex
{
pageIndex = newPageIndex;
if (pageIndex >= 0 && pageIndex < [[DataSource sharedDataSource] numDataPages])
{
NSDictionary *pageData =
[[DataSource sharedDataSource] dataForPage:pageIndex];
label.text = #"Tekstas";//[pageData objectForKey:#"pageName"];
textView.text = [pageData objectForKey:#"pageText"];
[self addContent:[pageData objectForKey:#"pageText"]];
CGRect absoluteRect = [self.view.window
convertRect:textView.bounds
fromView:textView];
if (!self.view.window ||
!CGRectIntersectsRect(
CGRectInset(absoluteRect, TEXT_VIEW_PADDING, TEXT_VIEW_PADDING),
[self.view.window bounds]))
{
textViewNeedsUpdate = YES;
}
}
}
Well here I stuck. My text view is updating but new content of UIscrollView don't update in iPad simulator.
Yea I mean in iphone it works while in iPad it don't. What I could improve if I want to achieve this functionality?
Maybe there are other way to do paging from iOS 5?
I would put source that a tried to make working.
Download source

You can just use a nib file add a UIScrollView with fix width and height. Now make some pages as a UIView and add them to UIScrollView with same size and same origin. In the main UIView:
- (void)viewDidLoad
{
[super viewDidLoad];
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width, scrollView.frame.size.height * 2);
}
-(void)viewWillAppear:(BOOL)animated{
CGFloat h = scrollView.frame.size.height;
[pageView1 setFrame:CGRectMake(0, 0, pageView1.frame.size.width, pageView1.frame.size.height)];
[pageView2 setFrame:CGRectMake(0, h, pageView2.frame.size.width, pageView2.frame.size.height)];
}
And don't forget to check Paging Enabled for UIScrollView in the Attributes in the nib file.
I hope be useful for you!

Related

Objective C - How to create a set of sub views to update

Perhaps I am thinking about this incorrectly, so please point me in the right direction..
I want to make many UIViews as a property so I can update them with different methods. Something like this:
#property UIView *view1
#property UIView *view2
...
#property UIView *view200
-(void)updateViews{
for (i=0; i <200; i++){
//Update view here
}
So my questions are:
How can I easily make multiple views?
How can I easily pass a message to each individual view?
So many great responses, I think I need to add a little more info.
Have tried putting my UIViews into an array to index them but I struggle to access them to update their positions within the UIViewController. I thought making them a property is the correct way to since I need to update them with the device heading. Looks like using a tag might be best. Can someone further comment on this approach:
for (i = 0 ; i < 144; i++) {
UIView *sunView =[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"sun.png"]];
sunView.tag = i;
}
//then later, in a separate method do the following:
for (i = 0 ; i < 144; i++) {
CGFloat CGx = self.acceleration.X;
CGFloat CGy = self.acceleration.Y
[sunView.tag.i setFrame:CGRectMake(CGx, CGy, 20, 20)]
}
Im not sure how to access the UView with the corresponding indexed tag. Can someone help me there too?
When they are really subviews then you could iterate through the superview's subviews array.
You could do that recursievely in order to apply it on all subivews of your subviews, if you have multiple hierarchy levels.
If you don't want to apply this to each of your superview's subviews, then tag your subviews with something like view.tag = 6502 and use that to identify those views to which you want to apply it.
Or maintain your own array or set (iterable collection) of views and iterate through them.
Create your views in a loop and store them in an NSMutableArray. That way you will have access to all of them in your view controller.
Create a property.
#property (monatomic) NSMutableArray *arrayOfViews;
self.arrayOfViews = [[NSMutableArray alloc] init];
UIView *view;
for (int i = 0; i < 10; i++)
{
view = [[UIView alloc] init];
[self.arrayOfViews addObject:view];
}
Run a loop over this array and access the views one by one and call the method you need to call.
On a side note: Why are you creating 200 UIViews? That's a lot :)
I think you need something like that:
-(void)updateViews
{
UIView *views;
UILabel *label;
for(int i = 0 ; i < numberOfViews ; i++)
{
views = [[UIView alloc] initWithFrame:CGRectMake(...)];
label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,views.frame.size.width,views.frame.size.height)];
[label setText:[NSString stringWithFormat:#"%d",i]];
[views addSubview:label];
[self.view addSubview:views];
}
}
How can I easily make multiple views?
Do you want to create it in IB?
1) You can use tags in Xcode
UILabel * label = (UILabel*)[self.view viewWithTag:19];
UIView * view = (UIView*)[self.view viewWithTag:20];
2) You can use property that you also do
How can I easily pass a message to each individual view?
if your views inside another view(currentView) you can use that
for (UIView *yourView in self.currentView.subviews) {
//Update view here
}
Or if you want to create it in the code
for (int i = 0; i < 10; i++)
{
UIView * myView = [[UIView alloc]initWithFrame:CGRectMake(10*i, 10*i, 25, 25)];
int r = arc4random() % 255;
int g = arc4random() % 255;
int b = arc4random() % 255;
myView.backgroundColor = [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1];
[self.view addSubview: myView];
}
That's what you can see
And to call all these views you can use
for (UIView *yourView in self.view.subviews) {
[yourView removeFromSuperview];
}
And that's what you'll see
If you want to call own view you can use tags like this
for (int i = 0; i < 10; i++)
{
UIView * myView = [[UIView alloc]initWithFrame:CGRectMake(10*i, 10*i, 25, 25)];
myView.tag = i + 21;
int r = arc4random() % 255;
int g = arc4random() % 255;
int b = arc4random() % 255;
myView.backgroundColor = [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1];
[self.view addSubview: myView];
}
for (UIView *yourView in self.view.subviews) {
if (yourView.tag == 21) {
[yourView removeFromSuperview];
}
}

Scrolling images by dragging UISlider

Iam beginner in IOS Dev. asking about a way to make UIScrollView images scrolls by dragging UISlider . This is my case :
Required case :
when dragging slider , images scrolls on UIScrollView . also when scrolling images , slider changes its value accordingly .
Actual case :
when scrolling images , slider changes its value accordingly BUT when dragging slider images DONOT Scroll .
Here is my code , I wish any one tell me how to scrolling when slider drags .
Slider IBAction
- (IBAction)sliding:(UISlider *)sender{
int slider_value = (int)slider.value;
NSString *current_page = [[NSString alloc] initWithFormat:#"%i",slider_value];
current_page_lbl.text = current_page ;
[self loadPage:slider_value];
[self loadVisiblePages];
}
methods for UIScrollview :
- (void)loadPage:(NSInteger)page {
if (page < 0 || page >= self.pageImages.count) {
return;
}
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView == [NSNull null]) {
CGRect frame = self.scrollView.bounds;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0.0f;
UIImageView *newPageView = [[UIImageView alloc] initWithImage:[self.pageImages objectAtIndex:page]];
newPageView.contentMode = UIViewContentModeScaleAspectFit;
newPageView.frame = frame;
[self.scrollView addSubview:newPageView];
[self.pageViews replaceObjectAtIndex:page withObject:newPageView];
}
}
- (void)purgePage:(NSInteger)page {
if (page < 0 || page >= self.pageImages.count) {
// If it's outside the range of what you have to display, then do nothing
return;
}
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView != [NSNull null]) {
[pageView removeFromSuperview];
[self.pageViews replaceObjectAtIndex:page withObject:[NSNull null]];
}
}
To loadVisiblePage
- (void)loadVisiblePages {
CGFloat pageWidth = self.scrollView.frame.size.width;
NSInteger page = (NSInteger)floor((self.scrollView.contentOffset.x * 2.0f + pageWidth) / (pageWidth * 2.0f));
NSLog(#"page loaded is %d",page);
self.pageControl.currentPage = page;
NSInteger firstPage = page - 1;
NSInteger lastPage = page + 1;
for (NSInteger i=0; i<firstPage; i++) {
[self purgePage:i];
}
for (NSInteger i=firstPage; i<=lastPage; i++) {
[self loadPage:i];
slider.value = 21-i ;
int slider_value = (int)slider.value;
NSString *current_page = [[NSString alloc] initWithFormat:#"%i",21-slider_value];
current_page_lbl.text = current_page ;
}
for (NSInteger i=lastPage+1; i<self.pageImages.count; i++) {
[self purgePage:i];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
[self loadVisiblePages];
}
uislider is not suitable to use with uiscrollview....for this purpose there is one controll available name UIPagecontrol..
following link is the nice example with code which direct you to how to use it with UIScollview
UIPagecontroll with UIscollview with code Click Here

Scroll the page in iPhone view

I have a view which has details of some event,which includes imageview, some labels etc.
I have the description of the event as a small subview in the view which is scrollable as below.
CGRect descriptionTextViewRect = CGRectMake(15, 185, 280, 85);
descriptionText = [[UITextView alloc] initWithFrame:descriptionTextViewRect];
descriptionText.textAlignment = UITextAlignmentLeft;
descriptionText.text =des;
descriptionText.editable = NO;
descriptionText.layer.cornerRadius = 5.0;
descriptionText.clipsToBounds = YES;
descriptionText.userInteractionEnabled = YES;
descriptionText.font = [UIFont systemFontOfSize:15];
[scrollView addSubview: descriptionText];
I followed this link but I get scrollable for both text view as well as the scrollview
I followed like this
float sizeOfContent = 0;
int i ;
for (i=0; i<[scrollView.subviews count]; i++) {
sizeOfContent += descriptionText.frame.size.height;
}
scrollView.contentSize = CGSizeMake(descriptionText.frame.size.width, sizeOfContent)
I need to display the whole content of the description and make the whole detail page scrollable.
Am I doing it correctly? Or am I missing out somthing?
How do I do that?
Thank you.
You are adding the same item's height for several times.
This:
for (i=0; i<[scrollView.subviews count]; i++) {
sizeOfContent += descriptionText.frame.size.height;
}
Should be this:
for (UIView *view in scrollView.subviews) {
sizeOfContent += view.frame.size.height;
}
So it will correctly add all item's heights to sizeOfContent.
You are adding subView at same position every time. For example: if you are adding 5 subViews it should be like as followings:
for(int i=0; i<5; i++)
{
CGRect descriptionTextViewRect = CGRectMake(15, i*185, 280, 85);
descriptionText = [[UITextView alloc] initWithFrame:descriptionTextViewRect];
descriptionText.textAlignment = UITextAlignmentLeft;
descriptionText.text =des;
descriptionText.editable = NO;
descriptionText.layer.cornerRadius = 5.0;
descriptionText.clipsToBounds = YES;
descriptionText.userInteractionEnabled = YES;
descriptionText.font = [UIFont systemFontOfSize:15];
[scrollView addSubview: descriptionText];
}

UIScrollView paging tagging

I've created a UIScrollView with paging containing several images, with 1 image per "page", and i was wondering if there were any way to distinguish the images from each other?
Fx. when the first image is showing, I would have a button to set a UILabel to '1' and when the second image is showing, the same button would set the same UILabel to '2'.
Here's my code:
pictures = [NSArray arrayWithObjects: [UIImage imageNamed:#"AND.png"], [UIImage imageNamed:#"ALB.png"], nil];
for (int i = 0; i < pictures.count; i++) {
CGRect frame;
frame.origin.x = 135 + (self.scrollViewQuiz.frame.size.width * i);
frame.origin.y = 40;
frame.size = CGSizeMake(50, 50);
UIImageView *subview = [[UIImageView alloc] initWithFrame:frame];
subview.image = [pictures objectAtIndex:i];
[self.scrollViewQuiz addSubview:subview];
}
self.scrollViewQuiz.contentSize = CGSizeMake(self.scrollViewQuiz.frame.size.width * pictures.count, self.scrollViewQuiz.frame.size.height);
It sounds like you just want to compute the "page number" that the scroll view is currently displaying. You can try something like this as your button's action:
- (IBAction)buttonWasTapped:(id)sender {
UIScrollView *scrollView = self.scrollViewQuiz;
int pageNumber = (int)roundf(scrollView.contentOffset.x / scrollView.bounds.size.width);
self.label.text = [NSString stringWithFormat:#"%d", pageNumber];
}
You could implement the following scrollview delegate method:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
In it you would examine the scrollview's contentOffset and set the label accordingly.
Try these two.. these should work.. hope this helps..
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat xOffset = scrollView.contentOffset.x;
int currentPage = floor(xOffset / scrollView.bounds.size.width);
[itsLabel setText:[NSString stringWithFormat:#"%i", currentPage]];
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
CGFloat xOffset = scrollView.contentOffset.x;
int currentPage = floor(xOffset / scrollView.bounds.size.width);
[itsLabel setText:[NSString stringWithFormat:#"%i", currentPage]];
}

UIScrollView only works if the child views aren't hit

I have a scroll view that doesn't scroll right, I've simplified the code for below.
It draws the view and some horizontal buttons that i add more stuff to in the real code.
If you drag the whitespace between the buttons the view scrolls. If you happen to put your finger on a button, it won't scroll.
After a related suggestion, I tried to add the delaysContentTouches = YES line, but it doesn't seem to make a difference.
UIScrollview with UIButtons - how to recreate springboard?
What am I doing wrong?
TIA,
Rob
Updated the code
- (void)viewDidLoad {
l = [self landscapeView];
[self.view addSubview:l];
[l release];
}
- (UIScrollView *) landscapeView {
// LANDSCAPE VIEW
UIScrollView *landscapeView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 325)];
landscapeView.backgroundColor = [UIColor whiteColor];
landscapeView.delaysContentTouches = YES;
NSInteger iMargin, runningY, n;
iMargin = 3;
runningY = iMargin;
for (n = 1; n <= 38; n++) {
//add day labels
UIButton *templabel = [[UIButton alloc] initWithFrame:CGRectMake(iMargin,runningY,320 - ( 2 * iMargin),20)];
templabel.backgroundColor = [UIColor grayColor];
[landscapeView addSubview:templabel];
[templabel release];
runningY = runningY + 30;
}
landscapeView.contentSize = CGSizeMake( 320, runningY);
return landscapeView;
}
I can't duplicate your results; when I create a scrollView and add buttons, scrolling is still active even when doing a touch-down on the button. Are you setting any other UIScrollView properties, or subclassing any methods, that aren't showing up in your simplified code?
It looks like one thing that's going on is that the getter for landScapeView is a complicated constructor...so every time you do [self landscapeView] or self.landscapeView, you're creating a whole new UIScrollView and operating on that.
I'd try something like this in your .h file:
#interface MyClass: MyParent {
UIScrollView *landscapeView;
}
#property (retain) UIScrollView *landscapeView;
...and this in your .m file:
#implementation MyClass
#synthesize landscapeView;
(void)viewDidLoad
{ l = [[[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 325)] autorelease];
[self.view addSubview:self.landscapeView]; [l release];
landscapeView.backgroundColor = [UIColor whiteColor];
landscapeView.delaysContentTouches = YES;
NSInteger iMargin, runningY, n;
iMargin = 3;
runningY = iMargin;
for (n = 1; n <= 38; n++) { //add day labels
UIButton *templabel = [[UIButton alloc] initWithFrame:CGRectMake(iMargin,runningY,320 - ( 2 * iMargin),20)];
templabel.backgroundColor = [UIColor grayColor];
[landscapeView addSubview:templabel];
[templabel release]; runningY = runningY + 30;
}
landscapeView.contentSize = CGSizeMake( 320, runningY);
}