Search code examples
swiftmacoscocoanstabview

tab view controller with dynamic width and height


I working with swift 4 for macOS. I have a tabView Controller with three tab view items. All item view controllers have different size (width / height)

Now I would like to realize, that the tabview controller will change his own size animated to the content size of the selected tab view item.

But I don't know, how I can realize that?


Solution

  • I created a quick demo code for your case. Basically you need to remember the original size of each view item. When tab selected, just resize the window.

    import Cocoa
    
    class MyViewController: NSViewController {
    var originalSize: NSSize
    
    init(originalSize: NSSize) {
        self.originalSize = originalSize
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    
    
       }
    }
    
    @NSApplicationMain
    class AppDelegate: NSObject, NSApplicationDelegate, NSTabViewDelegate {
    @IBOutlet weak var window: NSWindow!
    
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Insert code here to initialize your application
        // Tabview
        let tabView = NSTabView()
        tabView.delegate = self
        tabView.translatesAutoresizingMaskIntoConstraints = false
        self.window.contentView?.addSubview(tabView)
        self.window.contentView?.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[tabView]|", options: [], metrics: nil, views: ["tabView": tabView]))
        self.window.contentView?.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[tabView]|", options: [], metrics: nil, views: ["tabView": tabView]))
    
        // Tab item views
        let firstVC = MyViewController(originalSize: NSSize(width: 200, height: 200))
        firstVC.view = NSView()
        let firstView = firstVC.view
        firstView.wantsLayer = true
        firstView.layer?.backgroundColor = NSColor.red.cgColor
        let firstItem = NSTabViewItem(viewController: firstVC)
        tabView.addTabViewItem(firstItem)
    
        let secondVC = MyViewController(originalSize: NSSize(width: 300, height: 300))
        secondVC.view = NSView()
        let secondView = secondVC.view
        secondView.wantsLayer = true
        secondView.layer?.backgroundColor = NSColor.yellow.cgColor
        let secondItem = NSTabViewItem(viewController: secondVC)
        tabView.addTabViewItem(secondItem)
    
        let thirdVC = MyViewController(originalSize: NSSize(width: 400, height: 400))
        thirdVC.view = NSView()
        let thirdView = thirdVC.view
        thirdView.wantsLayer = true
        thirdView.layer?.backgroundColor = NSColor.green.cgColor
        let thirdItem = NSTabViewItem(viewController: thirdVC)
        tabView.addTabViewItem(thirdItem)
    }
    
    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }
    
    // Delegate
    func tabView(_ tabView: NSTabView, didSelect tabViewItem: NSTabViewItem?) {
        if let selectedVC = tabViewItem?.viewController as? MyViewController {
            print("Selected view size is : \(selectedVC.originalSize)")
    
            var frame = window.frame
            frame.size = selectedVC.originalSize
    
            window.setFrame(frame, display: true, animate: true)
    
    
           }
        }
    }
    

    enter image description here