如何使用文本工具包(iOS 7)在UITextView中垂直居中文本

时间:2013-11-14 09:08:44

标签: ios ios7 uitextview textkit

要点:

在iOS 6中,我通过键值观察文本视图的contentSize属性(https://stackoverflow.com/a/12591299/1239263),在UITextView中垂直居中。当我升级到iOS 7时,后一种技术工作不一致。

我宁愿使用Text Kit在UITextView中垂直居中文本,而不是尝试修复KVO技术。

我使用Text Kit设计了一个解决方案,但它会在设备轮换时中断。

UITextView是橙色的。

最初加载文本视图时,文本正确居中:

enter image description here

当设备旋转为横向时,文本仍然正确居中:

enter image description here

但是,当设备旋转回纵向时,文本未正确居中。文本应该在一行上,就像在上面的第一个截图中一样。

enter image description here

对于后一个屏幕截图,将几何图形记录到控制台会显示文本视图的文本容器宽度太窄。

详细信息:

@interface ViewController ()

// text view is created in storyboard; it's added to the root view and it's using auto layout
@property (weak, nonatomic) IBOutlet UITextView *textView;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSTextContainer *textContainer = self.textView.textContainer;
   [textContainer setWidthTracksTextView:YES];  
}

- (void)centerText
{
    NSTextContainer *container = self.textView.textContainer;
    NSLayoutManager *layoutManager = container.layoutManager;

    CGRect textRect = [layoutManager usedRectForTextContainer:container];

    UIEdgeInsets inset = UIEdgeInsetsZero;
    inset.top = self.textView.bounds.size.height / 2 - textRect.size.height / 2;
    inset.left = self.textView.bounds.size.width / 2 - textRect.size.width / 2;

    self.textView.textContainerInset = inset;
}

- (void)viewDidLayoutSubviews
{
    [self centerText];
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];

    [self centerText];
}

我尝试了什么:

我尝试在centerText方法中手动设置容器大小。根据我为容器大小设置的值,在某些情况下设置容器大小确实有效。哪个案子?这取决于显示的文本行数。

// fixes problem if a single line of text; clips multi-line text
container.size = CGSizeZero; 

// fixes problem if multi-line text, but not if a single line of text
container.size = CGSizeMake(self.textView.bounds.size.width, FLT_MAX);

由于我将widthTracksTextView设置为YES,我不明白为什么我需要设置文本容器大小。如果我确实需要设置文本容器宽度,为什么正确的值似乎取决于显示的行数?

1 个答案:

答案 0 :(得分:0)

我想我找到了解释和解决方案。容器本身存在线段碎片的一些问题。这就是我在包中看到的。

  

返回receiverRect接收器内的行片段rect的边界。这是proposedRect和-size属性定义的接收者的边界矩形的交集。 -exclusionPaths属性定义的区域将从返回值中排除。 charIndex是正在处理的行片段的文本存储内的字符位置。由于排除路径,proposedRect可能会被划分为多个行片段。

使用屏幕旋转时,排除exclusionPaths。因此文本无法保存您想要的方向值。这就是为什么当你定义CGRect时,它以某种方式解决了这个问题。 所以你应该使用的方法是:

- (CGRect)lineFragmentRectForProposedRect:(CGRect)proposedRect atIndex:(NSUInteger)characterIndex writingDirection:(NSWritingDirection)baseWritingDirection remainingRect:(CGRect *)remainingRect;