I am currently writing up an app that reads in a file and puts the headings into a list. When each heading is clicked, it switches to a controller with a CATextLayer containing the text associated with that heading (generally a few paragraphs). Initially, I used a UITextView, however I found that I needed more formatting options (namely justified alignment) and switched to a CATextLayer.
I have read in other questions here that CATextLayer is innately scrollable, however I cannot find how to trigger that behaviour. When I've attempted to set contentsRect
, my text disappears entirely from the view.
This is my set-up code, which works aside from the scrolling:
CATextLayer *textLayer = [[CATextLayer alloc] init];
textLayer.alignmentMode = kCAAlignmentJustified;
textLayer.string = [_data objectForKey:@"Text"];
textLayer.wrapped = YES;
textLayer.frame = CGRectMake(27, 75, 267, 320);
textLayer.font = [UIFont fontWithName:@"Helvetica" size:17.0f];
textLayer.foregroundColor = [UIColor blackColor].CGColor;
textLayer.backgroundColor = [UIColor whiteColor].CGColor;
[textLayer setCornerRadius:8.0f];
[textLayer setMasksToBounds:YES];
[textLayer setBorderWidth:1.0f];
[textLayer setBorderColor:[UIColor grayColor].CGColor];
[self.view.layer addSublayer:textLayer];
[textLayer release];
I have looked through the documentation for CATextLayer and numerous other SO questions, and haven't found what I was looking for.
EDIT: It is possible for this class to be scrolled, however it needs to be done so programmatically using the contentsRect
's offsets. It can be sub-layered to a CAScrollLayer
for some helper functions (scrollToPoint
and scrollToRect
) and slightly tidier set of calculations. CAScrollLayer
also requires the programmer to handle touch events, so for the sake of simplicity, I will not be pursuing this route.
For those who would like to go this route with a CAScrollLayer
, my set-up code changed to the following:
CAScrollLayer *scrollLayer = [[CAScrollLayer alloc] init];
scrollLayer.frame = CGRectMake(27, 75, 267, 320);
scrollLayer.backgroundColor = [UIColor whiteColor].CGColor;
scrollLayer.scrollMode = kCAScrollVertically;
[scrollLayer setCornerRadius:8.0f];
[scrollLayer setMasksToBounds:YES];
[scrollLayer setBorderWidth:1.0f];
[scrollLayer setBorderColor:[UIColor grayColor].CGColor];
scrollLayer.contentsRect = CGRectMake(0, 0, 250, 350);
scrollLayer.contentsGravity = kCAGravityCenter;
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
{
scrollLayer.contentsScale = [[UIScreen mainScreen] scale];
}
CATextLayer *textLayer = [[CATextLayer alloc] init];
textLayer.alignmentMode = kCAAlignmentJustified;
textLayer.string = [_notice objectForKey:@"Text"];
textLayer.wrapped = YES;
textLayer.frame = CGRectMake(5, 5, 250, 500);
textLayer.font = [UIFont fontWithName:@"Helvetica" size:17.0f];
textLayer.foregroundColor = [UIColor blackColor].CGColor;
textLayer.backgroundColor = [UIColor whiteColor].CGColor;
[scrollLayer addSublayer:textLayer];
[self.view.layer addSublayer:scrollLayer];
[scrollLayer release];
[textLayer release];
How are you using contentsRect? It's a unit rectangle coordinates, that is each argument is between zero and one (inclusive).
So if you want to display 50 x 50 sub-rectangle at point 30, 30 you would do
textLayer.contentsRect = CGRectMake(30.0f / CONTENT_WIDTH, 30.0f / CONTENT_HEIGHT, 267.0f / CONTENT_WIDTH, 320.0f / CONTENT_HEIGHT);
Where CONTENT_WIDTH and CONTENT_HEIGHT are the size of the contents.