Pertanyaan cara memusatkan popoverview dengan cepat


Saya memiliki kode berikut untuk menampilkan popoverview (dialog) tanpa panah, yang berfungsi dengan baik. Satu-satunya masalah adalah, dialog yang ditampilkan di kiri atas (IPad). Saya ingin memusatkan tampilan di layar.

Apa yang harus diubah atau ditambahkan dalam kode berikut? :

func show_help(){


    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let controller = storyboard.instantiateViewControllerWithIdentifier("Help") as! UIViewController

    controller.modalPresentationStyle = UIModalPresentationStyle.Popover

    let popoverPresentationController = controller.popoverPresentationController

    // result is an optional (but should not be nil if modalPresentationStyle is popover)
    if let _popoverPresentationController = popoverPresentationController {

        // set the view from which to pop up
        _popoverPresentationController.sourceView = self.view;
        _popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirection.allZeros;
        // present (id iPhone it is a modal automatic full screen)
        self.presentViewController(controller, animated: true, completion: nil)
    }

}

Infos Tambahan

enter image description here

Dalam pandangan saya, yang terkait dengan viewcontroller saya, saya mengatur ukuran yang diinginkan seperti ini:

override func viewDidLoad() {
        let dialogheigth:CGFloat = self.view.frame.height * 0.5;
        let dialogwidth:CGFloat = self.view.frame.width * 0.5;
        self.preferredContentSize = CGSizeMake(dialogwidth,dialogheigth);
}

32
2017-08-01 07:53


asal


Jawaban:


Anda harus menyediakan sumber rujukan untuk popover.

Dari dokumentasi apel: sumber rect adalah segiempat panjang dalam tampilan yang ditentukan untuk melabuhkan popover. Gunakan properti ini bersama dengan properti sourceView untuk menentukan lokasi jangkar untuk popover.

Dalam kasus Anda, di bawah

_popoverPresentationController.sourceView = self.view;

menambahkan:

_popoverPresentationController.sourceRect = CGRectMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds),0,0)

Itu akan berhasil!

enter image description here


64
2017-08-06 11:19



Berikut ini implementasi menggunakan Swift 3

let popover = storyboard?.instantiateViewController(withIdentifier: "popover") as! PopoverVC

    popover.modalPresentationStyle = UIModalPresentationStyle.popover
    popover.popoverPresentationController?.backgroundColor = UIColor.green
    popover.popoverPresentationController?.delegate = self

    popover.popoverPresentationController?.sourceView = self.view
    popover.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)

    popover.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)

    self.present(popover, animated: true)

Berdasarkan Istvan menjawab


25
2017-12-21 15:56



Swift 4 implementasi:

popover.popoverPresentationController?.sourceRect = CGRect(x: view.center.x, y: view.center.y, width: 0, height: 0)
popover.popoverPresentationController?.sourceView = view
popover.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)

4
2017-10-30 18:48



Cara lain untuk Swift 3 (Xcode 8, iOS 9) adalah ini:

Dipanggil dari suatu tempat:

self.performSegue(withIdentifier: "showPopupSegue", sender: yourButton)

Fungsi yang dipanggil sebelum segue dipecat:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let popoverPresentationController = segue.destination.popoverPresentationController {
        let controller = popoverPresentationController
        controller.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
        controller.sourceView = self.view
        controller.sourceRect = CGRect(x: UIScreen.main.bounds.width * 0.5 - 200, y: UIScreen.main.bounds.height * 0.5 - 100, width: 400, height: 200)
        segue.destination.preferredContentSize=CGSize(width: 400, height: 200)
    }
}

Ingat untuk mengatur atribut Kindboard segue's ke "Present as Popover" dan Anchor atribut ke tampilan apa pun di pengontrol tampilan sebelumnya.


3
2018-02-09 09:34



Pada dasarnya terdiri dari tiga langkah (iOS 8):

1. - Presentasikan tampilan:

Katakanlah, Anda ingin menunjukkan tampilan khusus untuk meminta Ulasan kepada pengguna .. di sini fungsi loadNibForRate() mengembalikan turunan dari RateDialog diambil dari nibnya, tetapi Anda dapat menggunakannya di sini dengan cara apa pun yang Anda inginkan untuk menemukannya UIViewController

private static func presentCustomDialog(parent: RateDialogParent) -> Bool {
    /// Loads the rateDialog from its xib, handled this way for further customization if desired
      if let rateDialog = loadNibForRate() {
        rateDialog.modalPresentationStyle = UIModalPresentationStyle.Popover
        rateDialog.modalTransitionStyle = UIModalTransitionStyle.CrossDissolve
        let x = parent.view.center

        let sourceRectX : CGFloat
        //Here we check for the orientation of the device, just to know if we are on an iPad
        let maximumDim = max(UIScreen.mainScreen().bounds.height, UIScreen.mainScreen().bounds.width)
        if maximumDim == 1024 { //iPad
            sourceRectX = x.x
        }else {
            sourceRectX = 0
        }

        rateDialog.popoverPresentationController?.sourceView = parent.view
        rateDialog.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.allZeros
        rateDialog.popoverPresentationController?.sourceRect = CGRectMake(sourceRectX, x.y, 0, 0)
        rateDialog.popoverPresentationController?.popoverLayoutMargins = UIEdgeInsetsMake(0, 0, 0, 0)
        rateDialog.popoverPresentationController?.delegate = parent

        rateDialogParent = parent

        callFunctionAsync() {
            parent.presentViewController(rateDialog, animated: true, completion: nil)
        }
        return true
    }
    return false
}

