iOS8 问题 - UIView drawRect 未被调用

Posted

技术标签:

【中文标题】iOS8 问题 - UIView drawRect 未被调用【英文标题】:iOS8 issue - UIView drawRect is not called 【发布时间】:2014-09-25 12:10:51 【问题描述】:

我有一个很简单的UIView,就是画一个三角形。它实现了一个正在绘制图形的UIView drawRect 方法。它在 ios7 上运行良好,但是当我在 iOS8 上运行相同的代码时,它甚至没有被调用。任何想法在 iOS8 上发生了什么变化?简而言之我的代码:

@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];

更新 我的视图层次结构:UIViewController View->Custom UILabel->MyView

这是一个错误信息气泡,我的观点是一个指向某物的喙。

我使用了一个新的 UI 调试工具,但在那里看不到它。调用了 init 方法,drawRect 没有。 iOS8 中一定发生了一些变化,因为 iOS7 正在调用drawRect

更新 2 当然我使用了约束(和Masonry pod),这就是我没有指定框架的原因。

[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);
];

我也尝试在不同的地方添加[myView setNeedsDisplay],但没有帮助。

【问题讨论】:

关于如何在视图层次结构中引入视图的更多信息?您是否使用新的调试工具检查了视图层次结构,以找出您的视图在哪里? @Vinzzz 更新了问题。如果您需要更多信息,请告诉我。 好的...所以你正在使用这个 MASConstraintMaker...也许 iOS 8 的错误来自那个类? @Vinzzz 这是可能的,但我以不同的方式解决了这个问题,请注意我的帖子。非常感谢您的帮助! 【参考方案1】:

问题终于解决了。我不确定究竟是什么导致了这个问题(Masonry [约束框架] 或 iOS8 更改为UILabel),但解决方案是更改视图层次结构。我创建了另一个UIView,其中包含UILabel 和我的UIView(绘制的喙),而不是将UIView 添加到UILabel 作为子视图。现在drawRect方法在iOS7和iOS8上都被调用了。

以前的层次结构:UIViewController View->Custom UILabel->MyView

新层次结构:UIViewController View->Container UIView->Custom UILabel & MyView

总结一下,如果您的drawRect 方法在iOS8 上没有被调用,并且您将一些UIView 添加到UILabel 作为子视图,请尝试使用一些同时包含UIViewUILabel 的容器.

【讨论】:

【参考方案2】:

确保myView 的superview 属性clipToBounds = NO,并且myView rect 在屏幕上

【讨论】:

【参考方案3】:

您的方法中缺少一个重要的细节。您需要指定一个框架来确定视图的原点和大小。这可以通过UIViewinitWithRect 方法来完成,也可以在分配/初始化之后设置帧。由于您已经有一个自定义的 init 方法,我会执行以下操作:

myView = [MyView new];
myView.frame = CGRectMake(0.0,0.0,100.0,100.0);
[self addSubview:myView];

这将使用 (0.0,0.0) 的原点和 100.0 的宽度和高度绘制您的自定义视图。

此外,如果您仍然遇到问题,添加对setNeedsDisplay 的调用应该会强制调用drawRect 方法:

[myView setNeedsDisplay];

【讨论】:

感谢您的回复。我当然使用约束,所以我的代码中没有框架。抱歉,忘记写这个了。已更新问题。 您可能想尝试调用 [self.view layoutSubviews] 以确保您的约束得到正确处理和渲染。

以上是关于iOS8 问题 - UIView drawRect 未被调用的主要内容,如果未能解决你的问题,请参考以下文章

UIView 在后台调用 drawRect

如何在drawRect中获取UIView大小

使用drawrect自定义UIView动画

UIView 子类:drawRect 未调用

在 UIView 中将属性传递给 drawRect 时遇到问题

在 UIView::drawRect() 之外绘制 UIBezierPath?