1 问题
使用纯代码布局并且AutoLayout关闭的状态下,在drawRect方法中绘制的图形,在视图大小发生变化时图形会失真,本案例学习绘制图形的布局如图1,图2所示:
2 方案
首先在创建好的项目中将自动布局功能关闭,再创建一个View类,继承至UIView。
其次在Stroyboard的场景中拖放一个View控件,和屏幕一样大小,然后将View的类型修改为View。
然后在View类中重写drawRect方法,在屏幕左上方绘制一个三角形。
最后将View的contentMode属性设置成Redraw,即可实现绘制的布局,屏幕切换或者变化绘制的图形也不会失真。
3 步骤
实现此案例需要按照如下步骤进行。
步骤一:创建View类,绘制图像
首先在创建好的项目中将自动布局功能关闭,创建一个View类,继承至UIView,用于绘制图形。在Storyboard中拖放一个View控件,和屏幕同等大小,并将View的类型修改为View,如图3所示:
然后将View控件关联成ViewController的私有属性myView,代码如下所示:
@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UIView *myView;
@end
最后在View类中重写drawRect方法,在屏幕左上方绘制一个三角形,代码如下所示:
- (void)drawRect:(CGRect)rect
{
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(20, 20)];
[path addLineToPoint:CGPointMake(20, 120)];
[path addLineToPoint:CGPointMake(120, 20)];
[path closePath];
path.lineWidth = 4;
[[UIColor redColor] setStroke];
[path stroke];
}
步骤二:进行绘制布局
完成绘制代码,运行程序可见屏幕左上方有一个三角形,但是当切换成横屏时发现三角形失真,如图4所示:
解决的办法是,当视图大小发生变化时,进行重新绘制图形,即在布局方法viewDidLayoutSubviews里面调用setNeedDisplay方法即可,代码如下所示:
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[self.myView setNeedsDisplay];
}
但是通常直接将myView的contentMode属性设置为Redraw即可实现绘制布局,相当于调用了上面的代码,将myView的contentMode属性设置为Redraw有两个方法,第一种可以直接通过代码设置,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
self.myView.contentMode = UIViewContentModeRedraw;
}
第二种方法可以直接在Stroyboard中设置,右边栏的检查器四中将Mode选项设置为Redraw即可,如图4所示:
将contentMode设置为Redraw之后就不需要再写布局代码,此时切换屏幕绘制图形就不会失真了。
4 完整代码
本案例中,ViewController.m文件中的完整代码如下所示:
#import "ViewController.h"
#import "View.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *myView;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.myView.contentMode = UIViewContentModeRedraw;
}
//- (void)viewDidLayoutSubviews
//{
// [super viewDidLayoutSubviews];
// [self.myView setNeedsDisplay];
//}
@end
本案例中,View.m文件中的完整代码如下所示:
#import "View.h"
@implementation View
- (void)drawRect:(CGRect)rect
{
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(20, 20)];
[path addLineToPoint:CGPointMake(20, 120)];
[path addLineToPoint:CGPointMake(120, 20)];
[path closePath];
path.lineWidth = 4;
[[UIColor redColor] setStroke];
[path stroke];
}
@end