2012-05-22 68 views
0

我正在使用CoreText绘制多列中的文本(取决于iPad的方向)。自定义uiscrollview不滚动(使用coretext)

为了测试,我创建了一个由数字100 - 999组成的NSMutableString。该文本跨越5列,其中1或2个在屏幕上(取决于方向)。

我的主要ViewController我已经添加了一个自定义的UIScrollView来容纳这个文本,我希望它是可滚动的。

我注意到,滚动视图不会滚动,直到我设置:

[myScrollView setContentMode:UIViewContentModeRedraw]。

我希望scrollView在iPad旋转时调用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 

回答

2

看着这个,我看不到你在哪里设置你的scrollView的contentSize。如果您未设置scrollView的contentSize,则不会启用滚动,您只会看到适合scrollView当前区域的内容。另外,如果您的文本在配置中是静态的,请考虑优化某些正在发生的重绘,并将其添加到scrollView的子视图中。

+0

我已经在drawRect方法中包含了一个setContentSize调用......但解决方案是将所有文本绘制到UIView中,然后包含UIScrollView内部的整个视图(如@ heckman建议)!!! 谢谢你的包! –

+0

@Chris Allinson如果你的setContentSize被嵌入到这个drawRect方法中,很可能这就是为什么你在执行后能够滚动[myScrollView setContentMode:UIViewContentModeRedraw]; heckman

+0

感谢您的帮助:D –

1

也就是说drawRect中是如何工作的。它被称为每一次视图移动或改变或重叠它的东西。如果你正在正确地管理内存,这应该不成问题。

+0

ok,我会看看确保一切都已发布......谢谢 –