Pagination UIScrollView - ios

Need some help with a complex issue on my paginated scrollview. Im adding multiple pages with tableviews and some more data that could be heavy for memory. But it building up memory with each scroll. I would like my code to only add a subview once and on scroll replace it and release the old on (im using ARC). But the memory is building up, i think its because its adding the subview multiple times.
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
#synchronized(self) {
#autoreleasepool {
CGFloat pageWidth = mainScrollView.frame.size.width;
NSInteger page = round(mainScrollView.contentOffset.x / pageWidth);
int scrollOffset = (page * barWidth)-(mainScrollView.bounds.size.width/2);
if (scrollOffset<=0) {
scrollOffset = 0;
} else if (scrollOffset >= (pageIndicatorScrollView.contentSize.width - pageIndicatorScrollView.frame.size.width)) {
scrollOffset = (pageIndicatorScrollView.contentSize.width - pageIndicatorScrollView.frame.size.width);
}
[pageIndicatorScrollView setContentOffset:CGPointMake(scrollOffset, 0) animated:YES];
if(page < 0)
{
page = 0;
}
if(page >= [categoryScrollersArray count])
{
page = [categoryScrollersArray count] - 1;
}
//page = page +1;
//////////NSLog(#"page = %d",page);
// don't create or delete pages while rotating
if (!isRotating) {
if([categoryScrollersArray count] == 1)
{
if([categoryScrollersArray objectAtIndex:0] == [NSNull null])
{
[self loadScrollViewWithPage:0];
}
}
else if([categoryScrollersArray count] == 2)
{
if([categoryScrollersArray objectAtIndex:0] == [NSNull null])
{
[self loadScrollViewWithPage:0];
}
if([categoryScrollersArray objectAtIndex:1] == [NSNull null])
{
[self loadScrollViewWithPage:1];
}
}
else
{
if(page - 1 < 0)
{
if([categoryScrollersArray objectAtIndex:0] == [NSNull null])
{
[self loadScrollViewWithPage:0];
}
if([categoryScrollersArray objectAtIndex:1] == [NSNull null])
{
[self loadScrollViewWithPage:1];
}
}
else
{
if([categoryScrollersArray objectAtIndex:page - 1] == [NSNull null])
{
[self loadScrollViewWithPage:page - 1];
}
if([categoryScrollersArray objectAtIndex:page] == [NSNull null])
{
[self loadScrollViewWithPage:page];
}
if(page + 1 < [categoryScrollersArray count])
{
if([categoryScrollersArray objectAtIndex:page + 1] == [NSNull null])
{
[self loadScrollViewWithPage:page + 1];
}
}
}
if(page -2 >= 0 )
{
if([categoryScrollersArray objectAtIndex:page -2] != [NSNull null])
{
UIView *u = [categoryScrollersArray objectAtIndex:page-2];
//////////NSLog(#"remove page = %d",page-2);
[u removeFromSuperview];
if (page-2 < [categoryScrollersArray count]) {
if ([categoryScrollersArray objectAtIndex:page-2] == nil) {
[self showUnexpectedBehaviorAlertWithTest:#"An unknown error occured, please reopen the questionnaire. (1307)"];
}
else {
[categoryScrollersArray replaceObjectAtIndex:page-2 withObject:[NSNull null]];
}
}
else {
[self showUnexpectedBehaviorAlertWithTest:#"An unknown error occured, please reopen the questionnaire. (1314)"];
}
}
}
if(page +2 < [categoryScrollersArray count])
{
if([categoryScrollersArray objectAtIndex:page +2] != [NSNull null])
{
UIView *u = [categoryScrollersArray objectAtIndex:page+2];
// [u removeObserver:u.self forKeyPath:#"doReload"];
//////////NSLog(#"remove page = %d",page+2);
[u removeFromSuperview];
if (page+2 < [categoryScrollersArray count]) {
if ([categoryScrollersArray objectAtIndex:page+2] == nil) {
[self showUnexpectedBehaviorAlertWithTest:#"An unknown error occured, please reopen the questionnaire. (1329)"];
}
else {
[categoryScrollersArray replaceObjectAtIndex:page+2 withObject:[NSNull null]];
}
}
else {
[self showUnexpectedBehaviorAlertWithTest:#"An unknown error occured, please reopen the questionnaire. (1337)"];
}
}
}
}
}
[self changeProgressBar:page];
// ////////NSLog(#"viewControllers are %#",viewControllers);
// ////////NSLog(#"questionsScroll.subviews %#",questionsScroll.subviews);
}
}
}
And the other function:
- (void)loadScrollViewWithPage:(int)page
{
if (page < 0)
return;
if (page >= [categoryScrollersArray count])
return;
//Categories * anCat;
//anCat = [catArray objectAtIndex:page];
// replace the placeholder if necessary
CategoryScrollerView *catScroll = [categoryScrollersArray objectAtIndex:page];
if ((NSNull *)catScroll == [NSNull null])
{
Step *aStep = [steps objectAtIndex:page];
NSString *coder = [[NSString alloc] init];
if ([self.visit.savedStatus integerValue] == 2 && [self.visit.state integerValue] == 1) {
coder = #"SAVED";
} else {
coder = #"OPEN";
}
NSString *questCode = [NSString stringWithFormat:#"%#",self.visit.questionnaire.version];
catScroll = [[CategoryScrollerView alloc] initWithFrame:mainScrollView.frame andStep:aStep andDelegate:self andStepname:aStep.name andVisitcode:coder andQuestionnairecode:questCode];
catScroll.autoresizesSubviews = YES;
catScroll.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
[self setNextBtnTitleForPage:page andView:catScroll];
if (page < [categoryScrollersArray count]) {
if ([categoryScrollersArray objectAtIndex:page] == nil) {
[self showUnexpectedBehaviorAlertWithTest:#"An unknown error occured, please reopen the questionnaire. (1101)"];
}
else {
[categoryScrollersArray replaceObjectAtIndex:page withObject:catScroll];
}
}
else {
[self showUnexpectedBehaviorAlertWithTest:#"An unknown error occured, please reopen the questionnaire. (1108)"];
}
}
// add the controller's view to the scroll view
if (catScroll.superview == nil)
{
CGRect frame = mainScrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
catScroll.frame = frame;
[mainScrollView addSubview:catScroll];
// NSDictionary *numberItem = [self.contentList objectAtIndex:page];
// controller.numberImage.image = [UIImage imageNamed:[numberItem valueForKey:ImageKey]];
// controller.numberTitle.text = [numberItem valueForKey:NameKey];
}
}

Doing this inside one view controller is going to be really complex. Especially if you're trying to do all the tableview datasource stuff in there too.
You would be much better off using a UIPageViewController.
It is a container controller (a lot like UINavigationController or UITabBarController) that is used to display view controllers in a paged scroll view type of view.
There are some tutorials here about using UIPageViewController. http://www.raywenderlich.com/?s=uipageviewcontroller&cof=FORID%3A10
Essentially you pass a different table view controller in for each page. It takes a bit of settings up but once it's done it will help make it much easier and will keep memory usage down.
There are lots more tutorials out there too... http://www.appcoda.com/uipageviewcontroller-tutorial-intro/
Also, you don't have to make it full screen. You can use the Page View Controller for only the part of the screen that you want to scroll.

Related

Check if iOS Update is available using objective-c?

How can I compare installed iOS version with the latest iOS version programatically using objective-c?
You have to take new version number from web service.This is because if you want to update app from app store then you just need to increase your app version from your pannel and you will get it in web service and then you can check it like this (call this method by passing web service version) :-
(BOOL)isUpdateAvailable:(NSString*)latestVersion
{
NSString *currentAppVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleShortVersionString"];
NSArray *myCurrentVersion = [currentAppVersion componentsSeparatedByString:#"."];
NSArray *myLatestVersion = [latestVersion componentsSeparatedByString:#"."];
NSInteger legthOfLatestVersion = myLatestVersion.count;
NSInteger legthOfCurrentVersion = myCurrentVersion.count;
if (legthOfLatestVersion == legthOfCurrentVersion)
{
for (int i=0; i<myLatestVersion.count; i++)
{
if ([myCurrentVersion[i] integerValue] < [myLatestVersion[i] integerValue])
{
return true;
}
else if ([myCurrentVersion[i] integerValue] == [myLatestVersion[i] integerValue])
{
continue;
}
else
{
return false;
}
}
return false;
}
else
{
NSInteger count = legthOfCurrentVersion > legthOfLatestVersion ? legthOfLatestVersion : legthOfCurrentVersion;
for (int i=0; i<count; i++)
{
if ([myCurrentVersion[i] integerValue] < [myLatestVersion[i] integerValue])
{
return true;
}
else if([myCurrentVersion[i] integerValue] > [myLatestVersion[i] integerValue])
{
return false;
}
else if ([myCurrentVersion[i] integerValue] == [myLatestVersion[i] integerValue])
{
continue;
}
}
if (legthOfCurrentVersion < legthOfLatestVersion)
{
for (NSInteger i=legthOfCurrentVersion; i<legthOfLatestVersion; i++)
{
if ([myLatestVersion[i] integerValue] != 0)
{
return YES;
}
}
return NO;
}
else
{
return NO;
}
}
}
This will return bool value if it will return YES then you will have new version of your app and if NO then your app has updated version.

dump app call stack in “for in” only onetime

- (id)objectAtIndexSafe:(NSUInteger)index
{
if (index < [self count]) {
return [self objectAtIndexSafe:index];
}else {
TTSafeKitAssert(NO, #"unsafe");
return nil;
}
}
TTSafeKitAssert : send dumped threads info(use PlCashReporter) to sever,but when objectAtIndexSafe called in for in,TTSafeKitAssert will send so many times . How can i just send once in this situation!
If it is a category:
- (id)objectAtIndexSafe:(NSUInteger)index
{
if (index < [self count]) {
return [self objectAtIndex:index];
}else {
TTSafeKitAssert(NO, #"unsafe");
return nil;
}
}

Improving Performance Of Core Plot

I'm plotting Real Time ECG using CorePlot library.When it uses in iPad air the performance is okay.But when i tried it with iPad mini, There is a delay in the plotting.I have done with collapseLayer and this link also.that didn't solved my problem.Can anyone suggest new solution for this.
My code is below:
-(void)newData:(NSTimer *)theTimer
{
for (int i =0;i<plotcount;i++){
if([Qrrch0 count]>0 || [Qrrch1 count]>0 || [Qrrch2 count]>0 || [Qrrch3 count]>0 || [Qrrspo2 count]>0 ){
if(g1==1 && thePlot){
currentIndex ++;
}
if(g2==1 && thePlot1){
currentIndex1 ++;
}
if(g3==1 && thePlot2){
currentIndex2 ++;
}
if(g4==1 && thePlot3){
currentIndex3 ++;
}
if(spo2==1 && thePlot4){
currentIndex4 ++;
}
if(arrayIndex>=kchannel1-1)
{
arrayIndex=0;
}
if(arrayIndex1>=kchannel2-1)
{
arrayIndex1=0;
}
if(arrayIndex>=kchannel1-1)
{
arrayIndex=0;
}
if(arrayIndex2>=kchannel3-1)
{
arrayIndex2=0;
}
if(arrayIndex3>=kchannel4-1)
{
arrayIndex3=0;
}
if(arrayIndex4>=kchannel5-1)
{
arrayIndex4=0;
}
if(g1==1 && thePlot){
currentIndex5++;
if(currentIndex5>=kchannel1)
{
if(arrayIndex==0)
{
[thePlot reloadDataInIndexRange:NSMakeRange(arrayIndex, arrayIndex)];
}else{
[thePlot deleteDataInIndexRange:NSMakeRange(arrayIndex, 1)];
}
}
if([Qrrch0 count]!=0)
{
arrPlot[arrayIndex]=[[Qrrch0 objectAtIndex:0] integerValue];
lastPlot0=[Qrrch0 objectAtIndex:0];
}else{
arrPlot[arrayIndex]=[lastPlot0 integerValue];
}
arrayIndex++;
}
if(g2==1 && thePlot1){
currentIndex6++;
if(currentIndex6>=kchannel2)
{
if(arrayIndex1==0)
{
[thePlot1 reloadDataInIndexRange:NSMakeRange(arrayIndex1, arrayIndex1)];
}else{
[thePlot1 deleteDataInIndexRange:NSMakeRange(arrayIndex1, 1)];
}
}
if([Qrrch1 count]!=0)
{
arrPlot1[arrayIndex1]=[[Qrrch1 objectAtIndex:0] integerValue];
lastPlot1=[Qrrch1 objectAtIndex:0];
}else{
arrPlot1[arrayIndex1]=[lastPlot1 integerValue];
}
arrayIndex1++;
}
if(g3==1 && thePlot2){
currentIndex7++;
if(currentIndex7>=kchannel3)
{
if(arrayIndex2==0)
{
[thePlot2 reloadDataInIndexRange:NSMakeRange(arrayIndex2, arrayIndex2)];
}else{
[thePlot2 deleteDataInIndexRange:NSMakeRange(arrayIndex2, 1)];
}
}
if([Qrrch2 count]!=0)
{
arrPlot2[arrayIndex2]=[[Qrrch2 objectAtIndex:0] integerValue];
lastPlot2=[Qrrch2 objectAtIndex:0];
}else{
arrPlot2[arrayIndex2]=[lastPlot2 integerValue];
}
arrayIndex2++;
}
if(g4==1 && thePlot3){
currentIndex8++;
if(currentIndex8>=kchannel4)
{
if(arrayIndex3==0)
{
[thePlot3 reloadDataInIndexRange:NSMakeRange(arrayIndex3, arrayIndex3)];
}else{
[thePlot3 deleteDataInIndexRange:NSMakeRange(arrayIndex3, 1)];
}
}
if([Qrrch3 count]!=0)
{
arrPlot3[arrayIndex3]=[[Qrrch3 objectAtIndex:0] integerValue];
lastPlot3=[Qrrch3 objectAtIndex:0];
}else{
arrPlot3[arrayIndex3]=[lastPlot3 integerValue];
}
arrayIndex3++;
}
if(spo2==1 && thePlot4){
currentIndex9++;
if(currentIndex9>=kchannel5)
{
if(arrayIndex4==0)
{
[thePlot4 reloadDataInIndexRange:NSMakeRange(arrayIndex4, arrayIndex4)];
}else{
[thePlot4 deleteDataInIndexRange:NSMakeRange(arrayIndex4, 1)];
}
}
if([Qrrspo2 count]!=0)
{
arrPlot4[arrayIndex4]=[[Qrrspo2 objectAtIndex:0] integerValue];
lastPlot4=[Qrrspo2 objectAtIndex:0];
}else{
arrPlot4[arrayIndex4]=[lastPlot4 integerValue];
}
arrayIndex4++;
}
if(g1==1 && thePlot){
if([Qrrch0 count]!=0)
{
[Qrrch0 removeObjectAtIndex:0];
}
if(currentIndex>=kchannel1)
{
currentIndex=1;
}
[thePlot insertDataAtIndex:currentIndex-1 numberOfRecords:1];
}
if(g2==1 && thePlot1){
if([Qrrch1 count]!=0)
{
[Qrrch1 removeObjectAtIndex:0];
}
if(currentIndex1>=kchannel2)
{
currentIndex1=1;
}
[thePlot1 insertDataAtIndex:currentIndex1-1 numberOfRecords:1];
}
if(g3==1 && thePlot2){
if([Qrrch2 count]!=0)
{
[Qrrch2 removeObjectAtIndex:0];
}
if(currentIndex2>=kchannel3)
{
currentIndex2=1;
}
[thePlot2 insertDataAtIndex:currentIndex2-1 numberOfRecords:1];
}
if(g4==1 && thePlot3){
if([Qrrch3 count]!=0)
{
[Qrrch3 removeObjectAtIndex:0];
}
if(currentIndex3>=kchannel4)
{
currentIndex3=1;
}
[thePlot3 insertDataAtIndex:currentIndex3-1 numberOfRecords:1];
}
if(spo2==1 && thePlot4){
if([Qrrspo2 count]!=0)
{
[Qrrspo2 removeObjectAtIndex:0];
}
if(currentIndex4>=kchannel5)
{
currentIndex4=1;
}
[thePlot4 insertDataAtIndex:currentIndex4-1 numberOfRecords:1];
}
}
else
{
[self datacha];
}
}
}
-(void) datacha{
NSArray *array;
if([FinalArray count]>0){
if(g1==1 && thePlot){
array = [[NSArray alloc] initWithArray:[FinalArray objectAtIndex:0]];
[Qrrch0 addObjectsFromArray:array];
}
if(g1==1 && thePlot){
[FinalArray removeObjectAtIndex:0];
}
}
if([FinalArray1 count]>0){
if(g2==1 && thePlot1){
array = [[NSArray alloc] initWithArray:[FinalArray1 objectAtIndex:0]];
[Qrrch1 addObjectsFromArray:array];
}
if(g2==1 && thePlot1){
[FinalArray1 removeObjectAtIndex:0];
}
}
if([FinalArray2 count]>0){
if(g3==1 && thePlot2){
array = [[NSArray alloc] initWithArray:[FinalArray2 objectAtIndex:0]];
[Qrrch2 addObjectsFromArray:array];
}
if(g3==1 && thePlot2){
[FinalArray2 removeObjectAtIndex:0];
}
} if([FinalArray3 count]>0){
if(g4==1 && thePlot3){
array = [[NSArray alloc] initWithArray:[FinalArray3 objectAtIndex:0]];
[Qrrch3 addObjectsFromArray:array];
}
if(g4==1 && thePlot3){
[FinalArray3 removeObjectAtIndex:0];
}
}
if([FinalArray4 count]>0){
if(spo2==1 && thePlot4){
array = [[NSArray alloc] initWithArray:[FinalArray4 objectAtIndex:0]];
[Qrrspo2 addObjectsFromArray:array];
}
if(spo2==1 && thePlot4){
[FinalArray4 removeObjectAtIndex:0];
}
}
}
#pragma mark -
#pragma mark Plot Data Source Methods
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
if(plot == thePlot)
{
if(currentIndex5>=kchannel1)
{
return kchannel1;
}else{
return currentIndex5;
}
}
if(plot == thePlot1)
{
if(currentIndex6>=kchannel2)
{
return kchannel2;
}else{
return currentIndex6;
}
}
if(plot == thePlot2)
{
if(currentIndex7>=kchannel3)
{
return kchannel3;
}else{
return currentIndex7;
}
}
if(plot == thePlot3)
{
if(currentIndex8>=kchannel4)
{
return kchannel4;
}else{
return currentIndex8;
}
}
if(plot == thePlot4)
{
if(currentIndex9>=kchannel5)
{
return kchannel5;
}else{
return currentIndex9;
}
}
return 0;
}
-(double)doubleForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)idx{
double num;
NSString *textval = [NSString stringWithFormat:#"%d", countofpktloss];
self.losscount.text = textval;
switch ( fieldEnum ) {
case CPTScatterPlotFieldX:
if(plot == thePlot){
num =currentIndex;
}
else if(plot == thePlot1)
{
num = currentIndex1;
}
else if(plot == thePlot2)
{
num = currentIndex2;
}
else if(plot == thePlot3)
{
num = currentIndex3;
}
else if(plot == thePlot4)
{
num = currentIndex4;
}
break;
case CPTScatterPlotFieldY:
if(plot == thePlot){
num =arrPlot[idx];
}
else
if(plot == thePlot1){
num =arrPlot1[idx];
}
else if(plot == thePlot2){
num =arrPlot2[idx];
}
else if(plot == thePlot3)
{
num =arrPlot3[idx];
}
else if(plot == thePlot4)
{
num =arrPlot4[idx];
}
break;
default:
break;
}
return num;
}
The collapsesLayers property is there to help save memory for a static graph. Using it on a graph that updates frequently makes the performance worse since it requires the graph to redraw everything, not just the part that changed, e.g., the plot.
Added comments
Make sure the timer stops when you expect it to. Otherwise, it will keep adding points to the plots.
How often does the timer fire to add points to the plots? There's no point in updating the plots more than 60 times per second and you may need to reduce that further on older devices like the iPad 2 to get good performance with lots of data points. You can add more than one point in each update if needed.
Check the ranges used to reload data points. You're passing the same number as the location and length of the range. I suspect you mean to use a length of one (1) for each range. If so, you're reloading more data than required on each pass.
Have you tried looking at other chart libraries? SciChart provides an iOS chart tailored for realtime ECG applications. It's extremely fast and doesn't have the performance problems of Core plot.
See iOS Chart Performance Comparison
and SciChart iOS ECG demo
Disclosure, I am the tech lead on the scichart projects

Content not loading on horizontal scroll view

Hi I am building an app in which I want my contents to be displayed on a view which is horizontally scroll-able.
I have implemented the following code for it:
-(void)DownLoadData:(NSString *)indexSelect
{
self._parserForNewsDetail = [afaqsParser getInstance];
[[afaqsParser getInstance] setCacheNeed:TRUE];
[self._parserForNewsDetail parseWithUrl:[_arrUrlLinks objectAtIndex:[indexSelect integerValue]] UrlTypefor:nil];
NSDictionary *resultDic;
resultDic = [[[self._parserForNewsDetail getLinkAndIdDic] valueForKey:#"items"]objectAtIndex:0];
NSLog(#"Detail Dic = %#",[resultDic description]);
if (resultDic== NULL || resultDic ==nil)
{
//Check internet here
[[SharedUtilities getInstance]RemoveActivityIndicatorView];
[SharedUtilities ShowAlert:#"No Data Found" title:nil withView:self.view];
return;
}
[self performSelectorOnMainThread:#selector(SetValuesInUserInterface:) withObject: resultDic waitUntilDone:NO];
[[SharedUtilities getInstance]RemoveActivityIndicatorView];
}
-(void)DownloadNext:(NSString *)indexSelect
{
resultDic = [[[self._parserForNewsDetail getLinkAndIdDic] valueForKey:#"items"]objectAtIndex:0];
NSURL *imgurl =[NSURL URLWithString:[[Dic valueForKey:#"image"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSArray *subviewsArr = [self.view subviews];
for (int i=0; i<[subviewsArr count]; i++) {
if ([[subviewsArr objectAtIndex:i] isKindOfClass:[ImageDownLoader class]]) {
}
}
[self loadScrollView];
}
-(void)SetValuesInUserInterface:(NSDictionary *)Dic
{
self._imageView1.layer.cornerRadius = 4;
self._imageView1.clipsToBounds = YES;
self._imageView1.tag = 999;
NSURL *imgurl =[NSURL URLWithString:[[Dic valueForKey:#"image"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
self._imageView1.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:imgurl]];
NSArray *subviewsArr = [self.view subviews];
for (int i=0; i<[subviewsArr count]; i++) {
if ([[subviewsArr objectAtIndex:i] isKindOfClass:[ImageDownLoader class]]) {
[[subviewsArr objectAtIndex:i] removeFromSuperview];
}
}
if ([[Dic valueForKey:#"image"] isEqual:#""])
{
_imageView1.hidden=YES;
_txtView.frame=CGRectMake(4.0f,95.0f,_txtView.frame.size.width,_txtView.frame.size.height );
NSLog(#"NO IMAGE");
}
else{
_imageView1.hidden=NO;
_imageView1.frame=CGRectMake(4.0f,95.0f,310.0f,180.0f );
// _txtView.frame=CGRectMake(4.0f,316.0f,310.0f,159.0f );
_txtView.frame=CGRectMake(4.0f,316.0f,_txtView.frame.size.width,_txtView.frame.size.height );
NSLog(#"IMAGE VISIBLE");
}
self._scrollView.scrollEnabled = YES;
self._scrollView.showsVerticalScrollIndicator = YES;
self._scrollView.showsHorizontalScrollIndicator = YES;
self._header.font = [UIFont fontWithName:#"HelveticaNeue-MediumCond" size:18];
[self._header setText: [Dic valueForKey:#"header"]];
self._header.textColor=[UIColor blackColor];
[self._Writer setText:[Dic valueForKey:#"AUTHOR"]];
[self._kicker setText:[Dic valueForKey:#"kicker"]];
[self._txtView setText:[Dic valueForKey:#"ARTICLE_BODY"]];
NSString *writer;
if ([[Dic valueForKey:#"AUTHOR"] length]>2)
{
writer=[NSString stringWithFormat:#"%#, ",[Dic valueForKey:#"AUTHOR"]];
}
else
{
writer=#"";
}
[self._Writer setText:str];
[_txtView sizeToFit]; //added
[_txtView layoutIfNeeded]; //added
CGRect frame = self._txtView.frame;
self._txtView.frame = frame;
[_txtView setScrollEnabled:NO];
self._scrollView.contentSize = CGSizeMake(320,440+frame.size.height);
_titleLabel.frame= CGRectMake(0, self._scrollView.contentSize.height-119, [[UIScreen mainScreen] bounds].size.width, 40);
_titleLabel.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:1];
_titleLabel.textColor = [UIColor whiteColor];
_titleLabel.textAlignment = NSTextAlignmentCenter;
_titleLabel.font = [UIFont fontWithName:#"Helvetica" size:13.5];
_titleLabel.numberOfLines=2;
[self._scrollView addSubview:_titleLabel];
[self loadScrollView];
}
-(void)viewWillAppear:(BOOL)animated
{
self.navigationController.navigationBarHidden = YES;
}
- (void)viewDidLoad
{
[self DownLoadData:resultDic];
UISwipeGestureRecognizer *rightRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(loadScrollView)];
rightRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
[rightRecognizer setNumberOfTouchesRequired:1];
//add the your gestureRecognizer , where to detect the touch..
[_scrollView addGestureRecognizer:rightRecognizer];
UISwipeGestureRecognizer *leftRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(loadScrollView)];
leftRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
[leftRecognizer setNumberOfTouchesRequired:1];
[_scrollView addGestureRecognizer:leftRecognizer];
}
- (void)rightSwipeHandle:(UISwipeGestureRecognizer*)gestureRecognizer
{
[self btnPreviousClick];
[self loadScrollView];
}
- (void)leftSwipeHandle:(UISwipeGestureRecognizer*)gestureRecognizer
{
NSLog(#"leftSwipeHandle");
[self btnNextClick];
[self loadScrollView];
}
-(IBAction)btnNextClick
{
btnPreviousNews.userInteractionEnabled=TRUE;
if(count!=[_arrUrlLinks count] -1)
{
if(count==[_arrUrlLinks count]-2)
{
btnNextNews.userInteractionEnabled=FALSE;
[btnNextNews setImage:[UIImage imageNamed:#"arrow2_next.png"] forState:UIControlStateNormal];
}
[btnPreviousNews setImage:[UIImage imageNamed:#"arrow1_prev.png"] forState:UIControlStateNormal];
count=count +1;
_lblNewsCount.text=[NSString stringWithFormat:#"%d/%d",count+1,[_arrUrlLinks count]];
NSLog(#"next %d",count);
[self performSelectorInBackground:#selector(DownLoadData:) withObject:[NSString stringWithFormat:#"%d",count]];
}
else{
btnNextNews.userInteractionEnabled=FALSE;
}
}
-(void)btnPreviousClick
{
btnNextNews.userInteractionEnabled=TRUE;
if(count==0)
{
btnPreviousNews.userInteractionEnabled=FALSE;
}
else{
if(count==1)
{
[btnPreviousNews setImage:[UIImage imageNamed:#"arrow2_prev.png"] forState:UIControlStateNormal];
btnPreviousNews.userInteractionEnabled=FALSE;
}
[btnNextNews setImage:[UIImage imageNamed:#"arrow1_next.png"] forState:UIControlStateNormal];
count=count-1;
_lblNewsCount.text=[NSString stringWithFormat:#"%d/%d",count+1,[_arrUrlLinks count]];
NSLog(#"previous %d",count);
[self performSelectorInBackground:#selector(DownLoadData:) withObject:[NSString stringWithFormat:#"%d",count]];
}
}
-(void)loadScrollView
{
_scrollView.contentSize = CGSizeMake(0, _scrollView.frame.size.height);
NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < [_arrUrlLinks count]; i++) {
[controllers addObject:[NSNull null]];
}
self.viewControllers = controllers;
count=1;
// a page is the width of the scroll view
_scrollView.pagingEnabled = YES;
_scrollView.contentSize = CGSizeMake(_scrollView.frame.size.width * [_arrUrlLinks count], _scrollView.frame.size.height);
_scrollView.showsHorizontalScrollIndicator =YES;
_scrollView.showsVerticalScrollIndicator = NO;
_scrollView.scrollsToTop = NO;
_scrollView.delegate = self;
pageControl.numberOfPages = [_arrUrlLinks count];
pageControl.currentPage = 0;
[_scrollView addSubview:_txtView];
[_txtView setText:[Dic valueForKey:#"ARTICLE_BODY"]];
[controller.view addSubview:_txtView];
// pages are created on demand
// load the visible page
// load the page on either side to avoid flashes when the user starts scrolling
[self loadScrollViewWithPage:0];
[self loadScrollViewWithPage:1];
}
- (void)loadScrollViewWithPage:(int)page {
if (page < 0) return;
if (page >= [_arrUrlLinks count])
return;
// replace the placeholder if necessary
controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null]) {
NSString *deviceType = [UIDevice currentDevice].model;
if([deviceType isEqualToString:#"iPhone"])
{
controller = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
}
else{
controller = [[MyViewController alloc] initWithNibName:#"MyViewController_ipad" bundle:nil];
}
[controller initWithPageNumber:page];
// [controller.view addSubview:_txtView];
// [controller.view addSubview:_imageview];
NSLog(#"loadscrollviewwithpage");
[viewControllers replaceObjectAtIndex:page withObject:controller];
// [controller release];
}
// add the controller's view to the scroll view
if (nil == controller.view.superview) {
CGRect frame = _scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
// _txtView.frame=frame;
// _imageview.frame=frame;
// _txtView.frame=CGRectMake(4.0f,316.0f,310.0f,159.0f );
_txtView=#"hello";
// [controller.view addSubview:_txtView];
[_imageView1 addSubview:controller.view];
// [_txtView addSubview:controller.view];
// [scrollView addSubview:controller.view];
NSLog(#"loadscrollviewwithpage................>>>>>>>>>>>>");
// [self._header setText: [Dic valueForKey:#"header"]];
// [self DownLoadData:resultDic];
//[self SetValuesInUserInterface:Dic];
[self DownloadNext:resultDic];
}
}
- (void)unloadScrollViewWithPage:(int)page {
if (page < 0) return;
if (page >= [_arrUrlLinks count]) return;
controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller != [NSNull null]) {
if (nil != controller.view.superview)
[controller.view removeFromSuperview];
[viewControllers replaceObjectAtIndex:page withObject:[NSNull null]];
// [controller.view addSubview:_txtView];
// [controller.view addSubview:_imageview];
NSLog(#"Unloadscrollviewwithpage");
// [[NSURLCache sharedURLCache] removeAllCachedResponses];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)sender {
// We don't want a "feedback loop" between the UIPageControl and the scroll delegate in
// which a scroll event generated from the user hitting the page control triggers updates from
// the delegate method. We use a boolean to disable the delegate logic when the page control is used.
if (pageControlUsed) {
// do nothing - the scroll was initiated from the page control, not the user dragging
return;
}
// Switch the indicator when more than 50% of the previous/next page is visible
CGFloat pageWidth = _scrollView.frame.size.width;
int page = floor((_scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pageControl.currentPage = page;
// NSLog(#"current page %d",page);
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
[self unloadScrollViewWithPage:page - 2];
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
[self unloadScrollViewWithPage:page + 2];
count=page+1;
// [self newCountTitleSet];
// A possible optimization would be to unload the views+controllers which are no longer visible
}
// At the begin of scroll dragging, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollViewLoc
{
CGFloat pageWidth = scrollViewLoc.frame.size.width;
CGPoint translation = [scrollViewLoc.panGestureRecognizer translationInView:scrollViewLoc.superview];
int page = floor((scrollViewLoc.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
if(translation.x > 0)
{
if(_strCurrentNewsSelect!=0)
{
if(page==0)
{
NSLog(#"OK");
NSLog(#"scrollviewwillbegindragging=0");
[self DownLoadDataPrevious:[_strCurrentNewsSelect.integervalue]-1];
}
}
else{
if(page==1)
{
NSLog(#"previous button");
[self btnPreviousClick];
}
}
} else
{
// [_txtView setText:[Dic valueForKey:#"ARTICLE_BODY"]];
// [controller.view addSubview:_txtView];
// [controller.view addSubview:_txtView];
// [controller.view addSubview:_imageview];
NSLog(#"loadscrollviewwithpage else");
[self btnPreviousClick];
NSLog(#"previous news");
// if(galleryItemClick+1!=[arrGallaeryUrl count])
//
// {
//
if(page+1==[_arrUrlLinks count])
//
{
//
NSLog(#"====....>>>>>>>");
}
count=count+1;
}
}
By using this code I am able to create the view controllers according to my array count[_arrUrlLinks] but the contents are not loaded on these views. On my first view I can only see an image view in black color rest of the views are blank.
How can I get the contents loaded on these views?

I can't figure this crash out: [__NSArrayM insertObject:atIndex:]: object cannot be nil

I am having the [__NSArrayM insertObject:atIndex:]: object cannot be nil crash when I test the app on my device, but not on the iOS simulator.
Here's what going on:
I am managing 5 UITextField on a View Controller, then I am passing the text of each UITextField to a another View Controller via an NSString using an IBAction (when I press the button, it crashes).
TextViewController
- (IBAction)choicebutton:(id)sender {
AnswerViewController *AVC = [self.storyboard instantiateViewControllerWithIdentifier:#"AnswerViewController"];
AVC.stringFromChoice1 = self.choice1.text;
AVC.stringFromChoice2 = self.choice2.text;
AVC.stringFromChoice3 = self.choice3.text;
AVC.stringFromChoice4 = self.choice4.text;
AVC.stringFromChoice5 = self.choice5.text;
[self presentViewController:AVC animated:YES completion:nil];
}
Then on the AnswerViewController, I am creating an NSMutableArray and randomizing the NSStrings to be displayed on a UILabel.
AnswerViewController
- (void)viewDidLoad
{
self.choiceAnswers1 = [[NSMutableArray alloc] initWithCapacity:5];
if(![self.stringFromChoice1 isEqualToString:#""])
{
[self.choiceAnswers1 addObject:self.stringFromChoice1];
}
if(![self.stringFromChoice2 isEqualToString:#""])
{
[self.choiceAnswers1 addObject:self.stringFromChoice2];
}
if(![self.stringFromChoice3 isEqualToString:#""])
{
[self.choiceAnswers1 addObject:self.stringFromChoice3];
}
if(![self.stringFromChoice4 isEqualToString:#""])
{
[self.choiceAnswers1 addObject:self.stringFromChoice4];
}
if(![self.stringFromChoice5 isEqualToString:#""])
{
[self.choiceAnswers1 addObject:self.stringFromChoice5];
}
int index = arc4random() % [self.choiceAnswers1 count];
self.choiceanswer.text = self.choiceAnswers1[index];
self.choiceanswer1.text = self.choiceAnswers1[index];
}
I've set it up this way in case the user doesn't fill all of the UITextFields, does this have to do anything with the crash? I can't figure this one out, please help!
Thanks!
Don’t use compare: against the empty string—it doesn’t catch the case where your string is nil and not #“”. Those are two distinct cases.
Instead of this:
if(![self.stringFromChoice1 isEqualToString:#""])
{
[self.choiceAnswers1 addObject:self.stringFromChoice1];
}
use this:
if (self.stringFromChoice1.length)
[self.choiceAnswers1 addObject:self.stringFromChoice1];
Since in C any non-0 value is true, and since sending a message to a nil object always returns 0, this catches all the cases. And is less wordy.
Less code is better code!
Change you viewDidLoad something like this.
- (void)viewDidLoad
{
self.choiceAnswers1 = [[NSMutableArray alloc] init];
if(self.stringFromChoice1.length > 0)
{
[self.choiceAnswers1 addObject:self.stringFromChoice1];
}
if(self.stringFromChoice2.length > 0)
{
[self.choiceAnswers1 addObject:self.stringFromChoice2];
}
if(self.stringFromChoice3.length > 0)
{
[self.choiceAnswers1 addObject:self.stringFromChoice3];
}
if(self.stringFromChoice4.length > 0)
{
[self.choiceAnswers1 addObject:self.stringFromChoice4];
}
if( self.stringFromChoice5.length > 0)
{
[self.choiceAnswers1 addObject:self.stringFromChoice5];
}
int index = arc4random() % [self.choiceAnswers1 count];
self.choiceanswer.text = self.choiceAnswers1[index];
self.choiceanswer1.text = self.choiceAnswers1[index];
}
Let me know it that helps.. :)

Resources