当子视图改变尺寸时,我该如何强制重绘 (drawRect) 子视图?

25

我有一个包含一行UIView子类的UIView。子类已经重写了drawRect: 并设置了 contentMode = UIViewContentModeRedraw

当用户缩放父容器时,子视图也会随之缩放。当形状发生变化时,我想让drawRect重复调用以更改子视图的内容。到目前为止,我尝试了很多但没有成功。请问正确的方法是什么?

谢谢,

Doug

3个回答

61
在Cocoa中,你很少(如果有的话)调用drawRect方法 - 你只需要标记该区域或视图需要更新,它就会被安排重新绘制。这允许多个无效状态的重绘被合并在一起。
对于Cocoa Touch,你需要使用[view setNeedsDisplay]setNeedsDisplayinRect:(CGRect)

1
我尝试过完全这样做。没有效果。什么都没有发生。在子类中,我这样重写了setTransform:方法:
  • (void)setTransform:(CGAffineTransform)newValue { [super setTransform:newValue]; [self setNeedsDisplay];
}
- dugla
显然,现在进行了一些代码调整,使setNeedsDisplay正确地触发。 - dugla

3
您需要调用[view setNeedsLayout],这应该会在布局更改时使子视图接收到drawRect:调用。不过我还没有测试过。

1
有人说 setNeedsDisplay,有人说 setNeedsLayout.. 这里有什么不同的含义? - Sti

0
这个解决方案有点疯狂,但是它很合乎逻辑,并且具有很好的视觉效果。我正在使用 NSLayoutManager 和一些 NSTextContainer 在两列中排版文本。因为我使用了多个文本容器(而且我不确定我想要多个 UITextView),所以我重写了 MyDrawingView: UIViewdraw(rect: CGRect) 方法。
问题在于使用 self.contentMode = .redraw 仍然会导致旋转时出现轻微的拉伸 - 这足以成为无法接受的问题。
我注意到将 contentMode = .left 或者甚至是 contentMode = .scaleAspectFit 设置为我想要的像素完美旋转的效果非常接近。 但是很明显,我没有得到所需的绘制调用。
所以 - 我重写了 layoutSubviews() 方法,将 contentMode 切换到 .scaleAspectFit,调用 super.layoutSubviews(),然后再切换回来。 :P
override func layoutSubviews() {
    self.contentMode = .scaleAspectFit

    super.layoutSubviews()
    self.contentMode = .redraw
}

这是...完美的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接