В iOS 8 я пытаюсь добавить UIImageView в качестве подзадачи UITextView, похожего на то, что показано здесь, но с текстом ниже изображения.
Я хочу сделать это с использованием пути исключения, потому что на других устройствах я мог бы поместить изображение по-разному в зависимости от размера экрана.
Однако существует ли проблема, когда CGRect, используемый для создания пути исключения, имеет Y-начало 0 и занимает всю ширину textView, исключение завершается с ошибкой и текст появляется в пути исключения (так что текст показанный за изображением, как вы можете видеть на этом снимке экрана).
Чтобы протестировать это, я построил простое приложение, используя шаблон Xcode с одним представлением, со следующим:
- (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, я установил такой стек UITextView в viewDidLoad():
// 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, 0, self.view.frame.size.width, 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.";
Затем я настраиваю начало Y в CustomTextContainer, как это... но это не так эффектно:
- (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;
}
Я полагаю, это можно считать ошибкой Apple, о которой мне нужно сообщить (если я не пропущу что-то очевидное), но если у кого-то есть обходной путь, это будет очень признательно.