Ios 如果UITextView textContainer排除路径为全宽且位于textContainer顶部,则该路径将失败
在iOS 8中,我尝试将UIImageView添加为UITextView的子视图,类似于此处所示,但在图像下方有文本 我想使用排除路径,因为在其他设备上,我可能会根据屏幕大小对图像进行不同的定位 但是,如果用于创建排除路径的CGRect的Y原点为0,并且占据了textView的整个宽度,则排除会失败,并且文本显示在排除路径中(因此,文本显示在imageView后面,如该屏幕截图所示) 为了测试这一点,我使用“单视图”Xcode模板构建了一个简单的应用程序,包括以下内容:Ios 如果UITextView textContainer排除路径为全宽且位于textContainer顶部,则该路径将失败,ios,uitextview,nstextcontainer,Ios,Uitextview,Nstextcontainer,在iOS 8中,我尝试将UIImageView添加为UITextView的子视图,类似于此处所示,但在图像下方有文本 我想使用排除路径,因为在其他设备上,我可能会根据屏幕大小对图像进行不同的定位 但是,如果用于创建排除路径的CGRect的Y原点为0,并且占据了textView的整个宽度,则排除会失败,并且文本显示在排除路径中(因此,文本显示在imageView后面,如该屏幕截图所示) 为了测试这一点,我使用“单视图”Xcode模板构建了一个简单的应用程序,包括以下内容: - (void)vie
- (void)viewDidLoad {
[super viewDidLoad];
// set up the textView
CGRect frame = CGRectMake(0, 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堆栈,如下所示:
然后我在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;
}
我想这可能是我需要报告的一个苹果bug(除非我遗漏了一些明显的东西),但如果有人有解决方法,我将不胜感激。快速解决方法:
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;
}
解决建议: 在文本中添加换行符
textView.text=“\n”+textView.text
这是一个老错误。在《推动限制iOS 7编程》一书中,作者在第377页写道:
在编写本文时,Text Kit无法正确处理某些类型的排除路径。特别是,如果排除路径会强制某些行为空,则整个布局可能会失败。例如,如果尝试以这种方式在圆中布局文本,则圆的顶部可能太小,无法包含任何文本,NSLayoutManager将自动失败。此限制影响NSTextContainer的所有使用。具体来说,如果lineFragmentRectForProposedRect:atIndex:writingDirection:remainingRect:返回空的cRect,则整个布局将失败
也许您可以重写lineFragmentRectForProposedRect:atIndex:writingDirection:remainingRect
:
您的自定义NSTextContainer的一部分,以解决此问题。我也遇到了此问题。如果您只需要排除textView顶部或底部的全宽空间,则可以使用
textContainerInset
我尝试过排除路径
我的问题是顶级排除路径从来都不起作用,它将内容推向顶部而不是中心,而底部内容的边距是排除路径边距的两倍
以下是对我有效的方法:
UITextView
Init
,使用textcontainer初始化它:
super.init(frame:frame,textContainer:textContainer)
布局子视图中
:
self.textContainerInset=UIEdgeInsets.init(顶部:t,左侧:l,底部:b,右侧:r)
UITextView
子类init()
中或在情节提要中,禁用滚动
self.isScrolEnabled=false
有关更多详细信息,请阅读。不幸的是,这似乎也不起作用。在您将origin.x或origin.y调整为足够大以使字符开始沿左侧或顶部显示(取决于字体大小)之前,它会以完全相同的方式失败。已尝试调整textView框架,但这也会将imageView向下推。我还试着调整文本容器。大小。高度。。。但你不能,因为它是只读的。一个难看的解决方法可能是将imageView改为self.view的子视图(同时按照建议调整textView框架),并在textView滚动时调整imageView的位置。我还不确定我是否想这么做。无论如何,我真的很欣赏这些建议。我也尝试过调整textView框架,然后简单地调整imageView的Y原点以将其向上移动(给它一个负Y原点)-但是大多数图像应该在空白处。我也经历了同样的事情(iOS8)。对我来说,这好像是个苹果虫。如果有人想出了一个成功的解决办法,大声说出来!另一个解决方法是使用故事板布局,并针对不同的屏幕大小类别对图像、文本和约束进行不同的布局。您只需仔细检查排除路径,并确保textView.textContainer包含它的rect@GeoffH,
textview.TextContainerSet
和textview.textContainer.lineFragmentPadding
和textview.contentInset
也需要检查……太好了。。。我选择了一种不同的方法来解决这个问题,它也有自己的问题,这正是我所需要的。谢谢
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;
}
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];
}