I am getting strange behavior with UIScrollView
subviews, the idea is to create programmatically an instance of UIView
with a customized nib file which is a form in my case, fill that form with data from a model class, and add it as subview for my UIScrollView
. The problem is when I deal with more than one subview, the UIScrollView
only keep the latest subview, so if I created three subviews, the scrollview will show only the third (the latest) subview. Although the page control is set to the coreect number of subviews (three).
The project is too long, so I will try to explain brievely my issue with the relevant code:
- (void)viewDidLoad {
NSArray *sorted = [appArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];//this array contains the data from model, I debugged that to make sure I got the exact data, no more no less :)
//Loop all NSManaged objects, for example let's say I have 3 model objects, don't worry about how I get data etc, because I debugged all and maked sure all data objects number are exact, etc.
for (App_Table *_appTable in sorted) {
//This looped 3 times as expected, I debugged that also and maked sure on each iteration I got the data I expected to have
//App_Table is a subclass of NSManagedObject, it's my model class and get its data from coredata file
[self addMoreView];//Call this method will create a new subview and add it as subview to the UIScrollView, it will also update the page control, update the content size property, etc.
AppTableView *_appTableView = (AppTableView *) [[self.scrollView subviews] lastObject];//Remember addMoreView method create a new instance of AppTableView and add it as subview for the UIScrollView property, then I get that subview to fill it with data here
_appTableView.txtADDRESS.text = _appTable.address;//Fill in the form, no need to write all the form fields code because it's the same way.
// Scroll To First Page...
self.pageControl.currentPage = 0;
[self.scrollView scrollRectToVisible:CGRectMake(0, 0, viewWidth, viewHeight) animated:YES];
self.scrollView.contentSize = CGSizeMake(viewWidth*noOfItems, viewHeight);//Set the content size to the sum of subviews width, I also debugged that to check it's correct
self.scrollView.delegate = self;
[super viewDidLoad];
}
Ok, so when I have three subviews, the scrollview will load with the width of three subviews as calculated with the line above:
self.scrollView.contentSize = CGSizeMake(viewWidth*noOfItems, viewHeight);//Set the content size to the sum of subviews width, I also debugged that to check it's correct
And I can scroll till 3 moves (which is the number of subviews) and the UIPageControl
is also set to three dots, but only ONE subview is visible, only the latest one I can see, the two other subviews disappeared, the scroll view calculated content size for them but they are not visible. Any thoughts ? Thanx.
EDIT:
It's worth to note that the first time I edit the view, all goes fine, when I deal with 3 subviews, they are all visible, but when I go to another view and get back to this view, only the last subview is visible.
Also, I am working on an iPad project for that with a split view.
EDIT:
This is the code of the method which draw new subview for the UIScrollView
-(IBAction) addMoreView
{
NSArray *arr = [[NSBundle mainBundle] loadNibNamed:@"AppTableView" owner:self options:nil];
AppTableView *aView = [arr objectAtIndex:0];
[aView setFrame:CGRectMake(startX, 0, aView.bounds.size.width, aView.bounds.size.height)];
[self.scrollView addSubview:aView];
self.scrollView.contentSize = CGSizeMake(self.scrollView.contentSize.width+aView.frame.size.width
, self.scrollView.contentSize.height);
startX = startX + aView.frame.size.width;//Update the X position, first 0, then 600, 1200, and so on.
[self.scrollView scrollRectToVisible:aView.frame animated:YES];
NSLog(@"%f",self.scrollView.contentSize.width);
NSLog(@"%f",self.scrollView.contentSize.height);
}
Suppose I have 3 subviews, the method above will be called 3 times since it's put inside the for
loop. So here is the result of NSLogs
for the above method:
NSLog(@"%f",self.scrollView.contentSize.width);
NSLog(@"%f",self.scrollView.contentSize.height);
First iteration:
600.000000
0.000000
Second iteration:
1200.000000
0.000000
Third iteration:
1800.000000
0.000000
EDIT:
The command suggested by rob mayoff allows me to see why this happen:
| | | | <AppTableView: 0x1eef4700; frame = (0 18; 600 430); autoresize = LM+RM+TM+BM; tag = 990; layer = <CALayer: 0x1eef4790>>
| | | | <AppTableView: 0x1ee3f380; frame = (0 18; 600 430); autoresize = LM+RM+TM+BM; tag = 991; layer = <CALayer: 0x1ee3f410>>
| | | | <AppTableView: 0x1ee56910; frame = (0 18; 600 430); autoresize = LM+RM+TM+BM; tag = 992; layer = <CALayer: 0x1ee3f410>>
All Three subviews are drawn in the same frame, so they are above each other, but when I debug that with breakpoints in runtime, the x
is changing, first time 0, then 600 then 1200 which make me think it's drawing correctly. How to fix that especially that the x value is being incremented correctly, so what's the problem and why they still drawing on the same x coordinate?
-viewDidLoad
is only called before the first time, and the issue is somewhere else in your code. – Seamus Campbell-viewDidLoad is only called before the first time
I checked with breakpoints andviewDidLoad
is always called when getting to the view. – Malloc-viewDidLoad
, what is changing between the two calls? – Seamus CampbellcontentSize
,frame
, data, etc. All is fine, Why the scrollview is always keeping the last iteration in thefor
loop, although it draws the necessar space to hold all subviews, but only showing up one of them? – Mallocfor
loop end? And you probably need to show us the code for-addMoreView
. – Seamus Campbell