I have a very simple UIView
, that is only drawing a triangle. It implements a UIView drawRect
method that is drawing a figure. It is working fine on iOS7, but when I run the same code on iOS8 it is not even called. Any ideas what has changed on iOS8? My code in nutshell:
@interface MyView : UIView
@end
@implementation MyView
- (instancetype)init {
self = [super init];
if (self) {
self.backgroundColor = [UIColor clearColor];
}
return self;
}
- (void)drawRect:(CGRect)rect {
// draw things
}
@end
myView = [MyView new];
[self addSubview:myView];
Update
My view hierarchy: UIViewController View->Custom UILabel->MyView
It is an error message bubble, and my view is a beak pointing to something.
I have used a new UI debugging tool, but it is not visible there. Init method is called, drawRect
is not. Something must have changed in iOS8, because iOS7 is calling drawRect
.
Update 2
Of course I'm using constraints (and Masonry
pod), and this is why I did not specify the frame.
[myView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(make.superview.mas_bottom);
make.centerX.equalTo(make.superview);
make.width.equalTo(@10.0f);
make.height.equalTo(@5.0f);
}];
I have also tried adding [myView setNeedsDisplay]
in various places, but it didn't help.
Problem finally solved. I'm not sure what exactly caused the issue (Masonry
[constraints framework] or iOS8 changes to UILabel
), but the solution was to change the view hierarchy. I created another UIView
that contains both UILabel
and my UIView
(drawn beak) instead of adding the UIView
to UILabel
as subview. Now drawRect
method is called both on iOS7 and iOS8.
Previous hierarchy:
UIViewController View->Custom UILabel->MyView
New hierarchy:
UIViewController View->Container UIView->Custom UILabel & MyView
To sum up, if your drawRect
method is not called on iOS8, and you are adding some UIView
to UILabel
as subview, try to use some container which will contain both UIView
and UILabel
.
make sure that myView
's superview property clipToBounds = NO
, and that myView
rect is on screen
There is an important detail missing in your approach. You need to specify a frame that determines the origin and size of your view. This can be done with the initWithRect
method of UIView
, or you can set the frame after allocation/initialization. Since you have a custom init
method already I would do the following:
myView = [MyView new];
myView.frame = CGRectMake(0.0,0.0,100.0,100.0);
[self addSubview:myView];
This will draw your custom view with an origin point of (0.0,0.0) and a width and height of 100.0.
Furthermore, adding a call to setNeedsDisplay
should force the drawRect
method to be called if you are still having trouble:
[myView setNeedsDisplay];