如何在swift中将我的popover调整到tableview中内容的大小?

时间:2015-04-04 18:31:32

标签: uitableview swift resize popover

我使用popoverPresentationController来展示我的popover。用于显示为弹出窗口的UITableViewController是以编程方式创建的,通常包含1到5行。如何设置此弹出框以将大小调整为tableview的内容?

我的popover代码:

if recognizer.state == .Began {
    let translation = recognizer.locationInView(view)

    // Create popoverViewController
    var popoverViewController = UITableViewController()
    popoverViewController.modalPresentationStyle = UIModalPresentationStyle.Popover
    popoverViewController.tableView.backgroundColor = UIColor.popupColor()

    // Settings for the popover
    let popover = popoverViewController.popoverPresentationController!
    popover.delegate = self
    popover.sourceView = self.view
    popover.sourceRect = CGRect(x: translation.x, y: translation.y, width: 0, height: 0)
    popover.backgroundColor = UIColor.popupColor()

    presentViewController(popoverViewController, animated: true, completion: nil)
}

6 个答案:

答案 0 :(得分:32)

在你的UITableViewController viewDidLoad()中你可以添加一个观察者:

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

然后添加此方法:

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

最后,在viewDidDisappear()中,请确保删除观察者:

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

这样,无论何时加载或更改内容,弹出框都会自动调整大小以适合内容。

答案 1 :(得分:26)

结帐preferredContentSize property of UIViewController

let height = yourDataArray.count * Int(popOverViewController.tableView.rowHeight)
popOverViewController.preferredContentSize = CGSize(width: 300, height: height)

答案 2 :(得分:18)

覆盖preferredContentSize扩展程序中的uitableviewcontroller属性,如下所示:

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

计算高度结帐tableView.rectForSection(<#section: Int#>)

答案 3 :(得分:10)

Swift 4.x Swift 5.x 的简单动态答案,不涉及尺寸计算(Bo Frese答案的现代版本):

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
}

答案 4 :(得分:3)

对于swift 4,如果你想观察内容大小,我发现这是最佳解决方案。在这里报告,因为我没有在网上找到完整的例子:

 func from(systemItem: UIBarButtonSystemItem)-> UIImage? {
    let tempItem = UIBarButtonItem(barButtonSystemItem: systemItem, target: nil, action: nil)

    // add to toolbar and render it
    UIToolbar().setItems([tempItem], animated: false)

    // got image from real uibutton
    let itemView = tempItem.value(forKey: "view") as! UIView
    for view in itemView.subviews {
        if let button = view as? UIButton, let imageView = button.imageView {
            return imageView.image
        }
    }

    return nil

    }
 }
    extension UITextView {

static let ScrollModeBottom = "UITextFieldScrollModeBottom"
static let ScrollModeUp = "UITextFieldScrollModeUp"
static let ScrollModeMiddle = "UITextFieldScrollModeMiddle"

func scrollToBotom() {
    let range = NSMakeRange((text as NSString).length - 1, 1);
    scrollRangeToVisible(range);
}

var scrollMode: String {
    let scrollViewHeight: Float = Float(frame.size.height)
    let scrollContentSizeHeight: Float = Float(contentSize.height)
    let scrollOffset: Float = Float(contentOffset.y)

    if scrollOffset == 0 {
        return UITextView.ScrollModeUp
    } else if scrollOffset + scrollViewHeight == scrollContentSizeHeight {
        return UITextView.ScrollModeBottom
    } else {
        return UITextView.ScrollModeMiddle
    }
}

答案 5 :(得分:0)

首先要做的是:所有评论都很好并且帮助完整。 我的逻辑没有什么变化,这使我的VC成为可重用的组件。

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);
   }
}