2011-06-27 65 views
1

我一直在爲此工作數天,而且我幾乎有東西在工作。我遇到的問題是,當我更新UIView內容(通過加倍文本字符串)時,超級視圖(UIScrollView)顯示更新後的內容大小。iOS UIScrollView/UIView顯示雙倍大小的更新內容

基本上,我有一個在IB中創建的UIViewController,它附有一個UIScrollView。 UIScrollView以編程方式創建它是子UIView。 UIView應該顯示一個小的「加載...」文本(通過核心文本),然後更改爲從URL加載的真實內容。

在我的測試中,我用一段比UIScrollView大兩行的段落替換了「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), &paragraphAlignment }, 
    }; 

    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); 
} 
+1

請顯示一些相關的代碼。如果沒有它,排除故障是非常困難的。 – RyanR

回答

1

好吧,看來這個問題有事情做從的drawRect函數內部改變視圖的大小。

當我將framesetter初始化工作拖入自己的函數中時,然後讓該函數調用了setNeedDisplay,這似乎處理了我遇到的問題。

-(void)updateText:(NSString*)textStr 
{ 
    if (textStr == longText) { return; } 

    longText = textStr; 

    CTTextAlignment paragraphAlignment = kCTLeftTextAlignment; 
    CTParagraphStyleSetting setting[1] = 
    { 
     { kCTParagraphStyleSpecifierAlignment, sizeof(paragraphAlignment), &paragraphAlignment }, 
    }; 

    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); 
} 
相關問題