First I wanna say thanks for all the helpful answers on this site. I starting programming about six months ago and many of the things I've learned have been from questions/answers here.
I'm using the Calendar from Tapku Library in an iPhone project and want the calendar tiles to be transparent so that I can see the view behind my TKCalendarMonthView view.
I implemented the TKCalendarMonthView using the code from this tutorial by Benjamin Pearson.
Then I removed the tile images and tried code from this answer by #Jacques, so the drawrect function in TKCalendarMonthView.m looks like this:
- (void) drawRect:(CGRect)rect {
//From Jacques' StackOverflow answer (I also put this in the init)
self.opaque = NO;
self.backgroundColor = [UIColor clearColor];
//From Jacques' answer
[[UIColor clearColor] setFill
];
UIRectFill(rect);
//Remove CGContextRef
//CGContextRef context = UIGraphicsGetCurrentContext();
//UIImage *tile = [UIImage imageWithContentsOfFile:TKBUNDLE(#"TapkuLibrary.bundle/Images/calendar/Month Calendar Date Tile.png")];
CGRect r = CGRectMake(0, 0, 46, 44);
//From Jacques' StackOverflow answer
[[UIColor clearColor] setFill];
UIRectFill(r);
//Remove this sense we won't use the tile image
//CGContextDrawTiledImage(context, r, tile.CGImage);
if(today > 0){
int pre = firstOfPrev > 0 ? lastOfPrev - firstOfPrev + 1 : 0;
int index = today + pre-1;
CGRect r =[self rectForCellAtIndex:index];
r.origin.y -= 7;
//Don't use image here
//[[UIImage imageWithContentsOfFile:TKBUNDLE(#"TapkuLibrary.bundle/Images/calendar/Month Calendar Today Tile.png")] drawInRect:r];
}
int index = 0;
UIFont *font = [UIFont boldSystemFontOfSize:dateFontSize];
UIFont *font2 =[UIFont boldSystemFontOfSize:dotFontSize];
//Change the font for our dates:
font = [UIFont fontWithName:#"HelveticaNeue-Light" size:dateFontSize];
font2 = [UIFont fontWithName:#"HelveticaNeue-Light" size:dateFontSize];
UIColor *color = [UIColor grayColor];
if(firstOfPrev>0){
[color set];
for(int i = firstOfPrev;i<= lastOfPrev;i++){
r = [self rectForCellAtIndex:index];
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++;
}
}
//Set the color for all dates in the current month that are not today
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];
if(today == i) [[UIColor whiteColor] set];
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];
if(today == i) [color set];
index++;
}
[[UIColor grayColor] set];
int i = 1;
while(index % 7 != 0){
r = [self rectForCellAtIndex:index] ;
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++;
}
}
The problem is that now the tiles (CGRects) are black; or whatever view is directly behind the them is black, and, frankly, I'm a bit lost in Tapku's code. Does anyone know why the tiles are black? Or where in the Tapku code I should be looking? I'm not very familiar with Core Graphics, so maybe I'm missing something basic/obvious.
NOTE: I also tried changing the color of TKCalendarMonthView's tileBox (which is a UIScrollView that seems to contain the calendar tiles) and although it did change color it didn't effect the tiles' background color.
Thanks in advance! And please let me know if any of this is unclear.
You can transparent calendar tiles by following steps
Step-1
Comment the code in TKCalendarMonthView.m
+ (void) initialize{
if (self == [TKCalendarMonthTiles class]){
//tileImage = [UIImage imageWithContentsOfFile:TKBUNDLE(#"calendar/Month Calendar Date Tile.png")];
}
}
Step-2
Change the code in TKCalendarMonthView.m
add line of code [self.currentTile setBackgroundColor:[UIColor clearColor]];
before the line [self.tileBox addSubview:self.currentTile];
in method - (void) _setupCurrentTileView:(NSDate*)date
so your code look like
- (void) _setupCurrentTileView:(NSDate*)date{
....
[self.currentTile setBackgroundColor:[UIColor clearColor]];
[self.tileBox addSubview:self.currentTile];
....
}
Finally I get how to make the background color clear in calender view.
Change code as below.
In TKCalendarMonthView.m
(1) Comment/remove below line.
+ (void) initialize
{
if (self == [TKCalendarMonthTiles class])
{
//tileImage = [UIImage imageWithContentsOfFile:TKBUNDLE(#"calendar/Month Calendar Date Tile.png")]; COMMENT THIS LINE
}
}
(2) In - (void) _setupCurrentTileView:(NSDate*)date method Add [self.currentTile setBackgroundColor:[UIColor clearColor]]; line as below
- (void) _setupCurrentTileView:(NSDate*)date{
if(self.currentTile) return;
NSDate *month = [date firstOfMonthWithTimeZone:self.timeZone];
NSArray *dates = [TKCalendarMonthTiles rangeOfDatesInMonthGrid:month startOnSunday:self.sunday timeZone:self.timeZone];
NSArray *data = [self.dataSource calendarMonthView:self marksFromDate:dates[0] toDate:[dates lastObject]];
self.currentTile = [[TKCalendarMonthTiles alloc] initWithMonth:month marks:data startDayOnSunday:self.sunday timeZone:self.timeZone];
[self.currentTile setTarget:self action:#selector(_tileSelectedWithData:)];
[self.currentTile setBackgroundColor:[UIColor clearColor]]; // ADD THIS LINE
[self.tileBox addSubview:self.currentTile];
self.monthYear.text = [date monthYearStringWithTimeZone:self.timeZone];
[self _updateSubviewFramesWithTile:self.currentTile];
}
Related
this is the way I create and add subviews into a view.
I'm wondering why the count always returns 0, when it should return "hundreds". What am I doing wrong, thanks!
I have added more code where shows clearly my issue. I copy/pasted all functions involved on my initial question.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.contenedor addSubview:vistaPanelBotones];
[self crearBotones];
}
- (void) crearBotones {
UIColor *colores[] = {
[UIColor blueColor],
[UIColor brownColor],
[UIColor redColor],
[UIColor orangeColor],
[UIColor greenColor],
[UIColor yellowColor],
[UIColor purpleColor],
[UIColor blackColor],
[UIColor whiteColor],
[UIColor darkGrayColor],
[UIColor magentaColor],
[UIColor cyanColor],
};
int indice = 0;
for (int col = 0; col < self.vistaPanelBotones.frame.size.width ; col=col+20) {
for (int fila = 0; fila < self.vistaPanelBotones.frame.size.height-20 ; fila = fila+20) {
CGRect frame = CGRectMake(col, fila, 20, 20);
Boton *boton = [Boton new];
boton.frame = frame;
boton.layer.backgroundColor = colores[(fila + col) % 7].CGColor;
boton.layer.cornerRadius = 0.25;
boton.layer.borderWidth = 0.25;
boton.layer.borderColor = [UIColor whiteColor].CGColor;
boton.layer.delegate = self;
[self.vistaPanelBotones addSubview:boton];
[boton setNeedsDisplay];
}
indice++;
}
NSLog(#"Vista Botones SubViews:%i",[[self.vistaPanelBotones subviews] count]);
}
- (IBAction)reiniciar:(id)sender {
if (self.vistaPanelBotones == nil){
NSLog(#"no existe la vista");
}
NSUInteger count = self.vistaPanelBotones.subviews.count;
NSLog(#"Vista SubViews: %i",count);
}
Here are a few of my thoughts:
I would check if self.vistaPanelBotones is non-nil, just in case (if it were nil, you would not get any errors in that code, but also no subviews).
Possibly executing this before you have a valid frame (IIRC, viewWillAppear is the earliest callback with valid geometry)
I'm pretty sure if boton was nil you would get an exception when adding as a subview, but it's another test worth using for debugging.
Use [[self.vistaPanelBotones subviews] count] to count the number of subviews, but there is an elegant way to remove all subviews from a view in Objective-C. Try this:
[[self.vistaPanelBotones subviews] makeObjectsPerformSelector:#selector(removeFromSuperView];
I have graph which shows percent sign on value given but i want the $ i am changing to $ in my code but it hides all the value also
-(void)drawHistogramWithItem:(ECGraphItem *)item index:(int)index color:(UIColor *)color
{
if (index != 0)
_histogramStartX += _histogramSpacing + item.width;
CGRect rect = CGRectMake(_histogramStartX, _xaxisStart.y - _ySpacingScale*item.yValue,item.width, _ySpacingScale*item.yValue);
[color setFill];
[[UIColor blackColor] setStroke];
CGContextAddRect(_context,rect);
CGContextDrawPath(_context, kCGPathFillStroke);
[[UIColor blackColor] set];
NSString *percentage = [NSString stringWithFormat:#"%.1f%%",item.yValue];
[percentage drawAtPoint:CGPointMake(_histogramStartX,_xaxisStart.y - _ySpacingScale*item.yValue - 15) withFont:[UIFont boldSystemFontOfSize:10]];
[self drawWords:item.name AtPoint:CGPointMake(_histogramStartX + item.width/8 ,_xaxisStart.y + 5) color:[UIColor blackColor]];
}
Just change that:
NSString *percentage = [NSString stringWithFormat:#"%.1f%%",item.yValue];
to that:
NSString *percentage = [NSString stringWithFormat:#"%.1f$",item.yValue];
It should work. Hope it helps
I have a custom class to create a textview with lines like the Notes app from Apple.
This is how the class looks:
NoteView.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#interface NoteView : UITextView <UITextViewDelegate> {
}
#end
NoteView.m
#import "NoteView.h"
#implementation NoteView
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor colorWithRed:1.0f green:1.0f blue:0.6f alpha:1.0f];
self.font = [UIFont fontWithName:#"Marker Felt" size:20];
}
return self;
}
- (void)drawRect:(CGRect)rect {
//Get the current drawing context
CGContextRef context = UIGraphicsGetCurrentContext();
//Set the line color and width
CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.2f].CGColor);
CGContextSetLineWidth(context, 1.0f);
//Start a new Path
CGContextBeginPath(context);
//Find the number of lines in our textView + add a bit more height to draw lines in the empty part of the view
NSUInteger numberOfLines = (self.contentSize.height + self.bounds.size.height) / self.font.leading;
//Set the line offset from the baseline.
CGFloat baselineOffset = 6.0f;
//Iterate over numberOfLines and draw each line
for (int x = 0; x < numberOfLines; x++) {
//0.5f offset lines up line with pixel boundary
CGContextMoveToPoint(context, self.bounds.origin.x, self.font.leading*x + 0.5f + baselineOffset);
CGContextAddLineToPoint(context, self.bounds.size.width, self.font.leading*x + 0.5f + baselineOffset);
}
//Close our Path and Stroke (draw) it
CGContextClosePath(context);
CGContextStrokePath(context);
}
#end
I add the view as a subview. Everything works fine, but the text only apears after I hit the return key. I can see the flashing cursor, when I type I can see the cursor moving, but the text is gone... After hitting the return key, the text becomes visible and after that everything works fine. Even when I select all the text, remove it and start typing the text is visible.
This is how the textarea looks like:
How to solve this?
Thanks in advance!
UPDATE:
This is how I alloc the view:
annotateText = [[NoteView alloc] initWithFrame:CGRectMake(85.0, 168.0, 600.0, 567.0)];
annotateText.backgroundColor = [UIColor clearColor];
[annotateText setText:[annotationNotes objectAtIndex:0]];
[paperAnnotationView addSubview:annotateText];
I know this question is pretty old. I ran into the same issue and was looking for a solution. So I thought I would post the answer here, just in case, if any one comes and looks for it. After pulling my hair for hours, I figured out that the text view wont display the text in the very first line (unless we press enter/return or scroll the text) when the bounds of the textview is off the screen. Even when the parent view is off the screen, I ran into the same issue.
Here is the code that I was working on.
self.captionView = [[[UIImageView alloc] initWithFrame:CGRectMake(231, 769, 563, 643)] autorelease]; //63
self.captionView.image = [UIImage imageNamed:#"ekp006_preview_fbsharecontainer"];
self.captionView.userInteractionEnabled = YES;
//self.captionView.layer.contents = (id)[UIImage imageNamed:#"ekp006_preview_fbsharecontainer"].CGImage;
UIButton *cancelButton = [[[UIButton alloc] initWithFrame:CGRectMake(10, 10, 73, 34)] autorelease];
[cancelButton setImage:[UIImage imageNamed:#"ekp006_preview_fbshare_btn_cancel"] forState:UIControlStateNormal];
[cancelButton setImage:[UIImage imageNamed:#"ekp006_preview_fbshare_btn_cancel_down"] forState:UIControlStateHighlighted];
[cancelButton addTarget:self action:#selector(cancelFacebookShare) forControlEvents:UIControlEventTouchUpInside];
[self.captionView addSubview:cancelButton];
UIButton *shareButton = [[[UIButton alloc] initWithFrame:CGRectMake(480, 10, 73, 34)] autorelease];
[shareButton setImage:[UIImage imageNamed:#"ekp006_preview_fbshare_btn_share"] forState:UIControlStateNormal];
[shareButton setImage:[UIImage imageNamed:#"ekp006_preview_fbshare_btn_share_down"] forState:UIControlStateHighlighted];
[shareButton addTarget:self action:#selector(facebookshare) forControlEvents:UIControlEventTouchUpInside];
[self.captionView addSubview:shareButton];
self.captionTextView = [[[UITextView alloc] initWithFrame:CGRectMake(20, 60, 523, 100)] autorelease];
self.captionTextView.textColor = [UIColor lightGrayColor];
self.captionTextView.delegate = self;
self.captionTextView.layer.shadowRadius = 5.0;
self.captionTextView.layer.shadowColor = [UIColor blackColor].CGColor;
self.captionTextView.layer.shadowOpacity = 0.8;
self.captionTextView.layer.borderColor = [UIColor blackColor].CGColor;
self.captionTextView.layer.borderWidth = 0.75;
self.captionTextView.layer.cornerRadius = 5.0f;
self.captionTextView.font = [UIFont fontWithName:#"VAGRoundedBlackSSi" size:18];
[self.captionView addSubview:self.captionTextView];
[[self topMostViewController].view addSubview:self.captionView];
If you see closely, the parent view for me (the caption view) was 769 in y origin and I made this explicit, so that I can make the view slide from bottom to top using UIView animations. In order to solve this, I had to take the alternate path of making the parent view frame as CGRectMake(231,63,563,643) and hide the entire view. And to present it I used something like this.
- (void) presentCaptionCaptureScreen
{
// The code which works
[AnimationEffects bounceAnimationForView:self.captionView afterTimeInterval:0];
self.captionTextView.textColor = [UIColor lightGrayColor];
self.captionTextView.text = #"Enter your caption for the photo";
// The code which didn't work
/*
[UIView animateWithDuration:0.7 animations:^
{
self.captionTextView.text = #"";
self.captionView.frame = CGRectMake(231, 63, 563, 643);
} completion:^(BOOL finished)
{
self.captionTextView.textColor = [UIColor lightGrayColor];
self.captionTextView.text = #"Enter your caption for the photo";
}];
*/
}
It worked for me!
Here's the problem:
I have a tab bar controller customized so the tab item highlights are yellow instead of the default blue. What's wrong is that the "More" item comes up because I have too many tab items (removing them is not really an option), and this "more" is still blue.
I used classes I got from the internet to implement the customization. Here is the code:
// UITabBar+ColorExtensions.m
#implementation UITabBar (ColorExtensions)
- (void)recolorItemsWithColor:(UIColor *)color shadowColor:(UIColor *)shadowColor shadowOffset:(CGSize)shadowOffset shadowBlur:(CGFloat)shadowBlur
{
CGColorRef cgColor = [color CGColor];
CGColorRef cgShadowColor = [shadowColor CGColor];
for (UITabBarItem *item in [self items])
if ([item respondsToSelector:#selector(selectedImage)] &&
[item respondsToSelector:#selector(setSelectedImage:)] &&
[item respondsToSelector:#selector(_updateView)])
{
CGRect contextRect;
contextRect.origin.x = 0.0f;
contextRect.origin.y = 0.0f;
contextRect.size = [[item selectedImage] size];
// Retrieve source image and begin image context
UIImage *itemImage = [item image];
CGSize itemImageSize = [itemImage size];
CGPoint itemImagePosition;
itemImagePosition.x = ceilf((contextRect.size.width - itemImageSize.width) / 2);
itemImagePosition.y = ceilf((contextRect.size.height - itemImageSize.height) / 2);
UIGraphicsBeginImageContext(contextRect.size);
CGContextRef c = UIGraphicsGetCurrentContext();
// Setup shadow
CGContextSetShadowWithColor(c, shadowOffset, shadowBlur, cgShadowColor);
// Setup transparency layer and clip to mask
CGContextBeginTransparencyLayer(c, NULL);
CGContextScaleCTM(c, 1.0, -1.0);
CGContextClipToMask(c, CGRectMake(itemImagePosition.x, -itemImagePosition.y, itemImageSize.width, -itemImageSize.height), [itemImage CGImage]);
// Fill and end the transparency layer
CGContextSetFillColorWithColor(c, cgColor);
contextRect.size.height = -contextRect.size.height;
CGContextFillRect(c, contextRect);
CGContextEndTransparencyLayer(c);
// Set selected image and end context
[item setSelectedImage:UIGraphicsGetImageFromCurrentImageContext()];
UIGraphicsEndImageContext();
// Update the view
[item _updateView];
}
}
#end
and the controller:
#implementation AATabBarController
- (void)viewDidLoad {
[super viewDidLoad];
// Put in a background
CGRect frame = CGRectMake(0.0, 0, self.view.bounds.size.width, 48);
backgroundView = [[UIView alloc] initWithFrame:frame];
[backgroundView setBackgroundColor:[UIColor colorWithRed:0.0
green:0.0
blue:0.0
alpha:0.1]];
[self.tabBar insertSubview:backgroundView atIndex:0];
}
-(void)dealloc {
[backgroundView release];
[super dealloc];
}
-(void)updateTabColor:(UIColor *)color {
// Recolor the tab bar
[self.tabBar recolorItemsWithColor:color shadowColor:[UIColor blackColor] shadowOffset:CGSizeMake(0.0f, -1.0f) shadowBlur:3.0f];
}
-(void)updateBackgroundColor:(UIColor *)color {
// Update the background color
[backgroundView setBackgroundColor:color];
}
#end
Does anyone know what I should do so the "more" tab item is the customized color?
That code looks very similar to the code in this question. I know you're asking a different question here (the linked Q asks "will my app be rejected" to which the answer is "yes"). Nevertheless, you're using the same private UITabBarItem methods, so it's unlikely that anyone can give you a reliable answer.
I am creating custom cell in my iphone aap and I am also adding an image to it but I continue to get error at [image drawatpoint:p];
the error states
*** -[UIImage drawAtPoint:]: message sent to deallocated instance 0x45cb1f0
my code is
-(void)setImage:(UIImage *)i
{
//[image release];
image = i;
[self setNeedsDisplay];
}
- (void)setNeedsDisplay
{
[super setNeedsDisplay];
[contentView setNeedsDisplay];
}
- (void)drawContentView:(CGRect)r
{
CGContextRef context = UIGraphicsGetCurrentContext();
UIColor *backgroundColor = [UIColor yellowColor];
UIColor *textColor = [UIColor blackColor];
if(self.selected)
{
backgroundColor = [UIColor clearColor];
textColor = [UIColor whiteColor];
}
[backgroundColor set];
CGContextFillRect(context, r);
CGPoint p;
p.x = 3;
p.y = 3;
[textColor set];
UIImage *image2 = image;
[image2 drawAtPoint:p];
p.x += 70; // space between words
[text2 drawAtPoint:p withFont:firstTextFont];
//[image release];
}
You do not retain the image in your setter (setImage:). As the error message says, it's gone at the time you try to draw it.