2.- Jika kita memutar perangkat kita, maka popover tidak akan tahu di mana memposisikan ulang itu sendiri, kecuali kita memiliki ini pada induknya    RateDialogParent

public class RateDialogParent: UIViewController, UIPopoverPresentationControllerDelegate {
/**
This function guarantees that the RateDialog is alwas centered at parent, it locates the RateDialog's view by searching for its tag (-555)
 */
 public func popoverPresentationController(popoverPresentationController: UIPopoverPresentationController, willRepositionPopoverToRect rect: UnsafeMutablePointer<CGRect>, inView view: AutoreleasingUnsafeMutablePointer<UIView?>) {
    if popoverPresentationController.presentedViewController.view.tag == RateDialog.thisViewTag {
        let x = popoverPresentationController.presentingViewController.view.center
        let newRect = CGRectMake(x.x, x.y, 0, 0)
        rect.initialize(newRect)
    }
 }
}

3.- Anda RateDialog harus memiliki tag yang diset, ini hanya untuk menghindari relokasi popovers yang tidak diinginkan jika ada lebih dari satu yang disajikan   dari kamu RateDialogParent

class RateDialog: UIViewController {
 @IBOutlet weak var reviewTitle: UILabel!
 @IBOutlet weak var reviewMessage : UILabel!
 @IBOutlet weak var cancelButtonTitle: UIButton!
 @IBOutlet weak var remindButtonTitle : UIButton!
 @IBOutlet weak var rateButtonTitle : UIButton!

    /// For being able to locate this view
 static let thisViewTag = -555

 override func viewDidLoad() {
    super.viewDidLoad()
    //sets the tag to identify this view
    self.view.tag = RateDialog.thisViewTag
 }
}

2
2017-08-06 15:59



Di iOS8, Anda tidak perlu menggunakannya self.view.frame untuk menghitung lebar dan tinggi.

Anda dapat dialog tinggi dan lebar menggunakan cara berikut:

override func viewDidLoad() {
     var frameSize: CGPoint = CGPointMake(UIScreen.mainScreen().bounds.size.width*0.5, UIScreen.mainScreen().bounds.size.height*0.5)
     self.preferredContentSize = CGSizeMake(frameSize.x,frameSize.y);
}

Diedit:

Anda juga dapat mengatur contentSizeForViewInPopover seperti di bawah ini juga:

self.contentSizeForViewInPopover = CGSizeMake(320.0, 360.0)

Biar saya tahu ini membantu atau tidak?


1
2017-08-01 08:57



Dalam hal jika itu membantu siapa saja, saya telah membuat ekstensi pada UIViewController

extension UIViewController{
    func configureAsPopoverAndPosition(withWidthRatio widthRatio:CGFloat,
                                       heightRatio:CGFloat){
        modalPresentationStyle = .popover
        let screenWidth = UIScreen.main.bounds.width
        let screenHeight = UIScreen.main.bounds.height
        let popover = popoverPresentationController
        popover?.sourceView = self.view

        popover?.permittedArrowDirections = [UIPopoverArrowDirection(rawValue: 0)]
        preferredContentSize = CGSize(width: (screenWidth * widthRatio),
                                      height: (screenHeight * heightRatio))

        popover?.sourceRect = CGRect(x: view.center.x,
                                     y: view.center.y,
                                     width: 0,
                                     height: 0)
    }
}

Pemakaian:

if UIDevice.current.userInterfaceIdiom == .pad{
                    yourViewController.configureAsPopoverAndPosition(withWidthRatio: 0.7 /*Make view controller width 70 % of screen width*/,
                                                                        heightRatio: 0.7/*Make view controller height 70 % of screen height*/)
                }

Ini akan menampilkan popover di tengah layar.


0
2018-05-11 07:09



Swift 4 implementation for center Popover controller

let navigationController = UINavigationController(rootViewController: controller)

        navigationController.modalPresentationStyle = .popover

        navigationController.modalPresentationStyle = UIModalPresentationStyle.popover
        let popover = navigationController.popoverPresentationController
        controller.preferredContentSize = CGSize(width:500,height:600) //manage according to Device like iPad/iPhone
        popover?.delegate = self
        popover?.sourceView = self.view
        popover?.sourceRect = CGRect(x: view.center.x, y: view.center.y, width: 0, height: 0)
        popover?.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)

        self.present(navigationController, animated: true, completion: nil)

0
2017-08-03 02:37