Последовательный выбор среди нескольких NSTextViews

У меня есть куча NSTextViewс, что я хотел бы поделиться одним выбором. Я в основном хочу, чтобы это велось как выделение текста на веб-странице, где есть несколько текстовых представлений, но вы можете перетаскивать, чтобы последовательно выбирать текст среди них.

Я нашел этот документ, в котором говорится, что возможно иметь несколько NSTextContainer объекты, разделяющие один NSLayoutManager и, таким образом, поделиться выбором. Это на полпути к тому, что я хочу, за исключением того факта, что один NSLayoutManager может иметь только один NSTextStorage объект. Я хочу, чтобы у каждого текстового представления был свой NSTextStorage так что у каждого текстового представления может быть свой собственный текст, но я все еще хочу иметь возможность выбирать текст в нескольких текстовых представлениях одним перетаскиванием. Это возможно?

2 ответа

Решение

Нет простого способа решить эту проблему (как я пытался найти, задавая этот вопрос). Он включает в себя всю обработку событий мыши и вычисления текста, которые вы ожидаете, поэтому я написал код и открыл его как INDSequentialTextSelectionManager,

Чтобы заставить работать эти отдельные текстовые контейнеры, вы должны рассчитать нарисованный размер каждой части строки и ограничить NSTextView этим размером:

    NSLayoutManager * layout = [[NSLayoutManager alloc] init];
    NSString * storedString = @"A\nquick\nBrown\nFox";
    NSTextStorage * storage = [[NSTextStorage alloc] initWithString:storedString];
    [storage addLayoutManager:layout];

    //I assume you have a parent view to add the text views
    NSView * view;

    //Assuming you want to split up into separate view by line break
    NSArray * paragraphs = [storedString componentsSeparatedByString:@"\n"];
    for (NSString * paragraph in paragraphs)
    {
        NSSize paragraphSize = [paragraph sizeWithAttributes:@{}];
        //Create a text container only big enough for the string to be displayed by the text view
        NSTextContainer * paragraphContainer = [[NSTextContainer alloc] initWithContainerSize:paragraphSize];
        [layout addTextContainer:paragraphContainer];

        //Use autolayout or calculate size/placement as you go along
        NSRect lazyRectWithoutSizeOrPlacement = NSMakeRect(0, 0, 0, 0);
        NSTextView * textView = [[NSTextView alloc] initWithFrame:lazyRectWithoutSizeOrPlacement
                                                    textContainer:paragraphContainer];
        [view addSubview:textView];
    }

Вы можете добавить делегата в NSLayoutManager для наблюдения за использованием вашего текстового контейнера:

- (void)layoutManager:(NSLayoutManager *)aLayoutManager
didCompleteLayoutForTextContainer:(NSTextContainer *)aTextContainer
                    atEnd:(BOOL)flag
{
    if (aTextContainer == nil)
    {
        //All text was unable to be displayed in existing containers. A new NSTextContainer is needed.
    }
}
Другие вопросы по тегам