I have created one scroll view and on the scroll view, i am adding two alternate custom UIView s
#interface FirstView : UIView
#interface SecondView : UIView
my array is
NSMutableArray *classArray= [[NSMutableArray alloc] initWithObjects:firstView, secondView, firstView, secondView, nil];
i am adding views on scroll view in following manner
for ( i = 0 ; i< 5; i++)
{
UIView *userView = [classArray objectAtIndex:i];
CGRect rect;
rect.size.height = KVIEWHGT;
float userViewWidth = userView.frame.size.width;
rect.size.width = userViewWidth;
userView.frame = rect;
[scrollView addSubview:userView];
[userView release];
}
UIView *userView = nil;
NSArray *userSubViews = [scrollView subviews];
CGFloat x = 0;
float userViewWidth = 0.0f;
for (userView in userSubViews) {
if ([userView isKindOfClass:[UIView class]]){
CGRect frame = userView.frame;
frame.origin = CGPointMake(x, 0);
userView.frame = frame;
userViewWidth = userView.frame.size.width;
x += userViewWidth + 10;
}
}
[scrollView setContentSize:CGSizeMake(x, scrollView.frame.size.height)];
I am getting output as only two custom views on scroll view but i want there should be 5 custom view on the scroll views
Please help me to solve this problem.
You are adding firstView ,secondView multiple time in the array, even though you add it multiple time it refers to the same instance
NSMutableArray *classArray= [[NSMutableArray alloc] initWithObjects:firstView, secondView, firstView, secondView, nil];
A UIView can only have one parent view. You are using the same UIView instance multiple times. If you add a UIView to another, it is removed from the one it is currently attached to.
Read UIView Class Reference, addSubview:
Views can have only one superview. If view already has a superview and that view is not the receiver, this method removes the previous superview before making the receiver its new superview.
even if it works, you would have duplicated views in your scrollview. you have to create x instances of you views and add them to your scrollview.
thats kind of creepy code anyway.
1.
UIView *userView = [classArray objectAtIndex:i];
[userView release];
you dont have to release this, because its not yours!
2: why iterating twice over the views? makes no sense, better
NSMutableArray* myArray = [[NSMutableArray alloc] initWithObjects: firstView,secView,thirdView,fourthView];
for (UIView* view in myArray)
{
//set the Frame and add it the the ScrollView
}
Related
So I have a scroll view with 3 other views as subviews. Using the scroll view to page between the 3 subviews which have their controllers stored in an array.
- (void)viewDidLoad
{
[self loadData];
self.uiScrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
[self.uiScrollView setPagingEnabled:YES];
[self.uiScrollView setContentSize:CGSizeMake(self.view.frame.size.width*3, self.view.frame.size.height)];
self.uiScrollView.delegate = self;
[self.view addSubview:self.uiScrollView];
self.uiPhotoCollectionViewControllers = [[NSMutableArray alloc] init];
int numberOfOtherViews = 3;
int subViewOffset = 0;
for (int i = 0; i < numberOfCollectionViews; i++)
{
UIViewController* uiViewController = [[UIPhotoCollectionViewController alloc] initWithData:dataArray];
// add offset to the view of the controller
[self.uiScrollView addSubview:uiViewController.view];
[self.uiViewControllers addObject:uiViewController];
uiViewController.view.frame = CGRectOffset(uiViewController.view.frame,subViewOffset,0.0f);
subViewOffset = subViewOffset + uiViewController.view.frame.size.width;
}
If I later wanted to switch the view in the middle of the scroll view with the first one, how would I go about this without removing all teh scroll views subviews and replacing them.
Not possible without replacing, but you can do this by swaping the objects in self.uiViewControllers array like this
[scrollView.subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];
and then after swaping the objects you can add subview by traversing the whole array.
In the parent view controller, I add a child view controller when the view loads:
// In the parent
- (void) viewDidLoad
{
[super viewDidLoad];
self.tokenFieldViewController = [[TokenFieldViewController alloc] init];
[self addChildViewController:self.tokenFieldViewController];
[self.view addSubview:self.tokenFieldViewController.view];
self.tokenFieldViewController.view.frame = self.view.bounds;
[self.tokenFieldViewController didMoveToParentViewController:self];
}
In essence, this child view controller has a text field in its view:
// In the child
- (void) loadView
{
self.view = [[UIView alloc] init];
self.textField = [[UITextField alloc] initWithFrame:CGRectMake(0,0,99,99)];
[self.view addSubview:self.textField];
}
When coded like this, the text field is not tappable. That is, tapping it does not put a blinking cursor into it. However, when I add the child view controller in the parent's viewDidAppear, the text field starts working. I would like to know how to fix it for viewDidLoad, because I need the lifecycle of the child to match that of the parent.
I would suspect that your only problem with the tapping is this line:
self.tokenFieldViewController.view.frame = self.view.bounds;
Between viewDidLoad and viewDidAppear there are a number of things going on. The biggest of which is the measurement of views and subviews. This happens between viewWillLoadSubviews and viewDidLoadSubviews. You should not count on valid sizes until after viewDidLoadSubviews.
Override viewDidLoadSubviews and put your line in it, like this:
- (void)viewDidLayoutSubviews {
self.tokenFieldViewController.view.frame = self.view.bounds;
}
I have created dynamic UIView with scrollview and UIView is having subview UIbutton.
my requirement is on clicking of the UIButton I need to show one more UIView in between the dynamic UIviews.
I need to know how to change the dynamic UIView frame size dynamically on clicking of the UIbutton.
Thanks in advance.
here is the samples
NSArray *subViews = [createIssueScroll subviews];
NSLog(#"%#",subViews);
NSInteger tag=[sender tag];
NSLog(#"%d", tag);
UIView *vw = [createIssueScroll viewWithTag:tag];
[self createIssueSubView:[vw frame]];
UIView *sVW = [createIssueScroll viewWithTag:(tag+1)];
NSLog(#"%#", sVW);
float y;
y = sVW.frame.origin.y;
sVW.frame = CGRectMake(0, y, sVW.frame.size.width, sVW.frame.size.height);
NSLog(#"%f", y);
code explanation
i have created button through programatically, i will explain in detail above code
In first line i have taken all the scrollview subviews(dynamically created UiViews)
i have button tag value
and add a method of UIsubviews(this subview is displaying on clicking of ui button)
suppose i have click dynamically created first Uiview button, need to show subview after the first dynamic UIview and second dynamic UIview is push to down side.
Find subViews by using foreach
UIView *firstView;
UIView *seconfView;
for(id currentview in scrollView.subviews)
{
if([currentview isKindOfClass:[UIView class]])
{
UIView *view = (UIView *)currentview;
if(view.tag == 1) //1 is your view tag
{
firstView = view;
}
if(view.tag == 2) //2 is your view tag
{
seconfView = view;
}
}
}
Now you can use first and second views :)
I am dealing with a project where I have a horizontal paged table view and it is connected to a sqlite3 database. I have tried many methods to create the horizontal tableview and worked nice but when I pass the objects to table view to be displayed on the cells, the app crashes.
I got error that I googled and found that table view is accessing an object from the array that did not exist.
for(int i = 0; i < colors.count; i++) {
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
UITableView *tableView = [[UITableView alloc] initWithFrame:frame];
self.tableView = tableView;
tableView.dataSource = self;
[self.scrollView addSubview:tableView];
And in - (void)scrollViewDidScroll:(UIScrollView *)sender I am passing the array's objects to a particular page when the page is scrolled.
Are there any other good methods to do this?
i think you should use NRGridView, because as per my understanding you have multiple tableview in scrollview, that why tableview delegate method going to confused & your app gone crashed.
I added a UITableView as a subview to a custom UIView class I'm working on. However I noticed that whenever I scroll the table it calls my classes layoutSubviews. I'm pretty sure its the UIScrollview that the table is inheriting from which is actually doing this but wanted to know if there is a way to disable this functionality and if not why is it happening? I don't understand why when you scroll a scrollview it needs its superview to layout its subviews.
Code:
#implementation CustomView
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
self.clipsToBounds = YES;
UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0, 15.0, 436.0, 132.0) style:UITableViewStylePlain];
tableView.dataSource = self;
tableView.delegate = self;
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
tableView.backgroundColor = [UIColor clearColor];
tableView.showsVerticalScrollIndicator = NO;
tableView.contentInset = UIEdgeInsetsMake(kRowHeight, 0.0, kRowHeight, 0.0);
tableView.tag = componentIndex;
[self addSubview:tableView];
[tableView release];
}
return self;
}
- (void)layoutSubviews {
// This is called everytime I scroll the tableview
}
#end
Yes, a UIScrollView does call layoutsubviews whenever it scrolls. I could've sworn this was stated in the documentation somewhere, but I guess not.
Anyways, the prevailing idea for this is that a UIScrollView should layout its stuff so that views that currently can't be seen shouldn't be laid out. As users scroll in the scroll view, it should add and remove subviews as necessary. I'm guessing this is what TableViews use to enqueue table cells that get hidden.
Is there any reason why you would care if layoutsubviews gets called or not?
UITableView at least does appear to layout its superview. This behavior can be problematic when you have a layoutSubviews method that might be expensive (e.g. if you call some JavaScript).
The quick fix is add an intermediary subview that prevents the scroll view from laying out your superview. Instead, it will layout the intermediate subview.
This could be somewhat imperfect but it should work for most cases:
Assume UIView * intermediateView is defined as an instance variable:
-(id) initWithFrame:(CGRect)frame
{
self = [super initWithFrame: frame];
if (self)
{
UIScrollView * theScrollView; // = your scroll view or table view
intermediateView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
// Ensures your intermediate view will resize its subviews.
intermediateView.autoresizesSubviews = YES;
// Ensure when the intermediate view is resized that the scroll view
// is given identical height and width.
theScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight;
[intermediateView addSubview: theScrollView];
// Ensure the frame of the scroll view is exactly the bounds of your
// intermediate view.
theScrollView.frame = bottomContainerView.bounds;
[self addSubview: intermediateView];
}
return self;
}
-(void) layoutSubviews
{
intermediateView.frame = CGRectMake(0, 50, 42, 42); // replace with your logic
}
Not sure i understand your issue correctly but when you scroll a tableview it removes the cells not shown from the memory and loads them again when they are scrolled back into visibility (cells are allocated on demand, only the visible ones) , in effect doing what you seem to be describing.