在iOS 8中,我尝试添加一个UI
ImageView作为UITextView的子视图,类似于此处显示的内容,但文字位于图像下方.
我想使用排除路径,因为在其他设备上,我可能会根据屏幕大小不同地定位图像.
但是,如果CGRect用于创建排除路径的Y原点为0,并占用textView的全部宽度,则排除失败,文本将显示在排除路径中(以便文本显示在imageView,你可以看到在那个截图).
要测试这个,我使用“单视图”Xcode模板构建了一个简单的应用程序,其中包含以下内容:
- (void)viewDidLoad {
[super viewDidLoad];
// set up the textView
CGRect frame = CGRectMake(0,self.view.frame.size.width,self.view.frame.size.height);
UITextView *textView = [[UITextView alloc] initWithFrame:frame];
[textView setFont:[UIFont systemFontOfSize:36.0]];
[self.view addSubview:textView];
textView.text = @"I wish this text appeared below the exclusion rect and not within it.";
// add the photo
CGFloat textViewWidth = textView.frame.size.width;
// uncomment if you want to see that the exclusion path DOES work when not taking up the full width:
// textViewWidth = textViewWidth / 2.0;
CGFloat originY = 0.0;
// uncomment if you want to see that the exclusion path DOES work if the Y origin isn't 0
// originY = 54.0;
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"photo_thumbnail"]];
imageView.frame = CGRectMake(0,originY,textViewWidth,textViewWidth);
imageView.alpha = 0.7; // just so you can see that the text is within the exclusion path (behind photo)
[textView addSubview:imageView];
// set the exclusion path (to the same rect as the imageView)
CGRect exclusionRect = [textView convertRect:imageView.bounds fromView:imageView];
UIBezierPath *exclusionPath = [UIBezierPath bezierPathWithRect:exclusionRect];
textView.textContainer.exclusionPaths = @[exclusionPath];
}
我也尝试子类化NSTextContainer并覆盖-lineFragmentRectForProposedRect方法,但调整Y原点似乎也没有帮助.
要使用自定义NSTextContainer,我在viewDidLoad()中设置了这样的UITextView堆栈:
// set up the textView stack NSTextStorage *textStorage = [[NSTextStorage alloc] init]; NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; [textStorage addLayoutManager:layoutManager]; CGSize containerSize = CGSizeMake(self.view.frame.size.width,CGFLOAT_MAX); CustomTextContainer *textContainer = [[CustomTextContainer alloc] initWithSize:containerSize]; [layoutManager addTextContainer:textContainer]; CGRect frame = CGRectMake(0,self.view.frame.size.height); UITextView *textView = [[UITextView alloc] initWithFrame:frame textContainer:textContainer]; [textView setFont:[UIFont systemFontOfSize:36.0]]; [self.view addSubview:textView]; textView.text = @"I wish this text appeared below the exclusion rect and not within it.";
然后我调整这个CustomTextContainer中的Y原点,但是这样也是如此壮观:
- (CGRect)lineFragmentRectForProposedRect:(CGRect)proposedRect atIndex:(NSUInteger)characterIndex writingDirection:(NSWritingDirection)baseWritingDirection remainingRect:(CGRect *)remainingRect {
CGRect correctedRect = proposedRect;
if (correctedRect.origin.y == 0) {
correctedRect.origin.y += 414.0;
}
correctedRect = [super lineFragmentRectForProposedRect:correctedRect atIndex:characterIndex writingDirection:baseWritingDirection remainingRect:remainingRect];
NSLog(@"origin.y: %f | characterIndex: %lu",correctedRect.origin.y,(unsigned long)characterIndex);
return correctedRect;
}
我想这可以被认为是一个我需要报告的苹果错误(除非我缺少一些明显的东西),但是如果有人有解决办法,这将是非常感激的.
解决方法
快速解决方法:
CGRect exclusionRect = [textView convertRect:imageView.bounds fromView:imageView];
if (exclusionRect.origin.x <= 0 && exclusionRect.origin.y <= 0 && exclusionRect.size.width >= textView.bounds.size.width) {
exclusionRect.origin.x = 1;
exclusionRect.origin.y = 1;
exclusionRect.size.width -= 2;
}
您的图像仍然会保持相同,除非您使用的字体宽度为1像素(我甚至不确定可能会提供字距调整等),否则您的excludeRect将被保证小于整个宽度.
我有兴趣知道如果你允许你的直觉被实时地移动,你会看到什么样的结果.附上一个UIPanGestureRecognizer并更新你的排除对象,当你平移屏幕.文本在什么时候跳入图像?
编辑:如果您看到问题,直到它能够适应至少一个字符,或许尝试调整您的文本框架.
if (exclusionRect.origin.x <= 0 && exclusionRect.origin.y <= 0 && exclusionRect.size.width >= textView.bounds.size.width) {
frame.origin.y += CGRectGetMaxY(exclusionRect);
frame.size.height -= CGRectGetMaxY(exclusionRect);
[textView setFrame:frame];
}