我已经在这方面工作了好几天,而且我几乎都有工作。我遇到的问题是,当我更新UIView内容时(通过加倍文本字符串),superview(UIScrollView)会显示双倍大小的更新内容。
基本上,我在IB中创建了一个附加了UIScrollView的UIViewController。 UIScrollView以编程方式创建它的子UIView。 UIView应该显示一个小的“Loading ...”文本(通过Core Text),然后更改为从URL加载的真实内容。
在我的测试中,我用一个比UIScrollView大2行的段落替换了“Loading ...”文本。它显示正确并滚动完美。
当URL完成加载时,我用完全相同的段落替换段落两次(字符串长度的两倍)。然后我在孩子UIView上做一个setNeedDisplay。 UIView(在其drawRect中使用相同的代码)获取新边界,绘制文本,并更新父级(UIScrollView)contentSize。
当模拟器上的屏幕更新时,我所拥有的是显示的内容,但是高度加倍,导致第二段文本被截断。
在孩子的drawRect的最后,我有NSLog'd父母的框架,边界,contentSize等,以及孩子的框架&界限。对我来说一切看起来都是正确的...孩子的框架和边界的高度是原来的两倍,父母的contentSize是框架的两倍,边界保持不变。
所以,那里必须有另一层影响绘图的地方,但我根本找不到它。欢迎任何建议。
这是我的内容视图的drawRect():
- (void)drawRect:(CGRect)rect
{
CTTextAlignment paragraphAlignment = kCTLeftTextAlignment;
CTParagraphStyleSetting setting[1] =
{
{ kCTParagraphStyleSpecifierAlignment, sizeof(paragraphAlignment), ¶graphAlignment },
};
CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(setting, 1);
NSMutableAttributedString* string = [[[NSMutableAttributedString alloc] initWithString:longText attributes:
[NSDictionary dictionaryWithObjectsAndKeys:(id)helvetica, (NSString*)kCTFontAttributeName,
paragraphStyle, (NSString*)kCTParagraphStyleAttributeName, nil]] autorelease];
CFRelease(paragraphStyle);
[string addAttribute:(id)kCTFontAttributeName
value:(id)helvetica
range:NSMakeRange(0, [string length])];
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)string);
CGSize size = CTFramesetterSuggestFrameSizeWithConstraints(framesetter,
CFRangeMake(0, 0),
NULL,
CGSizeMake(rect.size.width - 3, CGFLOAT_MAX),
NULL);
[self setFrame:CGRectMake(0, 0, (int)(size.width + 0.5), (int)(size.height + 0.5))];
MyContentScroller* scroller = (MyContentScroller*)self.superview;
[scroller setContentSize:self.bounds.size];
CGMutablePathRef columnPath = CGPathCreateMutable();
CGRect bounds = CGRectMake(2, 2, self.bounds.size.width - 4, self.bounds.size.height);
CGPathAddRect(columnPath, NULL, bounds);
CTFrameRef frame = CTFramesetterCreateFrame(framesetter,
CFRangeMake(0, 0),
columnPath, NULL);
CGPathRelease(columnPath);
CFRelease(framesetter);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CTFrameDraw(frame, context);
CFRelease(frame);
CGContextRestoreGState(context);
}
答案 0 :(得分:1)
好的,似乎问题与从drawRect函数内部更改视图的大小有关。
当我将framesetter初始化拉出到它自己的函数中时,然后让该函数调用setNeedDisplay,这似乎解决了我遇到的问题。
-(void)updateText:(NSString*)textStr
{
if (textStr == longText) { return; }
longText = textStr;
CTTextAlignment paragraphAlignment = kCTLeftTextAlignment;
CTParagraphStyleSetting setting[1] =
{
{ kCTParagraphStyleSpecifierAlignment, sizeof(paragraphAlignment), ¶graphAlignment },
};
CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(setting, 1);
NSMutableAttributedString* string = [[[NSMutableAttributedString alloc] initWithString:longText attributes:
[NSDictionary dictionaryWithObjectsAndKeys:(id)helvetica, (NSString*)kCTFontAttributeName,
paragraphStyle, (NSString*)kCTParagraphStyleAttributeName, nil]] autorelease];
CFRelease(paragraphStyle);
[string addAttribute:(id)kCTFontAttributeName
value:(id)helvetica
range:NSMakeRange(0, [string length])];
if (framesetter) { CFRelease(framesetter); }
framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)string);
CGSize size = CTFramesetterSuggestFrameSizeWithConstraints(framesetter,
CFRangeMake(0, 0),
NULL,
CGSizeMake(self.bounds.size.width - 4, CGFLOAT_MAX),
NULL);
[self setFrame:CGRectMake(0, 0, (int)(size.width + 0.5), (int)(size.height + 0.5))];
MyContentScroller* scroller = (MyContentScroller*)self.superview;
[scroller setContentSize:self.bounds.size];
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
if (!framesetter) { return; }
CGMutablePathRef columnPath = CGPathCreateMutable();
CGRect bounds = CGRectMake(2, 2, self.bounds.size.width - 4, self.bounds.size.height);
CGPathAddRect(columnPath, NULL, bounds);
CTFrameRef frame = CTFramesetterCreateFrame(framesetter,
CFRangeMake(0, 0),
columnPath, NULL);
CGPathRelease(columnPath);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CTFrameDraw(frame, context);
// CFRelease(frame); // This line causes a crash!
CGContextRestoreGState(context);
}