Korzystanie z Autolayout z rozszerzaniem NSTextViews

Moja aplikacja składa się z NSScrollView, którego widok dokumentu zawiera szereg pionowo ułożonych NSTextViews - z których każdy zmienia rozmiar w kierunku pionowym, gdy tekst jest dodawany.

Obecnie wszystko jest zarządzane w kodzie. NSTextViews zmienia rozmiar automatycznie, ale obserwuję ich zmianę rozmiaru za pomocą NSViewFrameDidChangeNotification, przelicza wszystkie ich pochodzenie, aby nie nachodziły na siebie, i zmienia rozmiar ich superview (widok przewijania dokumentu) tak, że wszystkie pasują i mogą być przewijane do.

Wydaje się, że to byłby idealnym kandydatem do autolayout! Ustawiam NSLayoutConstraints pomiędzy pierwszym widokiem tekstu i jego kontenerem, ostatnim widokiem tekstu i jego kontenerem oraz każdym widokiem tekstu między sobą. Następnie, jeśli dowolny widok tekstowy rośnie, automatycznie "popycha" pochodzenie widoków tekstowych poniżej, aby zaspokoić kontrasty, ostatecznie zwiększając rozmiar widoku dokumentu i wszyscy są zadowoleni!

Z wyjątkiem tego, że nie ma sposobu, aby NSTextView automatycznie rosnąć, gdy tekst jest dodawany w oparciu o ograniczenia układ? Używając dokładnie tego samego NSTextView, który został automatycznie Rozszerzony jako tekst wprowadzony wcześniej, jeśli nie podam ograniczenia dla jego wysokości, defautls do 0 i nie jest wyświetlany. Jeśli podam ograniczenie, nawet nierówność, taka jak >=20, pozostaje zablokowana w tym rozmiarze i nie rośnie w miarę dodawania tekstu.

Podejrzewam, że ma to związek z implementacją -intrinsicContentSize NSTextView, która domyślnie zwraca (NSViewNoInstrinsicMetric, NSViewNoInstrinsicMetric).

Więc moje pytania: jeśli podklasuję NSTextView aby zwrócić bardziej znaczące intrinsicContentSize czy na podstawie układu mojego tekstu mój autolayout będzie działał zgodnie z oczekiwaniami?

Jakieś wskazówki dotyczące implementacji intrinsicContentSize dla pionowej zmiany rozmiaru NSTextView?

Author: jemmons, 2012-06-28

3 answers

Miałem podobny problem z nstextfield i okazało się, że wynika to z tego, że widok chciał ciasno przytulić swoją treść tekstową wzdłuż orientacji pionowej. Jeśli więc ustawisz priorytet Przytulania treści na coś niższego niż priorytety innych ograniczeń, może to zadziałać. Np.:

[textView setContentHuggingPriority:NSLayoutPriorityFittingSizeCompression-1.0 forOrientation:NSLayoutConstraintOrientationVertical];
 10
Author: Marc Prud'hommeaux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-10 16:56:20

Pracuję nad bardzo podobną konfiguracją-pionowym stosem widoków zawierających widoki tekstowe, które rozszerzają się, aby pasowały do ich zawartości tekstowej i używają autolayout.

Do tej pory musiałem podklasować NSTextView, co nie jest czyste, ale działa znakomicie w praktyce:

- (NSSize) intrinsicContentSize {
    NSTextContainer* textContainer = [self textContainer];
    NSLayoutManager* layoutManager = [self layoutManager];
    [layoutManager ensureLayoutForTextContainer: textContainer];
    return [layoutManager usedRectForTextContainer: textContainer].size;
}

- (void) didChangeText {
    [super didChangeText];
    [self invalidateIntrinsicContentSize];
}

Początkowy rozmiar widoku tekstowego po dodaniu z addSubview jest, co ciekawe, nie jest wewnętrznym rozmiarem; jeszcze nie wiem ,jak wydać pierwsze unieważnienie( zaczepianie viewDidMoveToSuperview nie pomaga), ale jestem pewien, że wymyślę w końcu to się wydarzy.

 22
Author: Alexander Staubo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-22 23:15:33

Oto jak stworzyć rozszerzający się NSTextView za pomocą Auto Layout, w języku Swift 3Tutaj wpisz opis obrazka

  • użyłem kotwic do Auto layoutu
  • użyj textDidChange z NSTextDelegate. NSTextViewDelegate odpowiada NSTextDelegate
  • Idea jest taka, że textView ma edges ograniczenia, co oznacza, że za każdym razem, gdy jego intrinsicContentSize zmieni się, rozszerzy swój rodzic, czyli scrollView {13]}

    import Cocoa
    import Anchors
    
    class TextView: NSTextView {
      override var intrinsicContentSize: NSSize {
        guard let manager = textContainer?.layoutManager else {
          return .zero
        }
    
        manager.ensureLayout(for: textContainer!)
    
        return manager.usedRect(for: textContainer!).size
      }
    }
    
    class ViewController: NSViewController, NSTextViewDelegate {
    
      @IBOutlet var textView: NSTextView!
      @IBOutlet weak var scrollView: NSScrollView!
      override func viewDidLoad() {
        super.viewDidLoad()
    
        textView.delegate = self
    
        activate(
          scrollView.anchor.top.constant(100),
          scrollView.anchor.paddingHorizontally(30)
        )
    
        activate(
          textView.anchor.edges
        )
      }
    
      // MARK: - NSTextDelegate
      func textDidChange(_ notification: Notification) {
        guard let textView = notification.object as? NSTextView else { return }
    
        print(textView.intrinsicContentSize)
        textView.invalidateIntrinsicContentSize()
      }
    }
    
 5
Author: onmyway133,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-19 06:31:18