Search code examples
iosiphoneswiftuipopovercontroller

Creating a popoverview with only custom viewcontroller class on iphone


I am trying to implement a popovercontroller on the iPhone that has a modal presentation similar to the iPad. I am only able to get UI to generate when using storyboard and I would much prefer to build a controller fully programmatically. All the demos on SO and google seem to use storyboard. I can see methods from my custom UIViewController printing to the logs, but nothing appears on the modal popover. Showing Popover view

    func handlePop(sender: UIButton) {

      //let popController:UIViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "unique") as UIViewController //only way I generate UI in popoverview

      let popController = MyCustomViewController()  //would like to use

     //positioning 
    let placementView = UIView()
    view.addSubview(placementView)
    view.addConstraintsWithFormat("H:|[v0]|", views: placementView)
    view.addConstraintsWithFormat("H:|-64-[v0(200)]", views: placementView)

    popController.modalPresentationStyle = UIModalPresentationStyle.popover
    if let poppingVC = popController.popoverPresentationController {


        let popover: UIPopoverPresentationController = poppingVC

        popover.sourceView = placementView
        popover.permittedArrowDirections = .up
        popover.sourceRect = CGRect(x: view.frame.width / 2, y: -100, width: 0, height: 100)

        popover.delegate = self

        self.present(popController, animated: true, completion:nil)
    }

}

func dismissView() {
    self.dismiss(animated: true, completion: nil)
}
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
    return UIModalPresentationStyle.none
}

What am I missing that is keeping the popovercontroller blank?

    class RegionSelectionController: UIViewController, UIPopoverPresentationControllerDelegate, UITableViewDelegate, UITableViewDataSource {



let mainLabel = UILabel()
let cellId = "cellId"
let footerId = "footerId"
var keys = [String]()

let tableView = UITableView()


override func viewDidLoad() {
    super.viewDidLoad()


    tableView.delegate = self
    tableView.dataSource = self



    self.view.addSubview(tableView)

    tableView.register(RegionFilterCell.self, forCellReuseIdentifier: cellId)
    tableView.separatorStyle = .none

    tableView.delegate = self

}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    print(keys.count)
    return keys.count

}
func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! RegionFilterCell

    let regionName = keys[indexPath.row]
    cell.regionLabel.text = regionName

    return cell

}

 func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
    let footerCell = RegionRequestNewLocationCell()


    return footerCell
}
 func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    return 100
}

 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    print(indexPath.row, keys[indexPath.row])
}




override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    ref.child("Region").observeSingleEvent(of: .childAdded, with: { (snap) in
        if snap.exists() {

            let key: String = snap.key as String
            self.keys.append(key)
        }
        DispatchQueue.main.async ( execute: {
            self.tableView.reloadData()
        })
    })


}

}

  class RegionFilterCell: BaseTableCell {

let regionLabel: UILabel = {
    let label = UILabel()
    label.font = UIFont(name: "SFUIText-Medium", size: 16)
    label.text = "UMD"
    return label
}()

let separatorBar: UIView = {
    let view = UIView()
    view.backgroundColor = UIColor.rgb(151, green: 151, blue: 151, alpha: 0.3)
    return view
}()
override func setupViews() {
    super.setupViews()

    addSubview(regionLabel)
    addSubview(separatorBar)
    //addConstraintsWithFormat("H:[v0(100)]", views: regionLabel)
    addConstraint(NSLayoutConstraint(item: regionLabel, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0))
    addConstraintsWithFormat("V:|[v0]|", views: regionLabel)
    addConstraintsWithFormat("H:|[v0]|", views: separatorBar)
    addConstraintsWithFormat("V:[v0(0.5)]|", views: separatorBar)
}

}


Solution

  • From what you're showing, you're never setting the frame for your content in the ViewController that's being presented (in this case your UITableView). If you don't set the frame for the view, it won't be shown on the screen. You need to either specify the origin and size using a CGRect, or use auto layout with NSLayoutConstraints. The easiest way is just a frame. So in viewDidLoad, say you wanted to have the tableView take up the whole view:

    tableView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)
    

    Also you need to make sure you're instantiating the right VC. I don't know if you just used the name MyCustomViewController for the purpose of the example, but the VC you showed in your code is named RegionSelectionController