How do I adjust my popover to the size of the content in my tableview in swift?

后端 未结 6 1098
情话喂你
情话喂你 2021-01-31 03:17

I\'m using popoverPresentationController to show my popover. The UITableViewController used to show as popover is created programmatically and will usu

相关标签:
6条回答
  • 2021-01-31 03:23

    First thing first: All comments are good and help full. I have did little change in my logic which makes my VC as reusable component.

    Calling this method inside viewWillAppear:(BOOL)animated:

    -(void) setPopOverPreferedContentHeight {
    
         if (self.popoverPresentationController && self.tableView.contentSize.height < MAX_POPOVER_HEIGHT) {
              self.preferredContentSize=self.tableView.contentSize;
         } else if (self.popoverPresentationController){
             self.preferredContentSize = CGSizeMake(self.tableView.contentSize.width, MAX_POPOVER_HEIGHT);
       }
    }
    
    0 讨论(0)
  • 2021-01-31 03:24

    For swift 4 if you want to observe the content size I found this to be the optimal solution. Reporting it here since I did not find a complete example online:

    class MyTableViewController: UITableViewController {
    
        private var kvoContext = 0
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            addObserver(self, forKeyPath: #keyPath(tableView.contentSize), options: .new, context: &kvoContext)
    
        }
    
        override func viewDidDisappear(_ animated: Bool) {
            removeObserver(self, forKeyPath: #keyPath(tableView.contentSize))
            super.viewDidDisappear(animated)
        }
    
        override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
            if context == &kvoContext, keyPath == #keyPath(tableView.contentSize),
                let contentSize = change?[NSKeyValueChangeKey.newKey] as? CGSize  {
                self.popoverPresentationController?.presentedViewController.preferredContentSize = contentSize
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-31 03:28

    In your UITableViewController's viewDidLoad() you can add an observer:

    self.tableView.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)
    

    Then add this method:

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        self.preferredContentSize = tableView.contentSize
    }
    

    Lastly, in viewDidDisappear(), make sure you remove the observer:

    tableView.removeObserver(self, forKeyPath: "contentSize")
    

    This way the popover will automatically adjust size to fit the content, whenever it is loaded, or changed.

    0 讨论(0)
  • 2021-01-31 03:33

    Checkout the preferredContentSize property of UIViewController:

    let height = yourDataArray.count * Int(popOverViewController.tableView.rowHeight)
    popOverViewController.preferredContentSize = CGSize(width: 300, height: height)
    
    0 讨论(0)
  • 2021-01-31 03:41

    Override the preferredContentSize property in your extension of the uitableviewcontroller as following:

    override var preferredContentSize: CGSize {
        get {
            let height = calculate the height here....
            return CGSize(width: super.preferredContentSize.width, height: height)
        }
        set { super.preferredContentSize = newValue }
    }
    

    For calculating the height check out tableView.rectForSection(<#section: Int#>)

    0 讨论(0)
  • 2021-01-31 03:50

    Simple dynamic answer for Swift 4.x and Swift 5.x involving no size-computation (modern version of Bo Frese answer):

    private var contentSizeObserver : NSKeyValueObservation?
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        contentSizeObserver = tableView.observe(\.contentSize) { [weak self] tableView, _ in
            self?.preferredContentSize = CGSize(width: 320, height: tableView.contentSize.height) // Here I fixed the width but you can do whatever you want
        }
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
    
        contentSizeObserver?.invalidate()
        contentSizeObserver = nil
    }
    
    0 讨论(0)
提交回复
热议问题