0

CoreTextを使用して複数の列にテキストを描画しています(iPadの向きによって異なります)。

テストするために、100〜999の数字で構成されるNSMutableStringを作成しました。このテキストは5列にまたがっており、そのうちの1つまたは2つが画面に表示されます(向きによって異なります)。

メインのViewControllerに、このテキストを保持するためのカスタムUIScrollViewを追加しましたが、スクロール可能にしたいです。

次の設定を行うまで、scrollviewがスクロールしないことに気づきました。

[myScrollView setContentMode:UIViewContentModeRedraw];

iPadが回転したときに(列数を調整するために)scrollViewがdrawRectを呼び出すようにしたいです!

ただし、これに関する私の問題は、スクロール中にdrawRectを何度も何度も呼び出すように見えることです(したがって、より多くのメモリを割り当て、遅延も発生します)。

UIScrollViewをメインのviewControllerに次のように追加します。

myScrollView = [[CoreTextTestUIView alloc] init];
myScrollView.parentView = self;
if(FACING == @"PU" || FACING == @"PD")
{
    myScrollView.frame = CGRectMake(0,50,768,974);
}
else
{
    myScrollView.frame = CGRectMake(0,50,1024,718);
}
[myScrollView setContentMode:UIViewContentModeRedraw];
[container addSubview:myScrollView];

繰り返しになりますが、iPadが回転したときにdrawRectが呼び出されるようにしたいので、列の数を変更できます...しかし、UIScrollViewをスクロールしようとしたときにdrawRectを呼び出さないようにします。

誰かが私を助けてくれますか?

..。

以下は私のUIScrollViewの.mです。

#import "CoreTextTestUIView.h"
#import <CoreText/CoreText.h>

@implementation CoreTextTestUIView

@synthesize parentView;


NSMutableString *testText;



-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if(self)
    {
        // Initialization code

        //set BG color
        self.backgroundColor = [[UIColor alloc] initWithRed:134 green:166 blue:228 alpha:1.0];

        //UIScrollView Stuff
        //self.delegate = self;
        self.scrollEnabled = YES;
        self.pagingEnabled = YES;
        self.userInteractionEnabled = YES;
        [self becomeFirstResponder];
        self.showsVerticalScrollIndicator = NO;
        self.showsHorizontalScrollIndicator = NO;
        self.bounces = NO;
        self.alwaysBounceHorizontal = YES;
        self.alwaysBounceVertical = NO;

        //generate long text
        testText = [[NSMutableString alloc] initWithString:@""];
        for(int i = 100; i < 1000; i++)
        {
            [testText appendString:[NSString stringWithFormat:@"%i ",i]];
        }

        self.alpha = 0.0;
        [self fadeIn];
    }
    return self;
}



-(void)fadeIn
{
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:1.0];  
    [UIView setAnimationDelegate:self]; 
    //[UIView setAnimationDidStopSelector:@selector(animationFinished:finished:context:)];  
    self.alpha = 1.0;
    [UIView commitAnimations];
}



// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
-(void)drawRect:(CGRect)rect
{

    NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@",testText]];

    //set font
    CTFontRef helvetica = CTFontCreateWithName(CFSTR("Helvetica"), 40.0, NULL);
    [string addAttribute:(id)kCTFontAttributeName
                   value:(id)helvetica
                   range:NSMakeRange(0, [string length])];


    //layout master
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)string);

    //flip the coordinate system
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    CGContextTranslateCTM(context, 0, self.bounds.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    int textPos = 0;
    int columnIndex = 0;

    //how many columns? (orientation dependent)
    float howManyColumns;
    if(parentView.FACING == @"PU" || parentView.FACING == @"PD")
    {
        howManyColumns = 1.0;
    }
    else
    {
        howManyColumns = 2.0;
    }

    //create columns in loop
    while(textPos < [string length])
    {
        NSLog(@"column started");

        //column form
        CGMutablePathRef columnPath = CGPathCreateMutable();
        CGPathAddRect(columnPath, NULL, 
                      CGRectMake((self.bounds.size.width/howManyColumns*columnIndex), 0, 
                                 (self.bounds.size.width/howManyColumns),
                                 self.bounds.size.height));

        //column frame
        CTFrameRef columnFrame = CTFramesetterCreateFrame(framesetter, 
                                                             CFRangeMake(textPos, 0),
                                                             columnPath,
                                                             NULL);

        //use the column path
        CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(textPos, 0), columnPath, NULL);
        CFRange frameRange = CTFrameGetVisibleStringRange(frame);

        //draw
        CTFrameDraw(columnFrame, context);

        //cleanup
        CFRelease(columnFrame);
        CGPathRelease(columnPath);

        textPos += frameRange.length;
        columnIndex++;
    }

    //set scrollView content size
    int totalPages = (columnIndex+1)/howManyColumns;
    self.contentSize = CGSizeMake(totalPages*self.bounds.size.width, self.frame.size.height);

    //release
    CFRelease(framesetter);
    [string release];
}



-(void)dealloc
{
    [super dealloc];

    [parentView release];
    [testText release];
}


@end
4

2 に答える 2

2

これを見るとcontentSize、scrollViewのをどこに設定しているのかわかりません。scrollViewのを設定しない場合contentSize、スクロールは有効にならず、scrollViewの現在の領域に収まるものだけが表示されます。また、構成内でテキストが静的である場合は、発生している再描画の一部を最適化して、scrollViewのサブビューに追加することを検討してください。

于 2012-05-22T16:22:28.457 に答える
1

これがdrawRectの仕組みです。ビューが移動したり、変更されたり、何かが重なっている場合は、毎回呼び出されます。メモリを正しく管理している場合、これは問題にはなりません。

于 2012-05-22T16:01:26.490 に答える