9

Вопрос по nsscrollview, cocoa, objective-c – Создать NSScrollView программно в NSView - Какао

У меня есть класс NSView, который заботится о пользовательском представлении, созданном в файле пера.

Теперь я хочу добавить NSScrollView в пользовательское представление, но мне нужно сделать это программно, а не с помощью Interface Builder (Embed Into Scroll View).

Я нашел этот код:

NSView *windowContentView = [mainWindow contentView];
NSRect windowContentBounds = [windowContentView bounds];
scrollView = [[NSScrollView alloc] init];
[scrollView setBorderType:NSNoBorder];
[scrollView setHasVerticalScroller:YES];
[scrollView setBounds: windowContentBounds];
[windowContentView addSubview:scrollView];

Предполагая, что я объявляю в качестве IBOutlets переменные "mainWindow" и «scrollView» выше, как бы я мог подключить их к соответствующим компонентам в Интерфейсном Разработчике? Есть ли смысл делать это так?

Или есть лучший способ добавить представление прокрутки программно?

Постскриптум Я не могу соединить их обычным способом, потому что не могу создать объект NSObject из Interface Builder или использовать владельца файла.

  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от Kevin
  • Какие? Конечно, вы можете связать программные представления с созданными интерфейсом представлениями.

    от ctpenrose
  • Если вы создаете представления программно, они не "подключаются" с построителем интерфейса

    от Otium
  • 7

    Мне сложно создать

    NSScrollView сAutoLayout программно, но наконец-то все заработало. ЭтоSwift версия.

        // Initial scrollview
        let scrollView = NSScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.borderType = .noBorder
        scrollView.backgroundColor = NSColor.gray
        scrollView.hasVerticalScroller = true
    
        window.contentView?.addSubview(scrollView)
        window.contentView?.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[scrollView]|", options: [], metrics: nil, views: ["scrollView": scrollView]))
        window.contentView?.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[scrollView]|", options: [], metrics: nil, views: ["scrollView": scrollView]))
    
        // Initial clip view
        let clipView = NSClipView()
        clipView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.contentView = clipView
        scrollView.addConstraint(NSLayoutConstraint(item: clipView, attribute: .left, relatedBy: .equal, toItem: scrollView, attribute: .left, multiplier: 1.0, constant: 0))
        scrollView.addConstraint(NSLayoutConstraint(item: clipView, attribute: .top, relatedBy: .equal, toItem: scrollView, attribute: .top, multiplier: 1.0, constant: 0))
        scrollView.addConstraint(NSLayoutConstraint(item: clipView, attribute: .right, relatedBy: .equal, toItem: scrollView, attribute: .right, multiplier: 1.0, constant: 0))
        scrollView.addConstraint(NSLayoutConstraint(item: clipView, attribute: .bottom, relatedBy: .equal, toItem: scrollView, attribute: .bottom, multiplier: 1.0, constant: 0))
    
        // Initial document view
        let documentView = NSView()
        documentView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.documentView = documentView
        clipView.addConstraint(NSLayoutConstraint(item: clipView, attribute: .left, relatedBy: .equal, toItem: documentView, attribute: .left, multiplier: 1.0, constant: 0))
        clipView.addConstraint(NSLayoutConstraint(item: clipView, attribute: .top, relatedBy: .equal, toItem: documentView, attribute: .top, multiplier: 1.0, constant: 0))
        clipView.addConstraint(NSLayoutConstraint(item: clipView, attribute: .right, relatedBy: .equal, toItem: documentView, attribute: .right, multiplier: 1.0, constant: 0))
    
        // Subview1
        let view1 = NSView()
        view1.translatesAutoresizingMaskIntoConstraints = false
        view1.wantsLayer = true
        view1.layer?.backgroundColor = NSColor.red.cgColor
        documentView.addSubview(view1)
        documentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view1]|", options: [], metrics: nil, views: ["view1": view1]))
    
        // Subview2
        let view2 = NSView()
        view2.translatesAutoresizingMaskIntoConstraints = false
        view2.wantsLayer = true
        view2.layer?.backgroundColor = NSColor.green.cgColor
        documentView.addSubview(view2)
        documentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view2]|", options: [], metrics: nil, views: ["view2": view2]))
    
        // Subview3
        let view3 = NSView()
        view3.translatesAutoresizingMaskIntoConstraints = false
        view3.wantsLayer = true
        view3.layer?.backgroundColor = NSColor.blue.cgColor
        documentView.addSubview(view3)
        documentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view3]|", options: [], metrics: nil, views: ["view3": view3]))
    
        // Vertical autolayout
        documentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[view1(==100)][view2(==200)][view3(==300)]", options: [], metrics: nil, views: ["view1": view1, "view2": view2, "view3": view3]))
        documentView.addConstraint(NSLayoutConstraint(item: documentView, attribute: .bottom, relatedBy: .equal, toItem: view3, attribute: .bottom, multiplier: 1.0, constant: 0))
    

    enter image description here

  • 9

    Этот фрагмент кода должен продемонстрировать

    как программно создать NSScrollView и использовать его для отображения любого представления, будь то перо или код. В случае сгенерированного nib-представления вам просто нужно предварительно загрузить nib-файл в свой пользовательский вид и иметь выход к своему пользовательскому представлению (outletToCustomViewLoadedFromNib), созданный для владельца файла.

    NSScrollView *scrollView = [[NSScrollView alloc] initWithFrame:[[mainWindow contentView] frame]];
    
    // configure the scroll view
    [scrollView setBorderType:NSNoBorder];
    [scrollView setHasVerticalScroller:YES];
    
    // embed your custom view in the scroll view
    [scrollView setDocumentView:outletToCustomViewLoadedFromNib];
    
    // set the scroll view as the content view of your window
    [mainWindow setContentView:scrollView];
    

    У Apple есть руководство по этому вопросу, на которое я не буду ссылаться, поскольку оно требует доступа Apple Developer Connection, и их ссылки часто ломаются. Он называется «Создание и настройка вида прокрутки». и в настоящее время может быть найден, ища его название, используя Google.

  • 0

    Ответ Брайана правильный, вот как создать

    NSStackView внутриNSScrollView в Swift 4.2

    Возможно, вам придется перевернутьNSClipView

    final class FlippedClipView: NSClipView {
      override var isFlipped: Bool {
        return true
      }
    }
    
    
    private func setup() {
      setupScrollView()
      setupStackView()
    }
    
    private func setupScrollView() {
      view.addSubview(scrollView)
      scrollView.translatesAutoresizingMaskIntoConstraints = false
      scrollView.hasVerticalScroller = true
      scrollView.drawsBackground = false
    
      NSLayoutConstraint.activate([
        scrollView.leftAnchor.constraint(equalTo: view.leftAnchor),
        scrollView.rightAnchor.constraint(equalTo: view.rightAnchor),
        scrollView.topAnchor.constraint(equalTo: view.topAnchor),
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -30),
    
        scrollView.heightAnchor.constraint(equalToConstant: 400)
      ])
    
      let clipView = FlippedClipView()
      clipView.drawsBackground = false
      scrollView.contentView = clipView
      clipView.translatesAutoresizingMaskIntoConstraints = false
      NSLayoutConstraint.activate([
        clipView.leftAnchor.constraint(equalTo: scrollView.leftAnchor),
        clipView.rightAnchor.constraint(equalTo: scrollView.rightAnchor),
        clipView.topAnchor.constraint(equalTo: scrollView.topAnchor),
        clipView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor)
      ]
      scrollView.documentView = stackView
    
      stackView.translatesAutoresizingMaskIntoConstraints = false
      NSLayoutConstraint.activate([
        stackView.leftAnchor.constraint(equalTo: clipView.leftAnchor),
        stackView.topAnchor.constraint(equalTo: clipView.topAnchor),
        stackView.rightAnchor.constraint(equalTo: clipView.rightAnchor),
        // NOTE: No need for bottomAnchor
      ])
    }
    
    private func setupStackView() {
      stackView.orientation = .vertical
      stackView.edgeInsets = NSEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
    
      NSLayoutConstraint.activate([
        myRowView.heightAnchor.constraint(equalToConstant: 40)
      ])
    
      myRowView.onPress = { [weak self] in
        self?.doSomething()
      }
    
      stackView.addArrangedSubview(myRowView)
    }