在 iOS 上,drawRect 方法无法绘制超出视图边界的内容?

23

我曾经认为,从某个时间点开始对于 OS X 平台来说,对于 iOS 平台则一直如此,视图内容可以出现在视图范围之外?(对于 UIView 来说)但是,如果我创建一个全新的 Single View 应用程序,并且创建了一个子类化 UIView 的 MyView 类,并实现它的 drawRect: 方法。

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:
                                           CGRectMake(-20, -20, 600, 600)];
    [[UIColor greenColor] set];
    [path fill];

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [[UIColor blueColor] CGColor]);
    CGContextFillRect(context, CGRectMake(-20, -20, 600, 600));
}

我同时使用UI和CG绘制一个矩形,以防止其中一个无法使用。并且这个视图是在 viewDidAppear 中添加的:

- (void)viewDidAppear:(BOOL)animated {
    MyView *myView = [[MyView alloc] initWithFrame:CGRectMake(20, 20, 260, 260)];
    [self.view addSubview:myView];
}

但无论如何,有色框都不会超出(20, 20, 260, 260)的区域。 是否只有CALayer可以自由添加并出现在视图的边界之外? 这是因为图形上下文一开始就被限制在这个(20, 20, 260, 260)吗? 如果是这样,是否有一种方法让drawRect内容在视图的边界之外的所有四个方向上都显示出来?


我可以问一下,为什么你想在可见矩形之外绘制,因为它不会被显示出来?如果你计划稍后让它可见,你应该使用 CALayer,就像你正确提到的那样。 - Lefteris
一个原因是,我正在考虑实现一个具有圆角或甚至“云状边缘”的PopoutScrollView。我发现我可以子类化UIView并将UIScrollView作为属性,以便滚动视图成为视图的子视图,并且我实际上必须重写addSubview以添加到self.scrollView。这是因为我不能简单地在scrollView上绘制边框,否则它们会滚动消失。这可能会很复杂,我想,为什么不直接子类化UIScrollView,在drawRect中绘制超出边界的部分呢?然后我就不必重写那么多方法了。 - nonopolarity
虽然我没有尝试过这个,但我认为使用scrollview.layer.cornerRadius属性添加圆角应该很容易实现。如果您计划修改scrollView,最好是通过子类化scrollView和它的drawRect方法来实现,而不是UIView。 - Lefteris
那么您的意思是不使用drawRect来绘制带有圆角的图层?如果我子类化UIScrollView并使用drawRect绘制圆角,那么边框将像任何其他内容一样"滚动消失",这不是事实吗?或者除非[aScrollView addSubview:v]实际上是添加到另一个UIView对象中,该对象是UIScrollView的属性,因此UIScrollView的drawRect实际上没有绘制到该子视图中,因此没有问题? - nonopolarity
我遇到了类似的问题,尝试通过重写drawRect并绘制路径(为了通过绘制彩色边框来突出显示UIImage)在UIView周围绘制路径。但是我的路径被剪切到图像的内部。我们肯定可以修改剪切路径,而不必添加另一个更大的层图像到我想要突出显示的UIView上。我尝试过各种masksToBounds和clipsToBounds的变化,但没有积极的结果。 - cod3monk3y
显示剩余4条评论
2个回答

31
你的问题在于"drawRect"被自动剪切到你正在绘制的视图中。
不要在视图本身中进行绘制,而是将第二个(子)视图添加到第一个视图中,该视图位于第一个视图的边界之外。这将允许你进行基于第一个视图位置的绘制,但是超出第一个视图的边界。
希望这可以帮助你。

-3

在你添加了scrollView的视图上尝试这个:

self.scrollView.backgroundColor = [UIColor darkGrayColor];
self.scrollView.layer.cornerRadius = 10.0f;
self.scrollView.layer.masksToBounds = YES;

它应该显示一个带有圆角的灰色滚动视图,就像你想要的那样。

记得需要导入QuartzCore框架


如果需要超出边界怎么办? - nonopolarity
我不理解这个问题。 - Lefteris
我的意思是,上面的代码将在视图边界内绘制背景。如果我们需要在顶部上方10像素、左边距左侧10像素等位置绘制某些内容(绘制某些东西,或在这种情况下是绘制背景和圆角),该怎么办? - nonopolarity

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