Drawing 2 UIImage merged with different UILabel - ios

I've been trying to create a for loop which take UILabel.text and merge it into an UIImage then save it into an instance and then when getting into the for loop second time it would save the result in different instance.
The problem that I'm facing is that it is saving the first UIImage but with low quality and skipping the second one. I've even tried to do the UIImage saving code in a button action but still didn't work.
-(void)CreateTheImage{
UIImage * img = [UIImage imageNamed:#"SquareBackground.jpg"];
UIGraphicsBeginImageContext(_imgView.bounds.size);
int Counter = 0;
for (UIView * view in [_imgView subviews]){
[view removeFromSuperview];
}
NSString *txt1 = #"Test";
NSString *txt2 = #"Worked Well";
[array addObject:txt1];
[array addObject:txt2];
UILabel *lbl = [[UILabel alloc]init];
NSLog(#"%i",[array count]);
NSLog(#"Before the loop");
for (int x = 0; x < [array count]; x++) {
NSLog(#"Entered the loop");
NSLog(#"x = %i",x);
lbl.text = [array objectAtIndex:x];
NSLog(#"lbl.text = %#",[array objectAtIndex:x]);
lbl.textAlignment = NSTextAlignmentCenter;
[lbl setBackgroundColor:[UIColor clearColor]];
lbl.font = [UIFont boldSystemFontOfSize:16];
[lbl setFrame:CGRectMake(20,112.5, 260, 75)];
[_imgView addSubview:lbl];
[_imgView bringSubviewToFront:lbl];
[_imgView setImage:img];
[_imgView.layer renderInContext:UIGraphicsGetCurrentContext()];
Counter = x+1;
NSLog(#"counter = %i",Counter);
switch (Counter) {
case 1:
NSLog(#"swintch case 1");
newImage1 = UIGraphicsGetImageFromCurrentImageContext();
break;
case 2:
NSLog(#"swintch case 2");
newImage2 = UIGraphicsGetImageFromCurrentImageContext();
break;
default:
break;
}
NSLog(#"after switch");
UIGraphicsEndImageContext();
}
//To save the picture in the album
UIImageWriteToSavedPhotosAlbum(newImage1, nil, nil, nil);
UIImageWriteToSavedPhotosAlbum(newImage2, nil, nil, nil);
NSLog(#"After the loop");
}
Also when I run this method on my iPhone it gives me a warning which is
CreatingVideo[334] : CGContextSaveGState: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

Your code doesn't make sense. You have a for loop that runs through an array, adds images to an image view, captures 1 of 2 images from the current off-screnen context, and then ends the image context after the first pass through the array. On the second pass, the context doesn't exist any more, so the second end context call will fail.
Move the end context outside of your for loop. That should fix your warning.
Even then, I'm not sure if it will work to remove subviews from an image view, add new views, an render the content to a graphics context, all without returning. UIKit view drawing usually queues changes to the UI until your code returns, then renders it on the next pass through the event loop.

Thanks to Duncan C for helping me find the answer and correct the code to work perfectly now
-(void)CreateTheImage{
UIImage * img = [UIImage imageNamed:#"SquareBackground.jpg"];
UIGraphicsBeginImageContextWithOptions(CGSizeMake(320, 320), NO, 0.0f);
int Counter = 0;
NSString *txt1 = #"Test";
NSString *txt2 = #"Worked Well";
[array addObject:txt1];
[array addObject:txt2];
UILabel *lbl = [[UILabel alloc]init];
NSLog(#"%i",[array count]);
NSLog(#"Before the loop");
for (int x = 0; x < [array count]; x++) {
for (UIView * view in [_imgView subviews]){
[view removeFromSuperview];
}
NSLog(#"Entered the loop");
NSLog(#"x = %i",x);
lbl.text = [array objectAtIndex:x];
NSLog(#"lbl.text = %#",[array objectAtIndex:x]);
lbl.textAlignment = NSTextAlignmentCenter;
[lbl setBackgroundColor:[UIColor clearColor]];
lbl.font = [UIFont boldSystemFontOfSize:25];
[lbl setFrame:CGRectMake(20,122.5, 280, 75)];
[_imgView addSubview:lbl];
[_imgView bringSubviewToFront:lbl];
[_imgView setImage:img];
[_imgView.layer renderInContext:UIGraphicsGetCurrentContext()];
Counter = x+1;
NSLog(#"counter = %i",Counter);
switch (Counter) {
case 1:
newImage1 = UIGraphicsGetImageFromCurrentImageContext();
NSLog(#"swintch case 1");
break;
case 2:
NSLog(#"swintch case 2");
newImage2 = UIGraphicsGetImageFromCurrentImageContext();
break;
default:
break;
}
NSLog(#"after switch");
}
UIGraphicsEndImageContext();
//To save the picture in the album
UIImageWriteToSavedPhotosAlbum(newImage1, nil, nil, nil);
UIImageWriteToSavedPhotosAlbum(newImage2, nil, nil, nil);
NSLog(#"After the loop");
}

Related

stop UIimageview animation at last image

NSArray *imageNames = #[#"2_00000.png", #"2_00001.png", #"2_00002.png", #"2_00003.png",
#"2_00004.png", #"2_00005.png", #"2_00006.png", #"2_00007.png",
#"2_00008.png", #"2_00009.png", #"2_00010.png", #"2_00011.png",
#"2_00012.png", #"2_00013.png", #"2_00014.png", #"2_00015.png",
#"2_00016.png", #"2_00017.png", #"2_00018.png", #"2_00019.png",
#"2_00020.png", #"2_00021.png", #"2_00022.png", #"2_00023.png",
#"2_00024.png", #"2_00025.png", #"2_00026.png", #"2_00027.png",
#"2_00028.png", #"2_00029.png", #"2_00030.png", #"2_00031.png",
#"2_00032.png", #"2_00033.png", #"2_00034.png", #"2_00035.png",
#"2_00036.png", #"2_00037.png", #"2_00038.png", #"2_00039.png",
#"2_00040.png", #"2_00041.png", #"2_00042.png", #"2_00043.png",
#"2_00044.png", #"2_00045.png", #"2_00046.png", #"2_00047.png",
#"2_00048.png", #"2_00049.png", #"2_00050.png", #"2_00051.png",
#"2_00052.png", #"2_00053.png", #"2_00054.png", #"2_00055.png",
#"2_00056.png", #"2_00057.png", #"2_00058.png", #"2_00059.png",
#"2_00060.png", #"2_00061.png", #"2_00062.png", #"2_00063.png"];
NSMutableArray *images = [[NSMutableArray alloc] init];
for (int i = 1; i < imageNames.count; i++) {
[images addObject:[UIImage imageNamed:[imageNames objectAtIndex:i]]];
}
// Normal Animation
UIImageView *animationImageView = [[UIImageView alloc] initWithFrame:CGRectMake(-6, 40, 200, 1034)];
animationImageView.animationImages = images;
animationImageView.animationDuration = 2;
animationImageView.animationRepeatCount = 0;
[self.view addSubview:animationImageView];
[animationImageView startAnimating];
If you know the animationRepeatCount before starting your animation
animationImageView.animationRepeatCount = 1 //For 1 loop
animationImageView.image = animationImageView.animationImages.lastObject;
For stoping animation dynamically
animationImageView.animationRepeatCount = 0 //infinite loop
When you need to stop the animation
[animationImageView stopAnimating];
animationImageView.image = animationImageView.animationImages.lastObject;
first set the animationRepeatCount to 1 and after starting the animation create a block that fires after the animation duration in this block set the animationImageView image to the last image .
dispatch_time_t dispatchAfter = dispatch_time(DISPATCH_TIME_NOW, animationImageView.animationDuration * NSEC_PER_SEC);
dispatch_after(dispatchAfter, dispatch_get_main_queue(), ^(void){
animationImageView.image = [images lastObject];
});
You could use transitionWithView:duration:options:animation:completion: of UIView for animating your UIImageView.
- (void)animatePictureTransition:(NSMutableArray *)arrayImages{
[UIView transitionWithView:imageViewButton
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
UIImage *newImage = (UIImage *)arrayImages.firstObject;
imageViewButton.image = newImage;
} completion:^(BOOL finished){
[arrayImages removeObjectAtIndex:0];
if(arrayImages.count) {
[self animatePicturesTransition:arrayImages];
}
}];
}
You could use this recursive, and call the method again inside the completion blog and pass through the remaining UIImages this way there shouldn't be a problem to stop at the last UIImages.
I would also recommend you, to load the UIImages dynamically from the resource folder in this way:
- (NSMutableArray *)getImagesWithSuffix:(NSString *)start andEndSuffix:(NSString *)end{
NSMutableArray *imageArray = [[NSMutableArray alloc] init];
for (int i = 1; i < 100; i++) {
NSString *fileName = [NSString stringWithFormat:#"%#%d%#.png", start, i, end];
if([self fileExistsInProject:fileName]){
[imageArray addObject:[UIImage imageNamed:fileName]];
} else {
break;
}
}
return imageArray;
}
Always writing all names of your UIImages takes a lot of time and can cause any problems. This way you just have to order your pictures so you can loop over.
To use this code, create a category of NSMutableArray and you can use it!
problem is with this line..
animationImageView.animationRepeatCount = 0;
by setting animationRepeatCount = 0 its set to infinite by default.
if u want it stop at last image you can go with
animationImageView.animationRepeatCount = 1; // specify no of times u need to run your animation.

CATiledLayer subview causing memory warning and crash [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
Alright, here's what's happening... I have a UIView subclass, which includes two points (start and end), a CGPath between those two points and lot of UILabels. If I add that UIView subclass as a subview to my scrollview (over top of my CATiledLayer based UIView) then my app starts getting memory warnings and eventually crashes. However, if I remove the UIView subclass that contains the points and path and leave the CATiledLayer view as it is, everything functions perfectly and no crashing or memory warnings occur.
Does anyone have any ideas on why this is occurring? The content view shouldn't have any problems being so big should it since I'm only draw labels that are at max 40px wide and a CGPath, which is also pretty small?
This is a mapping application
Here's some code:
//Display the map image
- (void)displayTiledImageNamed:(NSString *)imageName size:(CGSize)imageSize {
self.zoomScale = 1.0;
container = [[UIView alloc] initWithFrame:(CGRect){ CGPointZero, imageSize }];
_zoomView = [[UIImageView alloc] initWithFrame:(CGRect){ CGPointZero, imageSize }];
NSString *path = [NSString stringWithFormat:#"%#/%#-Small.png",[[NSBundle mainBundle] bundlePath], [imageName stringByDeletingPathExtension]];
UIImage *zoomImage = [UIImage imageWithContentsOfFile:path];
[_zoomView setImage:zoomImage];
[container addSubview:_zoomView];
[_zoomView release];
_tilingView = [[UMTileView alloc] initWithImageName:imageName size:imageSize];
_tilingView.frame = _zoomView.bounds;
[_zoomView addSubview:_tilingView];
[_tilingView release];
[self configureForImageSize:imageSize];
//This is the view that's causing the crash and memory warnings
//If this view is commented out the app functions just fine
UMMapContentView *m = [[UMMapContentView alloc] initWithFrame:CGRectMake(0,0,imageSize.width,imageSize.height) andColors:self.colors mapView:self.mapView];
self.contentView = m;
[container addSubview:self.contentView];
[m release];
[self addSubview:container];
[container release];
}
This my path view class which is another subview inside the UMMapContentView view above:
+ (Class)layerClass {
return [CATiledLayer class];
}
+ (CFTimeInterval)fadeDuration {
return 0.0;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.userInteractionEnabled = NO;
self.backgroundColor = [UIColor clearColor];
}
return self;
}
- (void)dealloc {
self.path = nil;
self.pathColor = nil;
[super dealloc];
}
- (void)resetPathView {
CATiledLayer *tiledLayer = (CATiledLayer*)self.layer;
tiledLayer.contents = nil;
[tiledLayer setNeedsDisplay];
}
- (void)drawPath:(UMPath*)p {
self.path = p;
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
if (self.path) {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, self.pathColor.CGColor);
CGContextSetShadowWithColor(context, CGSizeMake(2.0, 1.0), 1.0, [[UIColor colorWithWhite:0.2 alpha:0.8] CGColor]);
CGContextSetLineWidth(context, 8.0);
CGContextBeginPath (context);
CGContextMoveToPoint (context, ((UMMapPoint*)[self.path.points objectAtIndex: 0]).x, ((UMMapPoint*)[self.path.points objectAtIndex: 0]).y);
for (int i = 1; i < self.path.points.count; i++) {
CGContextAddQuadCurveToPoint (context, ((UMMapPoint*)[self.path.points objectAtIndex:i-1]).x, ((UMMapPoint*)[self.path.points objectAtIndex: i-1]).y, ((UMMapPoint*)[self.path.points objectAtIndex:i]).x, ((UMMapPoint*)[self.path.points objectAtIndex:i]).y);
}
CGContextStrokePath (context);
}
}
And this is my method that places all the UILabels in the UMMapContentView view:
- (void)mapAllLabelsInNavigationMap:(int)navigationMap {
//There are 1109 label dictionaries in the labels array
for (NSDictionary *dict in labels) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake([[dict objectForKey:#"X"] floatValue],[[dict objectForKey:#"Y"] floatValue],[[dict objectForKey:#"Width"] floatValue],[[dict objectForKey:#"Height"] floatValue])];
[label setLineBreakMode:NSLineBreakByWordWrapping];
[label setNumberOfLines:0];
[label setBackgroundColor:[UIColor clearColor]];
[label setTextColor:[self colorFromHexString:[dict objectForKey:#"Foreground"]]];
[label setFont:[UIFont systemFontOfSize:[[dict objectForKey:#"FontSize"] floatValue]]];
[label setTextAlignment:NSTextAlignmentCenter];
[label setText:[[UMDataBase shared] stringForID:[[dict objectForKey:#"Texts_ID"] intValue] withLanguage:languageID]];
[self addSubview:label];
[localMapLabels addObject:label];
[label release];
}
}
I'm not really sure what direction I need to head... Any help would be much appreciated! :)
You did not give the source code of UMMapContentView, but if it uses CATiledLayer, then that may be the problem. It seems that you cannot subview a CATiledLayer-backed view.
Scroll to the bottom (in the comments section): http://red-glasses.com/index.php/tutorials/catiledlayer-how-to-use-it-how-it-works-what-it-does/
It may be easier if you write your own tiled layer anyhow. Documentation on CATiledLayer is sparse while the bugs are aplenty.

Trouble with animation on UIImageView

I have 7 images which i'm trying to make fade in/out of 1 ImageView. I have stored all the images in an array, and then have a loop to display each image and fade into the next, however, when i run the program only the last 2 images show up. Any ideas on why this is? and how to fix it? Code is below.
imageArray = [NSArray arrayWithObjects:
[UIImage imageNamed:#"image 0.jpg"],
[UIImage imageNamed:#"image 1.jpg"],
[UIImage imageNamed:#"image 2.jpg"],
[UIImage imageNamed:#"image 3.jpg"],
[UIImage imageNamed:#"image 4.jpg"],
[UIImage imageNamed:#"image 5.jpg"],
[UIImage imageNamed:#"image 6.jpg"],
nil];
self.imageview.backgroundColor = [UIColor blackColor];
self.imageview.clipsToBounds = YES;
int count = [imageArray count];
for (int i = 0; i <count-1 ; i++)
{
UIImage *currentImage = [imageArray objectAtIndex: i];
UIImage *nextImage = [imageArray objectAtIndex: i +1];
self.imageview.image = [imageArray objectAtIndex: i];
[self.view addSubview:self.imageview];
CABasicAnimation *crossFade = [CABasicAnimation animationWithKeyPath:#"contents"];
crossFade.duration = 5.0;
crossFade.fromValue = (__bridge id)(currentImage.CGImage);
crossFade.toValue = (__bridge id)(nextImage.CGImage);
[self.imageview.layer addAnimation:crossFade forKey:#"animateContents"];
self.imageview.image = nextImage;
};
Some things to note:
1) You are doing everything synchronously on a loop that has no delay between each transition, there's no point in animating a if on the next loop it will be replaced by the next and so on, until the last 2. Also, you are adding your imageView as a subview every time, also unnecessary.
2) You are changing the .image property of the imageView, and then changing the contents of the layer. Might as well use an UIView and have the same effect.
My recommendation is to make a method to swap from one image to the next, and have a NSTimer call the function every x amount of seconds until you passed through them all.
Edit: For the future:
self.imageview.backgroundColor = [UIColor blackColor];
self.imageview.clipsToBounds = YES;
are completely unnecessary :)
The .backgroundColor is drawn over by the UIImage you are displaying.
The .clipsToBounds is the default behavior of UIImageView (it shrinks/expands your image to it's size, but never draws outside)

Image scrollview crashes

I've implemented a scrollview with paging to scroll between some images (graphs) at full page (like the Photo app installed in the iPhone).
I found the code below that use the classical 3 pages solution (I made some small modification for my application) but, even if it "works", the scrolling seems to be slow and often after I've scrolled some images the application crashes.
I'm using Xcode 4.2 with ARC option enabled and testing both on an iPad device.
Images (10 jpg) are 2048x1539 with a mean dimension of 200/250Kb each.
Is there anyone that can help me in finding the cause of the problem ?
Thanks,
Corrado
const int numImages = 10;
const float kPageWidth = 1024.0f;
const float kPageHeight = 768.0f;
- (void)viewDidLoad {
[super viewDidLoad];
scroll.contentSize = CGSizeMake(kPageWidth * numImages, kPageHeight);
imageview1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kPageWidth, kPageHeight)];
imageview2 = [[UIImageView alloc] initWithFrame:CGRectMake(kPageWidth, 0, kPageWidth, kPageHeight)];
imageview3 = [[UIImageView alloc] initWithFrame:CGRectMake(kPageWidth * 2, 0, kPageWidth, kPageHeight)];
scroll.contentOffset = CGPointMake(0, 0);
[imageview1 setImage:[UIImage imageNamed:#"grafico_0.jpg"]];
imageview1.contentMode = UIViewContentModeScaleAspectFit;
[imageview1 setTag:1];
imageview2.contentMode = UIViewContentModeScaleAspectFit;
[imageview2 setTag:2];
imageview3.contentMode = UIViewContentModeScaleAspectFit;
[imageview3 setTag:3];
[scroll addSubview:imageview1];
[scroll addSubview:imageview2];
[scroll addSubview:imageview3];
}
- (void)scrollViewDidScroll:(UIScrollView*)scrollView {
const CGFloat currPos = scrollView.contentOffset.x;
const NSInteger selectedPage = lroundf(currPos * (1.0f / kPageWidth));
const NSInteger zone = 1 + (selectedPage % 3);
const NSInteger nextPage = selectedPage + 1;
const NSInteger prevPage = selectedPage - 1;
/// Next page
if (nextPage < numImages)
{
NSInteger nextViewTag = zone + 1;
if (nextViewTag == 4)
nextViewTag = 1;
UIImageView* nextView = (UIImageView*)[scrollView viewWithTag:nextViewTag];
nextView.frame = (CGRect){.origin.x = nextPage * kPageHeight, .origin.y = 0.0f, kPageHeight, kPageWidth};
NSString *str = [NSString stringWithFormat:#"grafico_%d.jpg", nextPage];
UIImage* img = [UIImage imageNamed:str];
nextView.image = img;
}
/// Prev page
if (prevPage >= 0)
{
NSInteger prevViewTag = zone - 1;
if (!prevViewTag)
prevViewTag = 3;
UIImageView* prevView = (UIImageView*)[scrollView viewWithTag:prevViewTag];
prevView.frame = (CGRect){.origin.x = prevPage * kPageHeight, .origin.y = 0.0f, kPageHeight, kPageWidth};
NSString *str = [NSString stringWithFormat:#"grafico_%d.jpg", prevPage];
UIImage* img = [UIImage imageNamed:str];
prevView.image = img;
}
}
You should not use imageNamed: for the loading of your large images, because that method caches the images and should only be used for small images that you use multiple times in your App (like images for buttons etc.). That method is notorious for causing memory problems when used with many large images.
Switch to imageWithContentsOfFile: instead. Loading your images with that methods secures that the images are not cached and the memory is freed after you do not use that images any more.
If the scrolling seems to be sluggish you can move the loading of the image to a background thread using performSelectorInBackground:
[self performSelectorInBackground:#selector(retrieveImageData:) withObject:imagePath];
the loading of the UIImage happens in this method:
- (void)retrieveImageData:(NSString *)imagePath {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
[self performSelectorOnMainThread:#selector(imageDataRetrieved:) withObject:image waitUntilDone:NO];
[pool release];
}
and the attachment of the image to the UIImageView on the main thread (UI manipulations must not happen on a background Thread):
- (void)imageDataRetrieved:(UIImage)*image {
yourImageView.image = image;
}

TKCalendar - Custom image for day?

I'm using the standard implementation of the TKCalendar for iOS and because there isn't much documentation on it I was wondering if anyone knows of a simply way of setting a custom image for a day of the month.
Any help is greatly appreciated!
You may follow below steps to set custom image
You have to right click the TapkuLibrary.bundle and select show packet content
Now you can see folder as Images if you open that image folder you can see some folders
Among that folders you have to open the calendar folder
You can see so many images. now you can change images whatever you want
I think it may help you.
Just edit the images in TapkuLibrary.bundle (right click, show packet content)
No, that's all of your answers are wrong. What I wanted was the ability to change each day's image to a custom image that I would choose for every day.
I hacked the code together and got it to work . If anyone is looking for how to do this, just got go to TKCalendarMonthView.m and find the
- (void) drawRect:(CGRect)rect
method. Now in this method, copy in the following (this is a simplified version of the code that I have so you have to build it up yourself):
CGContextRef context = UIGraphicsGetCurrentContext();
UIImage *tile = [UIImage imageWithContentsOfFile:TKBUNDLE(#"TapkuLibrary.bundle/Images/calendar/Month Calendar Date Tile.png")];
CGRect r = CGRectMake(0, 0, 46, 44);
CGContextDrawTiledImage(context, r, tile.CGImage);
int index = 0;
UIFont *font = [UIFont boldSystemFontOfSize:dateFontSize];
UIFont *font2 =[UIFont boldSystemFontOfSize:dotFontSize];
UIColor *color = [UIColor grayColor];
//first do the boxes that are still visible from the previous month
//
//
if(firstOfPrev>0){
[color set];
for(int i = firstOfPrev;i<= lastOfPrev;i++){
r = [self rectForCellAtIndex:index];
///////////////////////////
///////////////////////////
///////////////////////////
int indexMoved = 7;
r.origin.y -= indexMoved; //this moves the block to put it back in it's place
//add an image to the rect - note you can add them over each other
[[UIImage imageNamed:[NSString stringWithFormat:#"t.png"]] drawInRect:r];
r.origin.y += indexMoved; //move back the block
///////////////////////////
///////////////////////////
///////////////////////////
if ([marks count] > 0)
[self drawTileInRect:r day:i mark:[[marks objectAtIndex:index] boolValue] font:font font2:font2];
else
[self drawTileInRect:r day:i mark:NO font:font font2:font2];
index++;
}
}
//Now to blocks for current month
//
//
color = [UIColor colorWithRed:59/255. green:73/255. blue:88/255. alpha:1];
[color set];
for(int i=1; i <= daysInMonth; i++){
r = [self rectForCellAtIndex:index];
///////////////////////////
///////////////////////////
///////////////////////////
int indexMoved = 7;
r.origin.y -= indexMoved; //this moves the block to put it back in it's place
//add an image to the rect - note you can add them over each other
[[UIImage imageNamed:[NSString stringWithFormat:#"t.png"]] drawInRect:r];
r.origin.y += indexMoved; //move back the block
///////////////////////////
///////////////////////////
///////////////////////////
if(today == i){ //this is done to highlight today's block
int indexMoved = 7;
r.origin.y -= indexMoved;
[[UIColor colorWithRed:59/255. green:73/255. blue:88/255. alpha:1] set];
//set the image to whatever you want today's block to have
[[UIImage imageNamed:[NSString stringWithFormat:#"Tile-Border-Green.png"]] drawInRect:r];
r.origin.y += indexMoved;
}
if ([marks count] > 0)
[self drawTileInRect:r day:i mark:[[marks objectAtIndex:index] boolValue] font:font font2:font2];
else
[self drawTileInRect:r day:i mark:NO font:font font2:font2];
index++;
}
//Finally, do blocks for the next month who's blocks are visible
//
//
[[UIColor grayColor] set];
int i = 1;
while(index % 7 != 0){
r = [self rectForCellAtIndex:index] ;
///////////////////////////
///////////////////////////
///////////////////////////
int indexMoved = 7;
r.origin.y -= indexMoved; //this moves the block to put it back in it's place
//add an image to the rect - note you can add them over each other
[[UIImage imageNamed:[NSString stringWithFormat:#"t.png"]] drawInRect:r];
r.origin.y += indexMoved; //move back the block
///////////////////////////
///////////////////////////
///////////////////////////
if ([marks count] > 0)
[self drawTileInRect:r day:i mark:[[marks objectAtIndex:index] boolValue] font:font font2:font2];
else
[self drawTileInRect:r day:i mark:NO font:font font2:font2];
i++;
index++;
}
Notice that it's spilt into three main areas (each with a for loop). These are (in order) the blocks from the previous month that are still visible, the blocks from the current month and lastly the blocks from the coming month that are visible in the current view.
I really hope this helps someone because it took be a lot of headache to set up!
Cheers!

Resources