I have a UIViewController with some images. I need to draw some horizontal and vertical lines in between images. Actually its like a hierarchy view. Is adding subviews with background color the best way to go?
You have 3 basic approaches:
Use QuartzCore and override drawRect: in a custom UIView subclass
Set the borderWidth and borderColor of the UIImageView layer property that contains each image
Create UIViews of height 1 for horizontal lines and width 1 for vertical lines, set the backgroundColor of the views and add them as subviews
3 is probably the easiest to implement, but not the most elegant, 1 is the most robust in terms of memory as you can also use drawInRect to draw your images into the same graphics context. This collapses the view hierarchy into a single view.
You can do it using layers as answered above or simply since you want just lines,use UIViews
Just like this
for(i=0;i<numberOfLine*heightofImage;i+=heightOfImage) {
UIView *horizontalLine=[[UIView alloc]initWithFrame:CGRectMake(x, i, height, 1)];
[self.view addSubView:horizontalLine];
}
Hope that helps
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIView *verticalLine = [[UIView alloc] initWithFrame:CGRectMake(roundf(self.view.bounds.size.width / 2), 0.0, 1.0, self.view.bounds.size.height)];
verticalLine.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.5];
verticalLine.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
[self.view addSubview:verticalLine];
UIView *horizontalLine = [[UIView alloc] initWithFrame:CGRectMake(0.0, roundf(self.view.bounds.size.height / 2), self.view.bounds.size.width, 1.0)];
horizontalLine.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.5];
horizontalLine.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
[self.view addSubview:horizontalLine];
}
I used the 3rd option posted by Magic Bullet Dave and it is working great. Here's the code:
UIView *borderBottom = [[UIView alloc] initWithFrame:CGRectMake(0.0, 10, widthDesired, 1.0)];
borderBottom.backgroundColor = [UIColor grayColor];
[myView addSubview:borderBottom];
If you want to make a vertical line you'd simply use a width of 1 and then the height desired.
Related
I have a UIView in which I define it's border in the following manner:
self.layer.borderColor = [UIColor blackColor].CGColor;
self.layer.borderWidth = 3;
I attach a subview to this UIView, and when I move the subview over the border, it goes underneath it. Is this the intended behavior? Is there anyway to make the subview go on top of it?
According to the Apple specification: It is composited above the receiver’s contents and sublayers.
So, the border will always be above of all your subviews, even if you bring your subview to the front and so on.
So I make a background view to fake the border.
E.g.:
UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
backgroundView.backgroundColor = [UIColor blackColor];
backgroundView.clipsToBounds = NO;
UIView *bView = [[UIView alloc] initWithFrame:CGRectInset(backgroundView.bounds, 3, 3)];
bView.backgroundColor = [UIColor redColor];
UIView *cView = [[UIView alloc] initWithFrame:CGRectMake(-50, -50, 100, 100)];
cView.backgroundColor = [UIColor yellowColor];
[bView addSubview:cView];
[backgroundView addSubview:bView];
[self.window addSubview:backgroundView];
and the effect:
Depending on your view structure, it might be easier to add the subview to the parent of your main view. It can then overlap the main view and will overlay the border as you requested.
Did you try setting the superview's 'clipsToBounds' property to YES? This is set to NO by default for performance reasons, but setting it to yes might give you the effect you are looking for.
Insert layer at specific position that suits you:
self.layer.insertSublayer(sublayer, at: 0)
I've created a subview of UIView to make some drawings - the drawings work fine in the drawRect method of my subclass, however, I cannot change the background color of the view. A little googling tells me I haven't set the frame for the view, but I'm not entirely sure how to do this. I tried two things:
I create the view in Storyboard and add it to my view controller, then declare it as a property in the header file and link them up. I synthesize the property at the top of the implementation file and in the viewDidLoad method, I add:
[myView setBackgroundColor: [UIColor whiteColor]];
The view's background is still black.
I also tried:
ViewSubclass *v = [[ViewSubclass alloc] initWithFrame: self.view.frame];
v.backgroundColor = [UIColor whiteColor];
myView = v;
To no avail.
What am I doing wrong?
UPDATE: This is the code I use to draw in the view, in case there's something going on there!
- (void)drawRect:(CGRect)rect {
CGFloat height = self.bounds.size.height;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, rect);
CGContextSetFillColorWithColor(context, [UIColor grayColor].CGColor);
CGFloat barWidth = 30;
int count = 0;
for (NSNumber *num in samples) {
CGFloat x = count * (barWidth + 10);
CGRect barRect = CGRectMake(x, height - ([num floatValue] * height), barWidth, [num floatValue] * height);
CGContextAddRect(context, barRect);
count++;
}
CGContextFillPath(context);
}
It just creates a set of bars in the screen, of different heights.
CGContextClearRect From the docs:
If the provided context is a window or bitmap context, Quartz
effectively clears the rectangle. For other context types, Quartz
fills the rectangle in a device-dependent manner. However, you should
not use this function in contexts other than window or bitmap
contexts.
It might be that this clearing clears your entire view with no regard to the background color you set
I can t add comments due my low lvl, but the question springs to mind, have you added to your UIView to viewcontroller?
like
[self.view addSubview:v];
EDIT:
I'm sorry I had understood that the second option was added to the view that pragmatically.
Are you adding the view in the header file? If so you might need to be sure the frame's coordinates are visible and that the view is on top, also make the new view slightly smaller to see if it is actually being created:
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];
[self.view addSubview: myView];
[self.view bringSubviewToFront:myView];
You can also change the main view background color to see if the new view is actually being created. For example:
[self.view setBackgroundColor:[UIColor grayColor]];
If the color is changing for your main view then the problem is that your new view is not being or brought to the front. Let us know how it goes!
At the point where do
[myView setBackgroundColor: [UIColor whiteColor]];
check to see if myView is not nil in the debugger
I'm adding a shadow to my view layer like so:
self.view.layer.shadowOffset = CGSizeZero;
self.view.layer.shadowOpacity = 0.10f;
self.view.layer.shadowRadius = 5.0f;
self.view.layer.shadowColor = [UIColor blackColor].CGColor;
self.view.layer.shadowPath = [UIBezierPath bezierPathWithRect:
CGRectMake(self.view.bounds.origin.x, self.view.bounds.origin.y, self.view.bounds.size.width - 5.0, self.view.bounds.size.height)].CGPath;
self.view.clipsToBounds = NO;
What I want to do is somehow clip the shadow so that it does not extend beyond the width, but does extend beyond the height. Basically, I just want a 90 degree shadow rather than a shadow all around my bounds. I tried subtracting the shadowRadius amount from the bezierRect width, but this messes up the shadow flow on the bottom a little bit.
Any ideas how this can be accomplished?
You can add a new "container" view and add your view (the content view) as a subview. The container view should be higher than your view but the same width. If you set your container view to clip to its bounds it will clip the shadows on the side but allow shadows on the bottom and top.
_________
| _______ | <-- container
|| ||
|| || <-- your view (inside container)
||_______||
|`````````| <-- shadow of your view (inside container)
|_________|
In code this would look something like
// contentView is already created and configured...
UIView *containerView = [[UIView alloc] initWithFrame:
CGRectInset([contentView frame],
0, // keep the same width
-radius)]; // increase the height
[[self view] addSubview:containerView];
[contentView setCenter:CGPointMake(CGRectGetMidX([contentView bounds]),
CGRectGetMidY([contentView bounds]));
[containerView addSubview:contentView];
[containerView setClipsToBounds:YES];
I am trying to add a non-standard color to the cell when its highlighted. FOr this i create a view with the background color that i want and set it as the selectedBackgroundView for the cell.
All is fine.
UIView *selectionView = [[UIView alloc] init];
[selectionView setBackgroundColor:[UIColor colorWithRed:(121/255.0) green:(201/255.0) blue:(209/255.0) alpha:1.0]];
[cell setSelectedBackgroundView:selectionView];
My question, can i change the frame of the selectedBackgroundView so that it highlights only a part of the cell (to be precise, i want the selectionBackroundView to have an X-offset of 20 pixels).
is there any easy way of doing this ?
Updated code :
UIView *selectionView = [[UIView alloc] init];
[selectionView setBackgroundColor:[UIColor clearColor]];
UIView *selectionSubView = [[UIView alloc] initWithFrame:(CGRectMake(20.0f, 0.0f, 300.0f, 72.0f))];
[selectionSubView setBackgroundColor:[UIColor colorWithRed:(121/255.0) green:(201/255.0) blue:(209/255.0) alpha:1.0]];
UIView *clearView = [[UIView alloc] initWithFrame:(CGRectMake(0.0f, 0.0f, 20.0f, 72.0f))];
[clearView setBackgroundColor: [UIColor clearColor]];
[selectionView addSubview: selectionSubView];
[selectionView addSubview: clearView];
[cell setSelectedBackgroundView: selectionView];
THis doesn seem to work either. I have added this code in the 'cellForRowAtIndexPath'
Thanks in advance
You could put a smaller UIView as subview of your selectionView and change tha background color of that view.
You can do like this.
You create the separate file for UIView as below.
TestView.m
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code.
[self setBackgroundColor:[UIColor clearColor]];
}
return self;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
/* Draw a circle */
// Get the contextRef
CGContextRef contextRef = UIGraphicsGetCurrentContext();
// Set the border width
CGContextSetLineWidth(contextRef, 1.0);
// Set the circle fill color to GREEN
CGContextSetRGBFillColor(contextRef, 100.0, 255.0, 0.0, 1.0);
// Set the cicle border color to BLUE
CGContextSetRGBStrokeColor(contextRef, 0.0, 0.0, 255.0, 1.0);
// Fill the circle with the fill color
CGContextFillRect(contextRef, CGRectMake(20, 0, rect.size.width, rect.size.height));
// Draw the circle border
//CGContextStrokeRectWithWidth(contextRef, rect, 10);//(contextRef, rect);
}
And this Custom View you can use as a background View for cell selection like this.
TestView *bgView = [[TestView alloc] initWithFrame:cell.frame]; // Creating a view for the background...this seems to be required.
cell.selectedBackgroundView = bgView;
May be this help you.
Thanks,
Minesh Purohit.
Does the cell have fixed size and highlight area ?
If yes, create an image and use image view as the selectedBackgroundView
Try to set frame size for selectionView where x = 20. I am not sure about this but I guess it should work for your given scenario.
In one of my view I am adding shadow to a view. Thing is that the shadow shows white spaces on left & right edges. I want to remove these spaces.
Here is my code:
UIView *myView = [[ISTView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 35)];
myView.backgroundColor = [UIColor greyColor];
[myView.layer setShadowOffset:CGSizeMake(0.0, 5.0)];
[myView.layer setShadowOpacity:0.8];
[myView.layer setShadowRadius:2.0];
[myView.layer setShadowColor:[UIColor blackColor].CGColor];
[self.view addSubview:myView];
[myView release];
Here is my view's o/p:
If you want homogenous shadow without side effects you can draw it in graphics editor, save to png and place UIImageView with stretchable image on your view. And don't forget to set clipToBounds to NO.
UIView *myView = [[ISTView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 35)];
myView.backgroundColor = [UIColor greyColor];
myView.clipToBounds = NO;
UIImageView *shadowView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 35, 320, 10)];
shadowView.image = [UIImage imageWithName:#"my-shadow.png"];
[myView addSubview:shadowView];
[shadowView release];
[self.view addSubview:myView];
[myView release];
It would be cheaper for system to draw cached existing image above view hierarcy than calculate layer's shadow.
Use shadowPath to make the shadow larger then the view
view.layer.shadowPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, view.frame.size.width+30, view.frame.size.height)].CGPath;
One solution I could think of and is working also is to adjust the view's frame by 2 pixels in X position and width:
UIView *myView = [[ISTView alloc] initWithFrame:CGRectMake(-2.0, 0.0, 324.0, 35)];
But this is not a cleaner approach of doing this. If anyone has better solution, please guide.
Try this, remove the code:
[myView.layer setShadowRadius:2.0];