UITextView textContainer-Ausschlusspfad schlägt fehl, wenn er in voller Breite oben auf textContainer positioniert ist.

In iOS 8 versuche ich, eine UIImageView als Unteransicht einer UITextView hinzuzufügen, ähnlich wie hier gezeigt - aber mit dem Text unter dem Bild.

Ich möchte einen Ausschlusspfad verwenden, da ich das Bild auf anderen Geräten je nach Bildschirmgröße möglicherweise anders positionieren kann.

Es gibt jedoch ein Problem, bei dem der Ausschluss fehlschlägt und der Text im Ausschlusspfad angezeigt wird, wenn das zum Erstellen des Ausschlusspfads verwendete CGRect einen Y-Ursprung von 0 hat und die gesamte Breite der Textansicht einnimmt (sodass der Text dahinter angezeigt wird) die Bildansicht, wie Sie in diesem Screenshot sehen können).

Um dies zu testen, habe ich eine einfache App mit der Xcode-Vorlage "single view" erstell

- (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];
}

Ich habe auch versucht, NSTextContainer in Unterklassen zu unterteilen und die -lineFragmentRectForProposedRect-Methode zu überschreiben, aber das Anpassen des Y-Ursprungs dort scheint auch nicht zu helfen.

Um den benutzerdefinierten NSTextContainer zu verwenden, habe ich den UITextView-Stack in viewDidLoad () folgendermaßen eingerichtet:

// 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.";

Dann passe ich den Y-Ursprung im CustomTextContainer wie folgt an ... aber das schlägt genauso spektakulär fehl:

- (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;
}

Ich nehme an, dies könnte als ein Apple-Fehler angesehen werden, den ich melden muss (es sei denn, ich vermisse etwas Offensichtliches), aber wenn jemand eine Problemumgehung hat, wäre dies sehr willkommen.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage