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)
Related
Please help me. I am phasing a problem, show a delete button on top of the view.
Without using bezier path showing like this
When i use bezier path is showing like this
how i can show the button.
This is the code i am using
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
[view1 setBackgroundColor:[UIColor orangeColor]];
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view1.bounds byRoundingCorners:UIRectCornerTopLeft| UIRectCornerTopRight cornerRadii:CGSizeMake(10.0, 10.0)];
// Create the shape layer and set its path
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = view1.bounds;
maskLayer.path = maskPath.CGPath;
// Set the newly created shape layer as the mask for the image view's layer
view1.layer.mask = maskLayer;
[self.view addSubview:view1];
UIButton *bt1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[bt1 setTitle:#"D" forState:UIControlStateNormal];
[bt1 setFrame:CGRectMake(87, -10, 25, 25)];
[view1 addSubview:bt1];
please help me. Thanks in advance.
You could always add the button in your superview depending of the view's position.
What #Larme said is true ,when you're making a view you're masking all the subviews that view has.
In case you don't want to do that just enter in your view's drawRect and draw there transparent corners to achieve the same effect.
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.
I put a custom UILabel in my UINavigation bar like this:
UILabel *navTitle = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 44)];
navTitle.backgroundColor = [UIColor clearColor];
navTitle.text = #"TEST";
navTitle.font = [UIFont fontWithName:#"GothamNarrowBook-Regular" size:28];
navTitle.textColor = [UIColor whiteColor];
navTitle.textAlignment = UITextAlignmentCenter;
self.navigationItem.titleView = navTitle;
But when it shows up on the emulator, its aligned too high:
I have had no luck with adjusting the frame. Any ideas?
You can put label inside another view, and insert this another one as titleView. That will allow some kind of flexibility.
You can also try to adjust position of the frame:
UILabel *navTitle = [[UILabel alloc] initWithFrame:CGRectMake(0, >>>10<<<, 200, 44)];
But remember, that NavigationBar has different height in landscape mode, so you have to use autoresizingMask accordingly.
Can you set the frame of self.nagivationItem.titleView and push it down?
CGRect initialFrame = self.navigationItem.titleView;
self.navigationItem.titleView = CGRectMake(initialFrame.origin.x, initialFrame.origin.y+10, initialFrame.size.width, initialFrame.size.height);
Another thing to check, make sure your UINavigationBar is actually 44px tall, if your UILabel is the same height then I believe default behavior is to center vertically which would land it in the correct position.
I take it that increasing the height of the UILAbel doesn't work.
Or the Y position.
And I take it you tried adjusting the frame after it's created, e.g. other than in the initWithFrame.
Maybe try using an image instead? Well it's an idea ;)
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];
UITableView has custom header UIView, which contains UILabel. Since table has also section index at right side, I want to center the label in remaining space.
Problem is how to "center" label in same way, when device is rotated to landscape! I've tried both Interface Builder and code-only and something is always wrong.
Restrictions:
Label is as narrow as possible
Label must not be resized
Label must be always centered inside table width minus section index
One easy way to fix this would be making section header view detached from tableView right side. Tried to do it, failed. Here's some code from viewForHeaderInSection:
CGRect frame = CGRectMake(0, 0, tableView.bounds.size.width - 32, 50.0f);
// MAGIC 32 for SectionIndexTitles
UIView *view = [[[UIView alloc] initWithFrame:frame] autorelease];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.font = [UIFont fontWithName:#"Courier" size:20];
label.text = #"Section title long";
label.textAlignment = UITextAlignmentCenter;
label.backgroundColor = [UIColor redColor];
CGSize labelSize = [label.text sizeWithFont:label.font
constrainedToSize:frame.size
lineBreakMode:UILineBreakModeClip];
label.frame = CGRectMake(0, 0, labelSize.width, labelSize.height);
label.center = CGPointMake(frame.size.width/2.0f, kHeaderHeight/2.0f);
label.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
Any ideas welcome! Can't even recall how many different ways I have failed :)
Hey, set up as following in the IB:
Disable all autoresizing functionalities (no flexible width, height, nor any left, bottom, top, right).
Should do the job :)
To support the magic 32 pixels, try to position your Label as you need it.
That means:
Position it in the center of your UIView and move it 16 pixels to the left, now don't change the frame programmatically, else the "wonderful" auto-positiong will be manipulated what we don't really want to :)