我确信这里有一个非常非常简单的解决方案,但我似乎无法弄明白。我有一个水平滚动UICollectionView与节标题。我希望段标题文本垂直写入:
我知道它与旋转上下文有关,但是尽管阅读了文档并在这里阅读了类似的帖子,但我似乎无法理解这一点。这就是我到目前为止所做的:
- (void)drawTitle
{
CGRect titleRect = self.bounds;
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
paragraphStyle.alignment = NSTextAlignmentCenter;
UIFont *cellFont = [UIFont fontWithName: DEFAULT_FONT size: self.bounds.size.width * FONT_WIDTH_FACTOR];
NSAttributedString *cellText = [[NSAttributedString alloc] initWithString: self.title attributes: @{ NSParagraphStyleAttributeName : paragraphStyle, NSFontAttributeName : cellFont, NSForegroundColorAttributeName : [UIColor whiteColor] }];
[cellText drawInRect: titleRect];
// Rotation code???
}
我真的很感激这方面的帮助,就像我确定的那样简单。我在这里显然遗漏了一些东西。非常感谢,提前。
答案 0 :(得分:2)
如果您按照现在的方式绘制文本,这是图形上下文的图表:
我们需要做两件事。我们需要旋转坐标系以便垂直绘制文本,我们需要移动坐标系(或文本矩形),以便旋转的文本矩形与(未旋转的)self.bounds
矩形完全重叠。
我们无法使用UIKit功能转换坐标系。我们必须进入Core Graphics(aka Quartz)级别。首先,我们获得对图形上下文的引用并保存其状态:
CGContextRef gc = UIGraphicsGetCurrentContext();
CGContextSaveGState(gc); {
现在我们可以改变坐标系。首先,我们将原点“转换”(移动)到边界矩形的左下角:
CGContextTranslateCTM(gc, 0, titleRect.size.height);
此时,如果我们绘制字符串,图形上下文将如下所示:
所以现在我们将以直角旋转坐标系:
CGContextRotateCTM(gc, -M_PI_2);
我可能有角度错误的迹象。如果没有显示任何内容,请尝试删除-
符号。
现在,如果我们绘制字符串,图形上下文将如下所示:
请注意,在我们传递给drawInRect:
的矩形中,width
始终是沿x轴的距离,现在x轴是垂直的。所以我们希望文本矩形与视图的高度一样宽,我们希望文本矩形与视图的宽度一样高。因此:
[cellText drawInRect:CGRectMake(0, 0, titleRect.size.height, titleRect.size.width)];
我们都完成了,所以我们恢复了图形上下文的状态:
} CGContextRestoreGState(gc);
所有在一起:
CGContextRef gc = UIGraphicsGetCurrentContext();
CGContextSaveGState(gc); {
CGContextTranslateCTM(gc, 0, titleRect.size.height);
CGContextRotateCTM(gc, -M_PI_2);
[cellText drawInRect:CGRectMake(0, 0, titleRect.size.height, titleRect.size.width)];
} CGContextRestoreGState(gc);
答案 1 :(得分:0)
这不是问题的另一个答案,而只是抢劫mayoff的优秀答案的后续行动。
旋转后,我也遇到了没有居中的问题。我想出了下面的“修复” - 呃,让我们称之为它,一个kludge - 让文本居中。
我绝不是iPhone编程专家,毫无疑问这样做的方法更好,但这对我有用。
if (...scrolling is horizontal...) {
// Rotate the text so it runs vertically.
CGAffineTransform rotateItem = CGAffineTransformMakeRotation(-M_PI_2);
header.label.transform = rotateItem;
// After rotating the label the text is always left-justified,
// i.e. it appears at the bottom of the screen. Do some calculations
// to get the title space-padded so it appears roughly centered.
// Calculate the size of the label.
float sizeOfLabel = [header.label.text sizeWithFont:header.label.font].width;
// Calculate where the label should start if it is to appear centered.
float centeredLabelStartPosition = (header.frame.size.height - sizeOfLabel) / 2.0;
// Calculate the size of a space character.
float sizeOfSpaceChar = [@" " sizeWithFont:header.label.font].width;
// Calculate how many leading space characters are needed to appear before the label
// so that the label appears centered. (The +1 is because I like it shifted
// ever-so-slightly toward the top of the screen, rather than true center.)
int numberOfLeadingSpaces = roundf(centeredLabelStartPosition / sizeOfSpaceChar) + 1;
// Create the label with leading space padding to get it centered.
header.label.text = [NSString stringWithFormat:@"%*s%@", numberOfLeadingSpaces, "", header.label.text];
} else {
// For vertical scrolling, turn off the rotation (which might have been left on
// if this label was used previously).
header.label.transform = CGAffineTransformIdentity;
}
重要提示:当用户在水平和垂直之间旋转iPhone方向时,iOS不会调用collectionView:viewForSupplementaryElementOfKind:atIndexPath:重绘部分标题。因此,标题不会在旋转时自动重新居中。
如果你愿意为你的应用关闭“自动布局”,这是一种更简单的方法来将标题文本置于中心位置。这也有益于标题可以在旋转时自动重新居中。在故事板中,您必须设置标题以水平扩展(或以编程方式执行)。
if (...scrolling is horizontal...) {
// Rotate the text so it runs vertically.
header.label.transform = CGAffineTransformMakeRotation(-M_PI_2);
// Center the text after rotation.
header.label.frame = CGRectMake(0.0, 0.0, header.frame.size.width, header.frame.size.height);
header.label.center = CGPointMake(header.frame.size.width/2, header.frame.size.height/2);
} else {
// For vertical scrolling, turn off the rotation (which might have been left on
// if this label was used previously).
header.label.transform = CGAffineTransformIdentity;
}