iOS UIScrollView / UIView отображает обновленный контент в двойном размере - PullRequest
1 голос
/ 27 июня 2011

Я работал над этим несколько дней, и у меня ПОЧТИ все работает. У меня проблема в том, что когда я обновляю контент UIView (путем удвоения текстовой строки), суперпредставление (UIScrollView) отображает обновленный контент в двойном размере.

По сути, у меня есть UIViewController, созданный в IB, к которому прикреплен UIScrollView. UIScrollView программно создает его дочерний UIView. Предполагается, что UIView отображает небольшой текст «Загрузка ...» (через Core Text), который затем изменяется на реальный контент, загружаемый из URL.

В моем тестировании я заменил текст «Загрузка ...» абзацем, который на 2 строки больше, чем UIScrollView. Он отображается правильно и отлично прокручивается.

Когда URL-адрес завершает загрузку, я заменяю абзац на один и тот же абзац дважды (удваивая длину строки). Затем я делаю setNeedDisplay для дочернего UIView. UIView (используя тот же код в своем drawRect) получает новые границы, рисует текст и обновляет contentSize родительского элемента (UIScrollView).

Когда обновляется экран в эмуляторе, отображается содержимое, но удваивается высота, в результате чего второй абзац текста обрезается.

В конце drawRect дочернего элемента у меня есть NSLog'd frame, bounds, contentSize и т. Д. Родителя вместе с frame & bounds дочернего элемента. Для меня все выглядит правильно ... рамка и границы дочернего элемента в два раза больше высоты, чем они были, родительский 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 Ответ

1 голос
/ 28 июня 2011

Хорошо, похоже, что проблема связана с изменением размера представления внутри функции drawRect.

Когда я вытащил инициализацию фрейм-установщика в свою собственную функцию, затем вызвал этот вызов функции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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...