调整 UIView 的大小并在 drawRect 中动态调整绘图的大小
Posted
技术标签:
【中文标题】调整 UIView 的大小并在 drawRect 中动态调整绘图的大小【英文标题】:Resizing a UIView and dynamically resizing the drawing in drawRect 【发布时间】:2015-10-18 11:10:14 【问题描述】:我有一个 UIView,我想通过 UISlider 调整其大小。我的 UISlider 范围设置为 1.0-2.0。目前我正在使用 CGAffineTransform 调整视图的大小。
截图:
我在自定义 UIView 中完成:
- (void)drawRect:(CGRect)rect
NSLog(@"Draw rect called");
//// Square Drawing
UIBezierPath* squarePath = [UIBezierPath bezierPathWithRect: CGRectMake(8, 8, 50, 50)];
[UIColor.whiteColor setFill];
[squarePath fill];
//// Right top Drawing
UIBezierPath* rightTopPath = [UIBezierPath bezierPathWithRect: CGRectMake(57, 13, 9, 10)];
[UIColor.whiteColor setStroke];
rightTopPath.lineWidth = 1;
[rightTopPath stroke];
//// Top left Drawing
UIBezierPath* topLeftPath = [UIBezierPath bezierPathWithRect: CGRectMake(13, 0, 17.5, 9)];
[UIColor.whiteColor setStroke];
topLeftPath.lineWidth = 1;
[topLeftPath stroke];
//// Top right Drawing
UIBezierPath* topRightPath = [UIBezierPath bezierPathWithRect: CGRectMake(35, 0, 17.5, 9)];
[UIColor.whiteColor setStroke];
topRightPath.lineWidth = 1;
[topRightPath stroke];
//// Right middle Drawing
UIBezierPath* rightMiddlePath = [UIBezierPath bezierPathWithRect: CGRectMake(57, 28, 9, 10)];
[UIColor.whiteColor setStroke];
rightMiddlePath.lineWidth = 1;
[rightMiddlePath stroke];
//// Right bottom Drawing
UIBezierPath* rightBottomPath = [UIBezierPath bezierPathWithRect: CGRectMake(57, 43, 9, 10)];
[UIColor.whiteColor setStroke];
rightBottomPath.lineWidth = 1;
[rightBottomPath stroke];
滑块代码:
- (IBAction)changeValue:(id)sender
CGAffineTransform transform = CGAffineTransformScale(CGAffineTransformIdentity, self.slider.value, self.slider.value);
self.square.transform = transform;
这可以正常工作,但是当我调整大小时,绘图会出现质量损失,因为我实际上并没有动态更改绘图的大小。我真正想做的是动态改变绘图的大小。我将如何实现这一目标?我是否需要先调整框架大小,然后调用[self.square setNeedsDisplay]
传递乘数?
编辑:
所以我厌倦了这种方法,现在当我移动滑块时:
- (IBAction)changeValue:(id)sender
CGRect newFrame = CGRectMake(20, 20, 72*self.slider2.value, 72*self.slider2.value);
self.square.frame = newFrame;
[self.square resizeAt:self.slider2.value];
所以我现在只是更改帧大小,然后将滑块值传递到视图并调用:
-(void)resizeAt: (float)multiply
self.size=multiply;
self.transform = CGAffineTransformScale(CGAffineTransformIdentity, self.size, self.size);
[self setNeedsDisplay];
drawRect 中发生的事情的一个例子:
UIBezierPath* squarePath = [UIBezierPath bezierPathWithRect: CGRectMake(11, 11, 50, 50)];
[squarePath applyTransform:self.transform];
[UIColor.whiteColor setFill];
[squarePath fill];
但是图像看起来不清晰或“重绘”
【问题讨论】:
【参考方案1】:考虑使用 0.0 到 1.0 范围内的点创建贝塞尔路径,然后将变换直接应用于每个贝塞尔路径。转换的比例显然会改变,因为您将路径缩放到完整视图大小,而不是相对大小。
因为您缩放路径而不是已经渲染的视图,所以路径渲染仍然干净准确。
【讨论】:
如何缩放路径?在我使用 CGAffineTransform 之前。我可以将此对象应用于 UIBezierPaths 吗? 是的,您将对所有路径应用类似的变换,然后绘制它们。不会对视图应用任何变换。 为什么要将范围从 0.0 更改为 1.0? 因此您可以可靠地缩放到任何视图大小(很容易)——技术上不需要,但将来更易于维护 所以我正在使用来自 UISlider 的数字创建一个 CGAffineTransform,然后我调用 setNeedsDisplay,这会强制重绘并将转换应用于每个单独的 UIBezierPath。它正在调整大小,但看起来仍然模糊,就像它没有被重绘一样。 (编辑我的问题)。我做错了吗?以上是关于调整 UIView 的大小并在 drawRect 中动态调整绘图的大小的主要内容,如果未能解决你的问题,请参考以下文章
调整 UIView 的大小,以便我绘制的任何内容都可见 - Objective C