43

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?

Sangram Shivankar
  • 3,535
  • 3
  • 26
  • 38
Ser Pounce
  • 14,196
  • 18
  • 84
  • 169
  • 2
    The apple doc said `The border is drawn inset from the receiver’s bounds by the value specified in this property. It is composited above the receiver’s contents and sublayers` so the border is on the top of your all layer (include your sublayer) – Guo Luchuan Mar 19 '13 at 03:23
  • Good hint @GuoLuchuan! Maybe use backGround image over overlay another UIView – LE SANG Mar 19 '13 at 03:28
  • @aăâ yes your are right , make a background view fake the border can handle it. maybe somebody else has a perfect way to handle it . And we also thought whether there is a perfect way – Guo Luchuan Mar 19 '13 at 03:51
  • Possible duplicate of [CALayer Border is appearing above subview (Z-order related, I think)](https://stackoverflow.com/questions/9901603/calayer-border-is-appearing-above-subview-z-order-related-i-think) – Jon Schneider Oct 17 '20 at 04:03

4 Answers4

56

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:

enter image description here

Danny
  • 3,975
  • 4
  • 22
  • 35
Guo Luchuan
  • 4,729
  • 25
  • 33
  • I think also could make a view that holds the border view, and the view that's suppose to go on top of it as subviews, then make the sure the border view is attached first. – Ser Pounce Mar 19 '13 at 03:55
  • @StackOverFlowRider yes you can make a `CustomView` , and its .`view` is the `border` , and `CustomView` has a `UIView` property can named `yourView`. the `yourView` is your real useful view , and `yourView` is a `subview` of the `CustomView`.`view` – Guo Luchuan Mar 19 '13 at 04:03
  • Make sure to set the #exclusiveTouch# and #userInteractionEnabled# properties of the subview to NO to pass the touch events to the button itself (http://interactivelogic.net/wp/2011/07/iosdev-tip-unblock-events-caused-when-adding-subviews-to-your-uibuttons/) – Rambatino Dec 20 '14 at 20:10
  • This way you won't be able to set a clear background – Scott Zhu Oct 09 '20 at 05:27
1

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.

northernman
  • 1,446
  • 16
  • 19
0

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.

D.C.
  • 15,340
  • 19
  • 71
  • 102
0

Insert layer at specific position that suits you:

self.layer.insertSublayer(sublayer, at: 0)
hasan
  • 23,815
  • 10
  • 63
  • 101