Как передать события прокрутки родительскому NSScrollView - PullRequest
7 голосов
/ 09 июня 2011

Мне нужны фиксированные размеры NSTextViews в большем окне прокрутки. IB требует, чтобы текстовые представления были внутри их собственных NSScrollViews, даже если их минимальный / максимальный размеры фиксированы, чтобы они фактически не прокручивались. Когда жесты трекпада выполняются в пределах рамок текстового обзора (независимо от того, имеют ли они фокус), они захватываются видами прокрутки текстовых представлений, поэтому ничего не происходит.

Как я могу указать скролл-просмотрам текстовых представлений передавать события прокрутки в основное окно прокрутки? (Или, возможно, мне следует спросить, как я говорю главному окну прокрутки окна обрабатывать эти события самостоятельно, а не передавать его дочерним прокруткам.)

Структура IB такая:

  • окно
    • просмотр содержимого окна
      • большой вид прокрутки для окна (желаемая цель для событий прокрутки)
        • коробка
          • просмотр содержимого в отдельном xib
            • прокрутка для просмотра текста
              • TextView
И, да, окно прокручивается правильно, когда текстовые представления не имеют фокус.

Ответы [ 5 ]

11 голосов
/ 17 октября 2011

Вам не нужно создавать розетку "svActive", чтобы отслеживать свой суперскролл-просмотр.Просто напишите это предложение в событии scrollWheel:

[[self nextResponder] scrollWheel:event];

, чтобы передать событие следующему респонденту в цепочке респондентов.

7 голосов
/ 10 июня 2011

IB не требует, чтобы у вас был текстовый вид внутри NSScrollView;это просто значение по умолчанию, потому что большую часть времени вы хотите, чтобы ваше представление прокручивалось.Выберите NSTextView и выберите Layout> Unembed Objects.Обратите внимание, что после этого вы больше не можете перемещать или изменять размер своего представления в IB.Кажется, это ошибка.

Вот пример того, как поместить два NSTextViews в один NSScrollView.

Добавьте два текстовых представления рядом друг с другом;вставьте в них текст, чтобы вы могли видеть, что происходит.

Выбор видов;выберите «Макет»> «Встроить объекты в»> «Представление прокрутки».Это помещает их в общий NSView внутри NSScrollView.

Выберите текстовые представления;выберите Layout> Unembed Objects.

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

Обратите внимание на высоту вида документа (здесь его 175).

Уменьшите вид прокрутки.Это также изменяет размер представления документа (NSView).

Восстановление вида документа до его исходного размера (я установил высоту обратно в 175).

Готово!Прокрутка работает так, как вы ожидаете.

3 голосов
/ 25 июня 2011

Это действительно неловко.После нескольких недель откладывания я сделал первую попытку заставить NSScrollView работать в подклассе и вести себя пассивно - и это оказалось совсем не просто.

Вот подкласс:

h файл:

#import <Cocoa/Cocoa.h>

@interface ScrollViewPassive : NSScrollView {

// This property is assigned a ref to windowController’s main scrollview.
NSScrollView *svActive; 

}

@property (nonatomic, retain) NSScrollView *svActive;

@end

m file:

#import "ScrollViewPassive.h"

@implementation ScrollViewPassive

@synthesize svActive;

// Pass any gesture scrolling up to the main, active scrollview.
- (void)scrollWheel:(NSEvent *)event {
    [svActive scrollWheel:event];
}

@end

Нет необходимости создавать выходы для этих пассивных прокруток;Я даю им их ссылки на основной вид прокрутки сразу после того, как их xibs назначены в качестве содержимого NSBox:

    [self.boxDisplayingTextViews setContentView:self.subviewCtllr1.view];
    // A textview's superview's superview is its scrollview:    
    ((ScrollViewPassive *)[[self.subviewCtllr1.textview1 superview] superview]).svActive = self.scrollviewMain;

Вот и все.Работает как шарм.

1 голос
/ 10 июня 2011

Я считаю, что IB3 и Xcode4 сражаются с вами, если вы пытаетесь сделать это напрямую, но вы можете сделать это косвенно. Сначала перетащите текстовое представление из просмотра прокрутки и удалите представление прокрутки. Вы получите осиротевшее текстовое представление. Я не знаю, как заставить IB позволить вам поместить это в ваше окно, но оно будет в вашем NIB. Теперь, присоедините к нему IBOutlet, и во время выполнения сделайте addSubview: и настройте его фрейм, чтобы переместить его в любой вид прокрутки, в котором вы хотите его видеть.

По моему опыту, NIB - хорошая вещь, но каждый сложный NIB, с которым я когда-либо работал, нуждался в некоторой окончательной перестройке кода.

0 голосов
/ 06 февраля 2019

На основе ответа @ phaibin, вот как вы это сделаете в Swift 4.2 .

Сначала подкласс NSScrollView и переопределение scrollWheel:

class ScrollThingy: NSScrollView{
  override func scrollWheel(with event: NSEvent) {
    self.nextResponder?.scrollWheel(with: event)
  }
}

Затем поместите класс ScrollThingy (или как вы его называете) на NSScrollView, который обернут вокруг вашего NSTextView.После этого родительский элемент NSScrollView получит событие прокрутки.

...